Substantially improved performance of Board.isLegal().

No longer a static method.
AlphaBeta is now playable with 4-move lookahead (although slow).
This commit is contained in:
Woody Folsom
2012-05-01 09:38:32 -04:00
parent 48915071d4
commit 924780baaf
4 changed files with 37 additions and 42 deletions

View File

@@ -12,14 +12,20 @@ public class Board {
public static final int NUM_ROWS = 5;
public static final int ROW_REMOVAL_SIZE = 3;
public static boolean isLegal(Board brd, CellPointer cp) {
private boolean boardEmpty = true;
public boolean isLegal(CellPointer cp) {
//coordinates are out of board bounds
if (cp.r < 0 || cp.r >= Board.NUM_ROWS || cp.c < 0
|| cp.c >= Board.NUM_COLS) {
return false;
}
boolean legal = (brd.getTile(cp.r, cp.c) == TileColor.NONE);
//target coordinate already has a tile
if (board[cp.r][cp.c] != TileColor.NONE) {
return false;
}
boolean rowUp = (cp.r - 1) >= 0;
boolean rowDown = (cp.r + 1) < Board.NUM_ROWS;
boolean colUp = (cp.c - 1) >= 0;
@@ -27,49 +33,49 @@ public class Board {
// r-1 / c-1
if (rowUp && colUp
&& (brd.getTile(cp.r - 1, cp.c - 1) != TileColor.NONE)) {
return legal && true;
&& (board[cp.r - 1][ cp.c - 1] != TileColor.NONE)) {
return true;
}
// r-1 / c
if (rowUp && (brd.getTile(cp.r - 1, cp.c) != TileColor.NONE)) {
return legal && true;
if (rowUp && (board[cp.r - 1][ cp.c] != TileColor.NONE)) {
return true;
}
// r-1 / c+1
if (rowUp && colDown
&& (brd.getTile(cp.r - 1, cp.c + 1) != TileColor.NONE)) {
return legal && true;
&& (board[cp.r - 1][ cp.c + 1] != TileColor.NONE)) {
return true;
}
// r / c-1
if (colUp && (brd.getTile(cp.r, cp.c - 1) != TileColor.NONE)) {
return legal && true;
if (colUp && (board[cp.r][ cp.c - 1] != TileColor.NONE)) {
return true;
}
// r / c+1
if (colDown && (brd.getTile(cp.r, cp.c + 1) != TileColor.NONE)) {
return legal && true;
if (colDown && (board[cp.r][ cp.c + 1] != TileColor.NONE)) {
return true;
}
// r+1 / c-1
if (rowDown && colUp
&& (brd.getTile(cp.r + 1, cp.c - 1) != TileColor.NONE)) {
return legal && true;
&& (board[cp.r + 1][ cp.c - 1] != TileColor.NONE)) {
return true;
}
// r+1 / c
if (rowDown && (brd.getTile(cp.r + 1, cp.c) != TileColor.NONE)) {
return legal && true;
if (rowDown && (board[cp.r + 1][ cp.c] != TileColor.NONE)) {
return true;
}
// r+1 / c+1
if (rowDown && colDown
&& (brd.getTile(cp.r + 1, cp.c + 1) != TileColor.NONE)) {
return legal && true;
&& (board[cp.r + 1][ cp.c + 1] != TileColor.NONE)) {
return true;
}
return brd.isEmpty();
return boardEmpty;
}
private final TileColor[][] board;
@@ -91,6 +97,7 @@ public class Board {
for (int r = 0; r < NUM_ROWS; r++) {
for (int c = 0; c < NUM_COLS; c++) {
this.boardEmpty = that.boardEmpty;
this.board[r][c] = that.board[r][c];
}
}
@@ -163,7 +170,7 @@ public class Board {
}
public boolean playTile(CellPointer cp, TileColor tile) {
if (!isLegal(this, cp)) {
if (!isLegal(cp)) {
return false; // Illegal move.
}
@@ -304,6 +311,8 @@ public class Board {
}
numPlies++;
boardEmpty = false;
return true;
}
@@ -320,16 +329,4 @@ public class Board {
}
return sb1.toString();
}
private boolean isEmpty() {
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
if (getTile(r, c) != TileColor.NONE) {
return false;
}
}
}
return true;
}
}

View File

@@ -286,7 +286,7 @@ public class CountingPlayer implements Player {
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
if (Board.isLegal(board, new CellPointer(r, c))) {
if (board.isLegal(new CellPointer(r, c))) {
moves.add(new Move(TileColor.BLUE, r, c));
moves.add(new Move(TileColor.GREEN, r, c));
moves.add(new Move(TileColor.RED, r, c));

View File

@@ -80,7 +80,7 @@ public class NeuralNetworkMoveGenerator implements MoveGenerator {
}
}
while (!Board.isLegal(board, mv.getCell())) {
while (!board.isLegal(mv.getCell())) {
mv = new Move(mv.getColor(), new CellPointer(
PlayerModel.rand.nextInt(Board.NUM_ROWS),
PlayerModel.rand.nextInt(Board.NUM_COLS)));

View File

@@ -22,13 +22,11 @@ public class ValidMoveGenerator implements MoveGenerator {
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
if (Board.isLegal(board, new CellPointer(r, c))) {
for (TileColor color : TileColor.values()) {
if (color == TileColor.NONE) {
continue;
}
validMoves.add(new Move(color, r, c));
}
if (board.isLegal(new CellPointer(r, c))) {
validMoves.add(new Move(TileColor.BLUE, r, c));
validMoves.add(new Move(TileColor.GREEN, r, c));
validMoves.add(new Move(TileColor.RED, r, c));
validMoves.add(new Move(TileColor.YELLOW, r, c));
}
}
}