From 924780baafaa34e347616f0dbd6d9baa9f914cfc Mon Sep 17 00:00:00 2001 From: Woody Folsom Date: Tue, 1 May 2012 09:38:32 -0400 Subject: [PATCH] Substantially improved performance of Board.isLegal(). No longer a static method. AlphaBeta is now playable with 4-move lookahead (although slow). --- src/model/Board.java | 63 +++++++++---------- src/model/comPlayer/CountingPlayer.java | 2 +- .../generator/NeuralNetworkMoveGenerator.java | 2 +- .../generator/ValidMoveGenerator.java | 12 ++-- 4 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/model/Board.java b/src/model/Board.java index bb91d0e..da1f9cb 100644 --- a/src/model/Board.java +++ b/src/model/Board.java @@ -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; - } } \ No newline at end of file diff --git a/src/model/comPlayer/CountingPlayer.java b/src/model/comPlayer/CountingPlayer.java index b4ce4fc..6e476b8 100644 --- a/src/model/comPlayer/CountingPlayer.java +++ b/src/model/comPlayer/CountingPlayer.java @@ -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)); diff --git a/src/model/comPlayer/generator/NeuralNetworkMoveGenerator.java b/src/model/comPlayer/generator/NeuralNetworkMoveGenerator.java index 1eb59e3..7e9cb75 100644 --- a/src/model/comPlayer/generator/NeuralNetworkMoveGenerator.java +++ b/src/model/comPlayer/generator/NeuralNetworkMoveGenerator.java @@ -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))); diff --git a/src/model/comPlayer/generator/ValidMoveGenerator.java b/src/model/comPlayer/generator/ValidMoveGenerator.java index f4879a4..f1e5109 100644 --- a/src/model/comPlayer/generator/ValidMoveGenerator.java +++ b/src/model/comPlayer/generator/ValidMoveGenerator.java @@ -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)); } } }