|
|
|
@@ -35,9 +35,8 @@ import com.threerings.puzzle.drop.client.DropControllerDelegate;
|
|
|
|
|
import com.threerings.puzzle.drop.util.DropBoardUtil;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A class that provides for various useful logical operations to be
|
|
|
|
|
* enacted on a two-dimensional board and provides an easier mechanism for
|
|
|
|
|
* referencing pieces by position.
|
|
|
|
|
* A class that provides for various useful logical operations to be enacted on a two-dimensional
|
|
|
|
|
* board and provides an easier mechanism for referencing pieces by position.
|
|
|
|
|
*/
|
|
|
|
|
public class DropBoard extends Board
|
|
|
|
|
implements DropPieceCodes
|
|
|
|
@@ -45,12 +44,11 @@ public class DropBoard extends Board
|
|
|
|
|
/** The rotation constant for rotation around a central piece. */
|
|
|
|
|
public static final int RADIAL_ROTATION = 0;
|
|
|
|
|
|
|
|
|
|
/** The rotation constant for rotation wherein the block occupies the
|
|
|
|
|
* same columns when rotating. */
|
|
|
|
|
/** The rotation constant for rotation wherein the block occupies the same columns when
|
|
|
|
|
* rotating. */
|
|
|
|
|
public static final int INPLACE_ROTATION = 1;
|
|
|
|
|
|
|
|
|
|
/** An operation that does naught but clear pieces, which proves to be
|
|
|
|
|
* generally useful. */
|
|
|
|
|
/** An operation that does naught but clear pieces, which proves to be generally useful. */
|
|
|
|
|
public static final PieceOperation CLEAR_OP = new PieceOperation () {
|
|
|
|
|
public boolean execute (DropBoard board, int col, int row) {
|
|
|
|
|
board.setPiece(col, row, PIECE_NONE);
|
|
|
|
@@ -59,19 +57,16 @@ public class DropBoard extends Board
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* An interface to be implemented by classes that would like to apply
|
|
|
|
|
* some operation to each piece in a column or row segment in the
|
|
|
|
|
* board.
|
|
|
|
|
* An interface to be implemented by classes that would like to apply some operation to each
|
|
|
|
|
* piece in a column or row segment in the board.
|
|
|
|
|
*/
|
|
|
|
|
public interface PieceOperation
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* Called for each piece in the board segment the operation is
|
|
|
|
|
* being applied to.
|
|
|
|
|
* Called for each piece in the board segment the operation is being applied to.
|
|
|
|
|
*
|
|
|
|
|
* @return true if the operation should continue to be applied if
|
|
|
|
|
* being applied to multiple pieces, or false if it should
|
|
|
|
|
* terminate after this application.
|
|
|
|
|
* @return true if the operation should continue to be applied if being applied to multiple
|
|
|
|
|
* pieces, or false if it should terminate after this application.
|
|
|
|
|
*/
|
|
|
|
|
public boolean execute (DropBoard board, int col, int row);
|
|
|
|
|
}
|
|
|
|
@@ -85,8 +80,7 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructs a drop board of the given dimensions with its
|
|
|
|
|
* pieces initialized to PIECE_NONE.
|
|
|
|
|
* Constructs a drop board of the given dimensions with its pieces initialized to PIECE_NONE.
|
|
|
|
|
*/
|
|
|
|
|
public DropBoard (int bwid, int bhei)
|
|
|
|
|
{
|
|
|
|
@@ -95,8 +89,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructs a drop board of the given dimensions with its
|
|
|
|
|
* pieces initialized to the given piece.
|
|
|
|
|
* Constructs a drop board of the given dimensions with its pieces initialized to the given
|
|
|
|
|
* piece.
|
|
|
|
|
*/
|
|
|
|
|
public DropBoard (int bwid, int bhei, int piece)
|
|
|
|
|
{
|
|
|
|
@@ -138,16 +132,14 @@ public class DropBoard extends Board
|
|
|
|
|
try {
|
|
|
|
|
return _board[(row*_bwid) + col];
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.warning("Failed getting piece [col=" + col +
|
|
|
|
|
", row=" + row + ", error=" + e + "].");
|
|
|
|
|
Log.warning("Failed getting piece [col=" + col + ", row=" + row + ", error=" + e + "].");
|
|
|
|
|
Log.logStackTrace(e);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* For boards that are always filled, this method is called to obtain
|
|
|
|
|
* pieces to fill the board.
|
|
|
|
|
* For boards that are always filled, this method is called to obtain pieces to fill the board.
|
|
|
|
|
*/
|
|
|
|
|
public int getNextPiece ()
|
|
|
|
|
{
|
|
|
|
@@ -155,8 +147,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the distance the piece at the given column and row can drop
|
|
|
|
|
* until it hits a non-empty piece (defined as {@link #PIECE_NONE}).
|
|
|
|
|
* Returns the distance the piece at the given column and row can drop until it hits a
|
|
|
|
|
* non-empty piece (defined as {@link #PIECE_NONE}).
|
|
|
|
|
*/
|
|
|
|
|
public int getDropDistance (int col, int row)
|
|
|
|
|
{
|
|
|
|
@@ -184,8 +176,7 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns whether all of the pieces at the given coordinates can be
|
|
|
|
|
* dropped one row.
|
|
|
|
|
* Returns whether all of the pieces at the given coordinates can be dropped one row.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isValidDrop (int[] rows, int[] cols, float pctdone)
|
|
|
|
|
{
|
|
|
|
@@ -207,8 +198,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns true if the specified coordinate is within the bounds of
|
|
|
|
|
* the board, false if it is not.
|
|
|
|
|
* Returns true if the specified coordinate is within the bounds of the board, false if it is
|
|
|
|
|
* not.
|
|
|
|
|
*/
|
|
|
|
|
public boolean inBounds (int col, int row)
|
|
|
|
|
{
|
|
|
|
@@ -216,9 +207,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns whether the specified block in the board is empty. The
|
|
|
|
|
* block is allowed to occupy space off the top of the board as long
|
|
|
|
|
* as it is within the horizontal board bounds.
|
|
|
|
|
* Returns whether the specified block in the board is empty. The block is allowed to occupy
|
|
|
|
|
* space off the top of the board as long as it is within the horizontal board bounds.
|
|
|
|
|
*
|
|
|
|
|
* @param col the left coordinate of the block.
|
|
|
|
|
* @param row the bottom coordinate of the block.
|
|
|
|
@@ -229,12 +219,10 @@ public class DropBoard extends Board
|
|
|
|
|
{
|
|
|
|
|
for (int ypos = row; ypos > (row - hei); ypos--) {
|
|
|
|
|
for (int xpos = col; xpos < (col + wid); xpos++) {
|
|
|
|
|
// only allow movement off the top of the board that's
|
|
|
|
|
// within the horizontal screen bounds and in a column
|
|
|
|
|
// that's not topped out
|
|
|
|
|
// only allow movement off the top of the board that's within the horizontal screen
|
|
|
|
|
// bounds and in a column that's not topped out
|
|
|
|
|
if (ypos < 0) {
|
|
|
|
|
if ((xpos < 0 || xpos >= _bwid) ||
|
|
|
|
|
(getPiece(xpos, 0) != PIECE_NONE)) {
|
|
|
|
|
if ((xpos < 0 || xpos >= _bwid) || (getPiece(xpos, 0) != PIECE_NONE)) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
continue;
|
|
|
|
@@ -259,25 +247,21 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Rotates the given block in the given direction and returns its
|
|
|
|
|
* final state as <code>(orient, col, row, popped)</code>, where
|
|
|
|
|
* <code>orient</code> is the final orientation of the drop block;
|
|
|
|
|
* <code>col</code> and <code>row</code> are the final column and row
|
|
|
|
|
* coordinates, respectively, of the central drop block piece.
|
|
|
|
|
* <code>popped</code> will be set to 1 if the piece was popped up, 0
|
|
|
|
|
* otherwise.
|
|
|
|
|
* Rotates the given block in the given direction and returns its final state as <code>(orient,
|
|
|
|
|
* col, row, popped)</code>, where <code>orient</code> is the final orientation of the drop
|
|
|
|
|
* block; <code>col</code> and <code>row</code> are the final column and row coordinates,
|
|
|
|
|
* respectively, of the central drop block piece. <code>popped</code> will be set to 1 if the
|
|
|
|
|
* piece was popped up, 0 otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public int[] getForgivingRotation (
|
|
|
|
|
int[] rows, int[] cols, int orient, int dir, int rtype, float pctdone,
|
|
|
|
|
boolean canPopup)
|
|
|
|
|
int[] rows, int[] cols, int orient, int dir, int rtype, float pctdone, boolean canPopup)
|
|
|
|
|
{
|
|
|
|
|
int px = cols[0], py = rows[0];
|
|
|
|
|
|
|
|
|
|
// Log.info("Starting rotation [px=" + px + ", py=" + py +
|
|
|
|
|
// ", orient=" + orient + ", pctdone=" + pctdone + "].");
|
|
|
|
|
|
|
|
|
|
// try rotating the block in the given direction through all four
|
|
|
|
|
// possible orientations
|
|
|
|
|
// try rotating the block in the given direction through all four possible orientations
|
|
|
|
|
for (int ii = 0; ii < 4; ii++) {
|
|
|
|
|
int oidx = orient/2;
|
|
|
|
|
|
|
|
|
@@ -289,15 +273,13 @@ public class DropBoard extends Board
|
|
|
|
|
orient = DropBoardUtil.getRotatedOrientation(orient, dir);
|
|
|
|
|
oidx = orient/2;
|
|
|
|
|
|
|
|
|
|
// because isBlockEmpty() always assumes the origin of the
|
|
|
|
|
// block is in the lower-left, we need to adjust the
|
|
|
|
|
// coordinates of the drop block's "central" piece accordingly
|
|
|
|
|
// because isBlockEmpty() always assumes the origin of the block is in the lower-left,
|
|
|
|
|
// we need to adjust the coordinates of the drop block's "central" piece accordingly
|
|
|
|
|
int ox = px + ORIENT_ORIGIN_DX[oidx];
|
|
|
|
|
int oy = py + ORIENT_ORIGIN_DY[oidx];
|
|
|
|
|
|
|
|
|
|
// if we're less than 50 percent through with our fall, we
|
|
|
|
|
// want to check our current coordinates for validity; if
|
|
|
|
|
// we're more, we want to check the row below our current
|
|
|
|
|
// if we're less than 50 percent through with our fall, we want to check our current
|
|
|
|
|
// coordinates for validity; if we're more, we want to check the row below our current
|
|
|
|
|
// coordinates
|
|
|
|
|
if (pctdone > 0.5) {
|
|
|
|
|
oy += 1;
|
|
|
|
@@ -307,8 +289,7 @@ public class DropBoard extends Board
|
|
|
|
|
for (int c = 0; c < COERCE_DX.length; c++) {
|
|
|
|
|
int cx = COERCE_DX[c];
|
|
|
|
|
// check if our hypothetical new coordinates are empty
|
|
|
|
|
if (isBlockEmpty(ox + cx, oy,
|
|
|
|
|
ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) {
|
|
|
|
|
if (isBlockEmpty(ox + cx, oy, ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) {
|
|
|
|
|
// Log.info(
|
|
|
|
|
// "Block is empty [ox=" + ox + ", cx=" + cx +
|
|
|
|
|
// ", oy=" + oy + ", oidx=" + oidx +
|
|
|
|
@@ -319,13 +300,11 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if our piece is facing south and we're using radial
|
|
|
|
|
// rotation then we need to try popping the piece up a row to
|
|
|
|
|
// check for a fit
|
|
|
|
|
// if our piece is facing south and we're using radial rotation then we need to try
|
|
|
|
|
// popping the piece up a row to check for a fit
|
|
|
|
|
if (canPopup && rtype == RADIAL_ROTATION && orient == SOUTH) {
|
|
|
|
|
// check if our hypothetical new coordinates are empty
|
|
|
|
|
if (isBlockEmpty(ox, oy - 1,
|
|
|
|
|
ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) {
|
|
|
|
|
if (isBlockEmpty(ox, oy - 1, ORIENT_WIDTHS[oidx], ORIENT_HEIGHTS[oidx])) {
|
|
|
|
|
// Log.info(
|
|
|
|
|
// "Popped-up block is empty [ox=" + ox +
|
|
|
|
|
// ", oy=" + (oy - 1) + ", oidx=" + oidx +
|
|
|
|
@@ -338,19 +317,17 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// this should never happen since even in the most tightly
|
|
|
|
|
// constrained case where the block is entirely surrounded by
|
|
|
|
|
// other pieces there are always two valid orientations.
|
|
|
|
|
// this should never happen since even in the most tightly constrained case where the block
|
|
|
|
|
// is entirely surrounded by other pieces there are always two valid orientations.
|
|
|
|
|
Log.warning("**** We're horked and couldn't rotate at all!");
|
|
|
|
|
// System.exit(0);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a {@link Point} object containing the coordinates to place
|
|
|
|
|
* the bottom-left of the given block at after moving it the given
|
|
|
|
|
* distance on the x- and y-axes, or <code>null</code> if the move is
|
|
|
|
|
* not valid. Note that only the final block position is checked.
|
|
|
|
|
* Returns a {@link Point} object containing the coordinates to place the bottom-left of the
|
|
|
|
|
* given block at after moving it the given distance on the x- and y-axes, or <code>null</code>
|
|
|
|
|
* if the move is not valid. Note that only the final block position is checked.
|
|
|
|
|
*
|
|
|
|
|
* @param col the leftmost column of the block.
|
|
|
|
|
* @param row the bottommost row of the block.
|
|
|
|
@@ -358,26 +335,23 @@ public class DropBoard extends Board
|
|
|
|
|
* @param hei the height of the block.
|
|
|
|
|
* @param dx the distance to move the block in columns.
|
|
|
|
|
* @param dy the distance to move the block in rows.
|
|
|
|
|
* @param pctdone the percentage of the inter-block distance that the
|
|
|
|
|
* piece has fallen thus far.
|
|
|
|
|
* @param pctdone the percentage of the inter-block distance that the piece has fallen thus
|
|
|
|
|
* far.
|
|
|
|
|
*/
|
|
|
|
|
public Point getForgivingMove (
|
|
|
|
|
int col, int row, int wid, int hei, int dx, int dy, float pctdone)
|
|
|
|
|
public Point getForgivingMove (int col, int row, int wid, int hei, int dx, int dy, float pctdone)
|
|
|
|
|
{
|
|
|
|
|
// try placing the block in the desired position and, failing
|
|
|
|
|
// that, at the same horizontal position but one row farther down
|
|
|
|
|
// try placing the block in the desired position and, failing that, at the same horizontal
|
|
|
|
|
// position but one row farther down
|
|
|
|
|
int xpos = col + dx, ypos = row + dy;
|
|
|
|
|
|
|
|
|
|
// if we're above the halfway mark, we check our current neighbors
|
|
|
|
|
// to see if we can move there; if we're below the halfway mark we
|
|
|
|
|
// check the next row down
|
|
|
|
|
// if we're above the halfway mark, we check our current neighbors to see if we can move
|
|
|
|
|
// there; if we're below the halfway mark we check the next row down
|
|
|
|
|
if (pctdone >= 0.5) {
|
|
|
|
|
ypos += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the block we wish to occupy is empty, we're all good
|
|
|
|
|
return (isBlockEmpty(xpos, ypos, wid, hei)) ?
|
|
|
|
|
new Point(xpos, row + dy) : null;
|
|
|
|
|
return (isBlockEmpty(xpos, ypos, wid, hei)) ? new Point(xpos, row + dy) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -393,10 +367,9 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Called by the {@link DropControllerDelegate} when it's time to
|
|
|
|
|
* apply a rising row of pieces to the board. Shifts all of the
|
|
|
|
|
* pieces in the given board up one row and places the given row of
|
|
|
|
|
* pieces at the bottom of the board.
|
|
|
|
|
* Called by the {@link DropControllerDelegate} when it's time to apply a rising row of pieces
|
|
|
|
|
* to the board. Shifts all of the pieces in the given board up one row and places the given
|
|
|
|
|
* row of pieces at the bottom of the board.
|
|
|
|
|
*/
|
|
|
|
|
public void applyRisingPieces (int[] pieces)
|
|
|
|
|
{
|
|
|
|
@@ -416,12 +389,11 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns true if the specified row (which count down, with zero at
|
|
|
|
|
* the top of the board) contains any pieces.
|
|
|
|
|
* Returns true if the specified row (which count down, with zero at the top of the board)
|
|
|
|
|
* contains any pieces.
|
|
|
|
|
*
|
|
|
|
|
* @param row the row to check for pieces.
|
|
|
|
|
* @param blankPiece the blank piece value, non-instances of which
|
|
|
|
|
* will be sought.
|
|
|
|
|
* @param blankPiece the blank piece value, non-instances of which will be sought.
|
|
|
|
|
*/
|
|
|
|
|
public boolean rowContainsPieces (int row, int blankPiece)
|
|
|
|
|
{
|
|
|
|
@@ -438,7 +410,7 @@ public class DropBoard extends Board
|
|
|
|
|
*/
|
|
|
|
|
public void fill (int piece)
|
|
|
|
|
{
|
|
|
|
|
Arrays.fill(_board, (int)piece);
|
|
|
|
|
Arrays.fill(_board, piece);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -449,7 +421,7 @@ public class DropBoard extends Board
|
|
|
|
|
public boolean setPiece (int col, int row, int piece)
|
|
|
|
|
{
|
|
|
|
|
if (col >= 0 && row >= 0 && col < _bwid && row < _bhei) {
|
|
|
|
|
_board[(row*_bwid) + col] = (int)piece;
|
|
|
|
|
_board[(row*_bwid) + col] = piece;
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
@@ -474,16 +446,14 @@ public class DropBoard extends Board
|
|
|
|
|
/**
|
|
|
|
|
* Sets the pieces in the given board segment to the specified piece.
|
|
|
|
|
*
|
|
|
|
|
* @param dir the direction of the segment; one of {@link #HORIZONTAL}
|
|
|
|
|
* or {@link #VERTICAL}.
|
|
|
|
|
* @param dir the direction of the segment; one of {@link #HORIZONTAL} or {@link #VERTICAL}.
|
|
|
|
|
* @param col the starting column of the segment.
|
|
|
|
|
* @param row the starting row of the segment.
|
|
|
|
|
* @param len the length of the segment in pieces.
|
|
|
|
|
* @param piece the piece to set in the segment.
|
|
|
|
|
*
|
|
|
|
|
* @return false if the segment was only partially applied because
|
|
|
|
|
* some pieces were outside the bounds of the board, true if it was
|
|
|
|
|
* completely applied.
|
|
|
|
|
* @return false if the segment was only partially applied because some pieces were outside the
|
|
|
|
|
* bounds of the board, true if it was completely applied.
|
|
|
|
|
*/
|
|
|
|
|
public boolean setSegment (int dir, int col, int row, int len, int piece)
|
|
|
|
|
{
|
|
|
|
@@ -495,8 +465,7 @@ public class DropBoard extends Board
|
|
|
|
|
/**
|
|
|
|
|
* Sets the pieces in the given board segment to the specified pieces.
|
|
|
|
|
*
|
|
|
|
|
* @param dir the direction of the segment; one of {@link #HORIZONTAL}
|
|
|
|
|
* or {@link #VERTICAL}.
|
|
|
|
|
* @param dir the direction of the segment; one of {@link #HORIZONTAL} or {@link #VERTICAL}.
|
|
|
|
|
* @param col the starting column of the segment.
|
|
|
|
|
* @param row the starting row of the segment.
|
|
|
|
|
* @param pieces the pieces to set in the segment.
|
|
|
|
@@ -508,13 +477,11 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Applies a specified {@link PieceOperation} to all pieces in the
|
|
|
|
|
* specified row or column starting at the specified coordinates and
|
|
|
|
|
* spanning the remainder of the row or column (depending on the
|
|
|
|
|
* application direction) in the board.
|
|
|
|
|
* Applies a specified {@link PieceOperation} to all pieces in the specified row or column
|
|
|
|
|
* starting at the specified coordinates and spanning the remainder of the row or column
|
|
|
|
|
* (depending on the application direction) in the board.
|
|
|
|
|
*
|
|
|
|
|
* @param dir the direction to iterate in; one of {@link #HORIZONTAL}
|
|
|
|
|
* or {@link #VERTICAL}.
|
|
|
|
|
* @param dir the direction to iterate in; one of {@link #HORIZONTAL} or {@link #VERTICAL}.
|
|
|
|
|
* @param col the starting column of the segment.
|
|
|
|
|
* @param row the starting row of the segment.
|
|
|
|
|
* @param op the piece operation to apply to each piece.
|
|
|
|
@@ -526,12 +493,10 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Applies a specified {@link PieceOperation} to all pieces in a row
|
|
|
|
|
* or column segment starting at the specified coordinates and of the
|
|
|
|
|
* specified length in the board.
|
|
|
|
|
* Applies a specified {@link PieceOperation} to all pieces in a row or column segment starting
|
|
|
|
|
* at the specified coordinates and of the specified length in the board.
|
|
|
|
|
*
|
|
|
|
|
* @param dir the direction to iterate in; one of {@link #HORIZONTAL}
|
|
|
|
|
* or {@link #VERTICAL}.
|
|
|
|
|
* @param dir the direction to iterate in; one of {@link #HORIZONTAL} or {@link #VERTICAL}.
|
|
|
|
|
* @param col the starting leftmost column of the segment.
|
|
|
|
|
* @param row the starting bottommost row of the segment.
|
|
|
|
|
* @param len the number of pieces in the segment.
|
|
|
|
@@ -558,8 +523,7 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Applies a specified {@link PieceOperation} to the specified piece
|
|
|
|
|
* in the board.
|
|
|
|
|
* Applies a specified {@link PieceOperation} to the specified piece in the board.
|
|
|
|
|
*
|
|
|
|
|
* @param col the column of the piece.
|
|
|
|
|
* @param row the row of the piece.
|
|
|
|
@@ -580,8 +544,7 @@ public class DropBoard extends Board
|
|
|
|
|
public void dumpAndCompare (Board other)
|
|
|
|
|
{
|
|
|
|
|
if (other != null && !(other instanceof DropBoard)) {
|
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
|
"Can't compare drop board to non-drop-board.");
|
|
|
|
|
throw new IllegalArgumentException("Can't compare drop board to non-drop-board.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DropBoard dother = (DropBoard)other;
|
|
|
|
@@ -623,8 +586,7 @@ public class DropBoard extends Board
|
|
|
|
|
// make sure we're comparing the same class type
|
|
|
|
|
if (!this.getClass().getName().equals(other.getClass().getName())) {
|
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
|
"Can't compare board of different class types " +
|
|
|
|
|
"[src=" + this.getClass().getName() +
|
|
|
|
|
"Can't compare board of different class types [src=" + this.getClass().getName() +
|
|
|
|
|
", other=" + other.getClass().getName() + "].");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -660,9 +622,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the bounds of this board. Note that a single rectangle is
|
|
|
|
|
* re-used internally and so the caller should not modify the
|
|
|
|
|
* returned rectangle.
|
|
|
|
|
* Returns the bounds of this board. Note that a single rectangle is re-used internally and so
|
|
|
|
|
* the caller should not modify the returned rectangle.
|
|
|
|
|
*/
|
|
|
|
|
public Rectangle getBounds ()
|
|
|
|
|
{
|
|
|
|
@@ -681,30 +642,27 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Copies the contents of this board directly into the supplied board,
|
|
|
|
|
* overwriting the destination board in its entirety.
|
|
|
|
|
* Copies the contents of this board directly into the supplied board, overwriting the
|
|
|
|
|
* destination board in its entirety.
|
|
|
|
|
*/
|
|
|
|
|
public void copyInto (DropBoard board)
|
|
|
|
|
{
|
|
|
|
|
// make sure the target board is a valid target
|
|
|
|
|
if (board.getWidth() != _bwid || board.getHeight() != _bhei) {
|
|
|
|
|
Log.warning("Can't copy board into destination board with " +
|
|
|
|
|
"different dimensions [src=" + this +
|
|
|
|
|
", dest=" + board + "].");
|
|
|
|
|
Log.warning("Can't copy board into destination board with different dimensions " +
|
|
|
|
|
"[src=" + this + ", dest=" + board + "].");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy our pieces directly into the board, avoiding any unsightly
|
|
|
|
|
// object allocation which is largely the point of this method,
|
|
|
|
|
// after all.
|
|
|
|
|
int[] dest = ((DropBoard)board).getBoard();
|
|
|
|
|
// copy our pieces directly into the board, avoiding any unsightly object allocation which
|
|
|
|
|
// is largely the point of this method, after all.
|
|
|
|
|
int[] dest = board.getBoard();
|
|
|
|
|
System.arraycopy(_board, 0, dest, 0, (_bwid*_bhei));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the raw board data associated with this board. One
|
|
|
|
|
* shouldn't fiddle about with this unless one knows what one is
|
|
|
|
|
* doing.
|
|
|
|
|
* Returns the raw board data associated with this board. One shouldn't fiddle about with this
|
|
|
|
|
* unless one knows what one is doing.
|
|
|
|
|
*/
|
|
|
|
|
public int[] getBoard ()
|
|
|
|
|
{
|
|
|
|
@@ -740,13 +698,13 @@ public class DropBoard extends Board
|
|
|
|
|
public Object clone ()
|
|
|
|
|
{
|
|
|
|
|
DropBoard board = (DropBoard)super.clone();
|
|
|
|
|
board._board = (int[])_board.clone();
|
|
|
|
|
board._board = _board.clone();
|
|
|
|
|
return board;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the number of characters to which a single piece should be
|
|
|
|
|
* padded when dumping the board for debugging purposes.
|
|
|
|
|
* Returns the number of characters to which a single piece should be padded when dumping the
|
|
|
|
|
* board for debugging purposes.
|
|
|
|
|
*/
|
|
|
|
|
protected int getPadWidth ()
|
|
|
|
|
{
|
|
|
|
@@ -754,16 +712,14 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a string representation of the given piece for use when
|
|
|
|
|
* dumping the board.
|
|
|
|
|
* Returns a string representation of the given piece for use when dumping the board.
|
|
|
|
|
*/
|
|
|
|
|
protected String formatPiece (int piece)
|
|
|
|
|
{
|
|
|
|
|
return (piece == PIECE_NONE) ? "." : String.valueOf(piece);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** An operation that sets the pieces in a board segment to a
|
|
|
|
|
* specified array of pieces. */
|
|
|
|
|
/** An operation that sets the pieces in a board segment to a specified array of pieces. */
|
|
|
|
|
protected static class SetSegmentOperation implements PieceOperation
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
@@ -810,8 +766,8 @@ public class DropBoard extends Board
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns true if we attempted to set a piece outside the bounds
|
|
|
|
|
* of the board during the course of our operation.
|
|
|
|
|
* Returns true if we attempted to set a piece outside the bounds of the board during the
|
|
|
|
|
* course of our operation.
|
|
|
|
|
*/
|
|
|
|
|
public boolean getError ()
|
|
|
|
|
{
|
|
|
|
@@ -859,29 +815,26 @@ public class DropBoard extends Board
|
|
|
|
|
// CCW CW
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// used to compute the bounds of the isBlockEmpty() block based on the
|
|
|
|
|
// drop block's orientation and "root" block position
|
|
|
|
|
// used to compute the bounds of the isBlockEmpty() block based on the drop block's orientation
|
|
|
|
|
// and "root" block position
|
|
|
|
|
protected static final int[] ORIENT_WIDTHS = { 2, 1, 2, 1 };
|
|
|
|
|
protected static final int[] ORIENT_HEIGHTS = { 1, 2, 1, 2 };
|
|
|
|
|
|
|
|
|
|
// used to compute the origin of the isBlockEmpty() block based on the
|
|
|
|
|
// drop block's orientation and "root" block position
|
|
|
|
|
// used to compute the origin of the isBlockEmpty() block based on the drop block's orientation
|
|
|
|
|
// and "root" block position
|
|
|
|
|
protected static final int[] ORIENT_ORIGIN_DX = { -1, 0, 0, 0 };
|
|
|
|
|
protected static final int[] ORIENT_ORIGIN_DY = { 0, 0, 0, 1 };
|
|
|
|
|
|
|
|
|
|
// used to coerce the block when rotating either a space to the left
|
|
|
|
|
// or right (or not at all)
|
|
|
|
|
// used to coerce the block when rotating either a space to the left or right (or not at all)
|
|
|
|
|
protected static final int[] COERCE_DX = { 0, 1, -1 };
|
|
|
|
|
|
|
|
|
|
/** The operation used to set the pieces in a board segment. */
|
|
|
|
|
protected static final SetSegmentOperation _setSegmentOp =
|
|
|
|
|
new SetSegmentOperation();
|
|
|
|
|
protected static final SetSegmentOperation _setSegmentOp = new SetSegmentOperation();
|
|
|
|
|
|
|
|
|
|
/** The operation used to set a piece in a board segment. */
|
|
|
|
|
protected static final SetPieceOperation _setPieceOp =
|
|
|
|
|
new SetPieceOperation();
|
|
|
|
|
protected static final SetPieceOperation _setPieceOp = new SetPieceOperation();
|
|
|
|
|
|
|
|
|
|
/** The number of characters to which each board piece should be
|
|
|
|
|
* padded when outputting for debug purposes. */
|
|
|
|
|
/** The number of characters to which each board piece should be padded when outputting for
|
|
|
|
|
* debug purposes. */
|
|
|
|
|
protected static final int DEFAULT_PAD_WIDTH = 3;
|
|
|
|
|
}
|
|
|
|
|