home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-08-14 | 8.5 KB | 322 lines |
- /*
- * @(#)TurnDiff.java
- */
- package games.Battle.shared.comm;
-
- import java.util.*;
-
- import games.Battle.shared.sys.*;
-
- /**
- * A TurnDiff is a delta of the game board sent to every player on every
- * "iteration" of the game. It only contains the differences in the game
- * board that are the result of this turn to help keep transmission costs
- * to a minimum.
- *
- * @version 1.00 02/02/96
- * @author Jay Steele
- * @author Alex Nicolaou
- */
-
- public class TurnDiff extends BattlePacket {
- /**
- * the board.
- */
- protected Board board;
-
- /**
- * the player whose point of view this turndiff is from.
- */
- protected int player;
-
- /**
- * a tag for encoding a special additional message with the turn. used
- * to indicate GAME OVER.
- */
- byte tag;
-
- /**
- * NORMAL is the usual tag placed on a turndiff.
- */
- public static final byte NORMAL = 0x00;
- /**
- * GAMEOVER is the used to say hasta la vista, baby.
- */
- public static final byte GAMEOVER = 0x01;
-
- /**
- * The most cells that can be run length encoded into one run.
- */
- static final int MAX_RUN = 16;
- /**
- * The amount of space we have to encode the TurnDiff.
- */
- static final int MAX_INDEX = Rules.rows * Rules.cols;
-
-
- /**
- * Constructor which indicates which game board this TurnDiff is
- * going to be reading/writing to, and which player in the game
- * the diff is being constructed for.
- * @param board the board the turn diff is representing
- * @param the player the turn diff is representing
- */
- public TurnDiff(Board board, int player) {
- this.board = board;
- this.player = player;
- this.tag = NORMAL;
- }
- /**
- * Constructor which indicates which game board this TurnDiff is
- * going to be reading/writing to, and which player in the game
- * the diff is being constructed for. Also takes a tag, so that
- * the server can indicate game over.
- * @param board the board the turn diff is representing
- * @param player the player the turn diff is representing
- * @param tag the tag for game over or not
- */
- public TurnDiff(Board board, int player, byte tag) {
- this.board = board;
- this.player = player;
- this.tag = tag;
- }
-
-
- /**
- * return the tag associated with this turn diff.
- */
- public final byte getTag() {
- return tag;
- }
-
- /**
- * Run-length encodes a run of cells invisible to the player this
- * turn diff is being constructed for.
- * @param cells the array of Cells
- * @param index the current index into cells
- * @param result the vector of result, to which bytes will be added
- */
- int encodeInvisibleRun(Object[] cells, int index, Vector result) {
- int i = 0;
- while (true)
- {
- if (i+index >= MAX_INDEX) {
- break;
- }
- if (i >= MAX_RUN) {
- break;
- }
- Cell cell = (Cell)cells[i+index];
- if (cell.isVisible(player)) {
- break;
- }
- i++;
- }
- int data = (int)Common.stuffOccupancyAndCount(Symbols.INVISIBLE, i-1);
- result.addElement(new Integer(data));
- return i;
- }
-
- /**
- * Run-length encodes a run of cells unmodified in the last turn.
- * @param cells the array of Cells
- * @param index the current index into cells
- * @param result the vector of result, to which bytes will be added
- */
- int encodeUnmodifiedRun(Object[] cells, int index, Vector result) {
- int i = 0;
- while (true)
- {
- if (i+index >= MAX_INDEX) {
- break;
- }
- if (i >= MAX_RUN) {
- break;
- }
- Cell cell = (Cell)cells[i+index];
- if (! cell.isVisible(player)) {
- break;
- }
- if (cell.isModified()) {
- break;
- }
- i++;
- }
- int data = (int)Common.stuffOccupancyAndCount(Symbols.UNMODIFIED, i-1);
- result.addElement(new Integer(data));
- return i;
- }
-
- /**
- * Run-length encodes a run of cells unoccupied in the last turn.
- * @param cells the array of Cells
- * @param index the current index into cells
- * @param result the vector of result, to which bytes will be added
- */
- int encodeUnoccupiedRun(Object[] cells, int index, Vector result) {
- int i = 0;
- while (true)
- {
- if (i+index >= MAX_INDEX) {
- break;
- }
- if (i >= MAX_RUN) {
- break;
- }
- Cell cell = (Cell)cells[i+index];
- if (cell.getOccupancy() != Symbols.UNOCCUPIED) {
- break;
- }
- if (! cell.isVisible(player)) {
- break;
- }
- i++;
- }
- int data = (int)Common.stuffOccupancyAndCount(Symbols.UNOCCUPIED, i-1);
- result.addElement(new Integer(data));
- return i;
- }
-
- /**
- * Encodes a cell occupied by a player in the last turn.
- * @param cells the array of Cells
- * @param index the current index into cells
- * @param result the vector of result, to which bytes will be added
- */
- int encodePlayer(Object[] cells, int index, Vector result) {
- Cell cell = (Cell)cells[index];
- int occ = cell.getOccupancy();
-
- // Take troops in the range [0-MAX_SERVER_TROOPS] and convert
- // to the range [0-MAX_CLIENT_TROOPS]
- int troops = cell.getTroops();
- float percent = troops / (float)Symbols.MAX_SERVER_TROOPS;
- troops = (int)((float)Symbols.MAX_CLIENT_TROOPS * percent);
- int pipes = cell.getPipeMask();
- int data0 = (int)Common.stuffOccupancyAndTroops(occ, troops);
- int data1 = (int)Common.stuffPipes(pipes);
- result.addElement(new Integer(data0));
- result.addElement(new Integer(data1));
- return 1;
- }
-
- /**
- * an array of bytes for the turn diff.
- */
- byte diffData[];
- /**
- * Produce an array of bytes representing the turn diff.
- */
- public void makeBytes() {
- Vector result = new Vector();
- Object[] data = board.getGrid().getData();
-
- boolean done = false;
- int index = 0;
- while (!done) {
- Cell cell = (Cell)data[index];
- if (! cell.isVisible(player))
- index = index + encodeInvisibleRun(data, index, result);
- /*
- else if (! cell.isModified())
- index = index + encodeUnmodifiedRun(data, index, result);
- */
- else if (cell.getOccupancy() == Symbols.UNOCCUPIED)
- index = index + encodeUnoccupiedRun(data, index, result);
- else if (Common.isPlayer(cell.getOccupancy()))
- index = index + encodePlayer(data, index, result);
- done = (index >= (Rules.rows * Rules.cols));
- }
-
- // convert from the vector representation to the byte-array repr.
- byte[] result_data = new byte[result.size()+1];
- result_data[0] = tag;
- for (int i=0; i<result.size(); i++) {
- Integer ie = (Integer)result.elementAt(i);
- result_data[i+1] = (byte)ie.intValue();
- }
-
- diffData = result_data;
- }
-
- /**
- * return the bytes for the turn diff.
- */
- public byte[] toBytes() {
- if (diffData == null)
- makeBytes();
- return diffData;
- }
-
- /**
- * Build a turn diff based on the data inside the given array of bytes
- * @param array the array of bytes
- */
- public void fromBytes(byte[] array) {
-
- tag = array[0];
-
- Board cb = board;
- Object[] data = cb.getGrid().getData();
- int index = 0;
-
- for (int i=1; i<array.length; i++) {
- byte b = array[i];
- int occ = Common.extractOccupancy(b);
- if (Common.isPlayer(occ)) {
- int troops = Common.extractTroops(b);
- b = array[++i];
- int pipes = Common.extractPipes(b);
- Cell cell = (Cell)data[index];
- cell.setOccupancy(occ);
- cell.setTroops(troops);
- cell.setPipes(pipes);
- // cell.update();
- index++;
- } else {
- int count = Common.extractCount(b)+1;
- for (int j=index; j<index+count; j++) {
- Cell cell = (Cell)data[j];
- if (occ != Symbols.UNMODIFIED) {
- cell.setOccupancy(occ);
- // cell.update();
- }
- }
- index += count;
- }
- }
- }
-
- /**
- * Debugging output
- */
- public void asciiDump(byte[] array) {
-
- System.out.println("-- TurnDiff --");
- for (int i=1; i<array.length; i++) {
- byte b = array[i];
- int occ = Common.extractOccupancy(b);
- if (Common.isPlayer(occ)) {
- int troops = Common.extractTroops(b);
- b = array[++i];
- int pipes = Common.extractPipes(b);
- System.out.print("[");
- System.out.print(Symbols.occupancyString[occ]);
- System.out.print(" Troops="+troops);
- System.out.print(" Pipes=");
- if ((pipes & 0x08) != 0) System.out.print("1"); else System.out.print("0");
- if ((pipes & 0x04) != 0) System.out.print("1"); else System.out.print("0");
- if ((pipes & 0x02) != 0) System.out.print("1"); else System.out.print("0");
- if ((pipes & 0x01) != 0) System.out.print("1"); else System.out.print("0");
- System.out.println("]");
- } else {
- int count = Common.extractCount(b)+1;
- System.out.print("[");
- System.out.print(Symbols.occupancyString[occ]);
- System.out.print(" Count="+count);
- System.out.println("]");
- }
- }
- }
- }
-