📄 boardstate.java
字号:
* <code>countPossibleMoves()</code><br><br>
* This method caches results of possible moves calculation for performance.
* @param white The color of the player
* @return An array with possible moves, containing source indices, destination indices,
* and the dice index used for specific move.
*/
public int[][] getPossibleMoves(boolean white)
{
if (!m_possibleMovesCalculated) calcPossibleMoves(white);
return m_possibleMoves;
}
/**
* Returns number of possible moves for current game state.
* See <code>getPossibleMoves</code>.<br><br>
* This method caches results of possible moves calculation for performance.
* @param white The color of the player
* @return Number of possible moves.
*/
public int countPossibleMoves(boolean white)
{
if (!m_possibleMovesCalculated) calcPossibleMoves(white);
return m_possibleMoveCount;
}
/**
* Throws dices, and puts new values in the dice value vector.
* If both dices are of same value, the dice value vector is
* expanded to contain four values. The dice value vector is
* sorted ascending.
*
* @param dice1 value of dice one
* @param dice2 value of dice two
*/
public synchronized void newDiceValues(int dice1, int dice2)
{
m_possibleMovesCalculated = false;
m_undoableMoveCount = 0;
m_dice[0] = dice1;
m_dice[1] = dice2;
m_diceVals = 2;
if (dice1 == dice2)
{
m_dice[2] = dice1;
m_dice[3] = dice1;
m_diceVals = 4;
}
else if (dice1 > dice2)
{
// Sort dice value vector to make movement more logical
m_dice[0] = dice2;
m_dice[1] = dice1;
}
}
/**
* Returns value of specified dice
* @param diceIndex the dice, 0 or 1
* @return a value between 1 and 6
*/
public int getDiceValue(int diceIndex)
{
return m_dice[diceIndex];
}
/**
* Returns number of possible undoable moves
* @return number of possible undoable moves
*/
public synchronized int countUndoableMoves()
{
return m_undoableMoveCount;
}
/**
* Calculates possible moves for specified player.
* @param white True for white player, false for black.
*/
protected void calcPossibleMoves(boolean white)
{
m_possibleMoveCount = 0;
int[] player = WHITE, opponent = BLACK;
if (!white)
{
player = BLACK;
opponent = WHITE;
}
// calculate number of unique dicevalues
int includeDices = m_diceVals > 2 ? 1 : m_diceVals;
if (includeDices == 2 && (m_dice[0] == m_dice[1]))
includeDices = 1;
// Check pieces under guard, first preference
if (player[POS_GUARD] > 0)
{
// try all dicevalues
for (int d = 0; d < includeDices; d++)
{
int toIndex;
if (white)
toIndex = m_dice[d] - 1;
else
toIndex = POS_BOARD - m_dice[d] + 1;
if (Rules.isValidFromGuard(this, toIndex, player, opponent))
{
// found a valid move, add to array
m_possibleMoves[m_possibleMoveCount][PM_SOUR] = POS_GUARD;
m_possibleMoves[m_possibleMoveCount][PM_DEST] = toIndex;
m_possibleMoves[m_possibleMoveCount++][PM_DICE] = d;
}
}
}
else
// No pieces under guard
{
int fromIndex, diceIndex;
boolean inverseDiceValues = false;
// Try all positions where pieces are found
for (int i = 0; i <= Board.POS_BOARD; i++)
{
// Flip fromindex after half board
// to make cursor interaction more intuitive
if (i < 12)
fromIndex = i;
else
fromIndex = Board.POS_BOARD - (i-12);
if (player[fromIndex] > 0)
{
if (includeDices > 0)
{
inverseDiceValues =
( white & fromIndex + m_dice[0] > 11) |
(!white & fromIndex - m_dice[0] < 12);
}
// Found some pieces, try all unique dicevalues
for (int d = 0; d < includeDices; d++)
{
if (inverseDiceValues)
diceIndex = includeDices - d - 1;
else
diceIndex = d;
int toIndex = fromIndex;
if (white)
{
toIndex += m_dice[diceIndex];
}
else
{
toIndex -= m_dice[diceIndex];
if (toIndex < 0) toIndex = -toIndex + POS_BOARD;
}
if (Rules.isValidMove(this, fromIndex, toIndex, white, player, opponent))
{
// found a valid move, add to array
m_possibleMoves[m_possibleMoveCount][PM_SOUR] =
fromIndex;
m_possibleMoves[m_possibleMoveCount][PM_DEST] =
toIndex > POS_BOARD ? POS_OUT : toIndex;
m_possibleMoves[m_possibleMoveCount++][PM_DICE] =
diceIndex;
}
} // per unique diceval
}
} // per pos on board
}
m_possibleMovesCalculated = true;
}
/**
* Returns true if there are no pieces of specified color
* before specified index.
* @param white True for white, false for black
* @param index The index
* @return true if no pieces before, false otherwise
*/
public boolean isNoneBefore(boolean white, int index)
{
boolean none = true;
int dir = -1;
int[] player = WHITE;
if (!white)
{
player = BLACK;
dir = 1;
}
index += dir;
while (none && index > 0 && index <= POS_BOARD)
{
none = player[index] == 0;
index += dir;
}
return none;
}
/**
* Checks if there are any pieces outside home - in that case pieces
* must not be moved off the boards.
* @param white true to check if all white is home,
* false to check if all black is home.
* @return true if no pieces outside home, false otherwise.
*/
public boolean areAllPiecesHome(boolean white)
{
boolean homeOk = true;
int[] player = WHITE;
if (!white)
{
player = BLACK;
}
for (int pos = 0; homeOk && pos <= POS_BOARD-6; pos++)
{
int index = getPlayerIndex(white, pos,0);
homeOk = player[index] == 0;
}
return homeOk;
}
/**
* Loads state from specified input stream. See <code>saveState</code> for format.
* @param dis the input stream
* @throws IOException
* @return size of data in bytes
*/
public int loadState(DataInputStream dis) throws IOException
{
int len = 0;
m_chooseTurns = dis.readBoolean();
len += 1;
m_diceThrown = dis.readBoolean();
len += 1;
boolean whiteTurn = dis.readBoolean();
len += 1;
m_undoableMoveCount = dis.readInt();
len += 4;
for (int a = 0; a < 5; a++)
{
for (int b = 0; b < 4; b++)
{
m_undoableMoves[a][b] = dis.readInt();
len += 4;
}
}
m_diceVals = dis.readInt();
len += 4;
for (int a = 0; a < 4; a++)
{
m_dice[a] = dis.readInt();
len += 4;
}
len += loadBoard(dis);
m_possibleMovesCalculated = false;
setCurrentPlayer(whiteTurn);
return len;
}
/**
* Saves current state to specified outputstream. Format:
* boolean m_chooseTurns
* boolean m_diceThrown
* boolean whiteTurn;
* int m_undoableMoveCount
* int[][] m_undoableMoves[5][4]
* int m_diceVals
* int[] m_dice[4]
* Board this
* @param dos the output stream
* @throws IOException
* @return size of data in bytes
*/
public int saveState(DataOutputStream dos) throws IOException
{
int len = 0;
dos.writeBoolean(m_chooseTurns);
len += 1;
dos.writeBoolean(m_diceThrown);
len += 1;
dos.writeBoolean(m_currentPlayer.isWhite());
len += 1;
dos.writeInt(m_undoableMoveCount);
len += 4;
for (int a = 0; a < 5; a++)
{
for (int b = 0; b < 4; b++)
{
dos.writeInt(m_undoableMoves[a][b]);
len += 4;
}
}
dos.writeInt(m_diceVals);
len += 4;
for (int a = 0; a < 4; a++)
{
dos.writeInt(m_dice[a]);
len += 4;
}
len += saveBoard(dos);
return len;
}
private BoardState() {}
public static BoardState getInstance()
{
if (m_instance == null)
{
m_instance = new BoardState();
}
return m_instance;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -