chessai
college code for ai playing chess in java
git clone https://9o.is/git/chessai.git
commit 1bad212500c0a722f31f595db978913d8adb04a7 parent 12b0c512dc1567a433da0ce742bb728a82f8360b Author: Jul <jul@9o.is> Date: Thu, 6 Dec 2012 17:38:57 -0500 Test if it plays smarter Diffstat:
| M | src/main/java/chess/ChessBoard.java | | | 21 | +++++++++++---------- |
| M | src/main/java/chess/ChessGame.java | | | 22 | +--------------------- |
| M | src/main/java/chess/ChessMove.java | | | 9 | +++++++++ |
| M | src/main/java/chess/ChessPlayer.java | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/main/java/chess/utils/ChessColor.java | | | 5 | +++++ |
5 files changed, 107 insertions(+), 31 deletions(-)
diff --git a/src/main/java/chess/ChessBoard.java b/src/main/java/chess/ChessBoard.java @@ -1,5 +1,6 @@ package chess; +import chess.utils.ChessColor; import chess.utils.ChessDirection; import java.util.ArrayList; @@ -72,16 +73,16 @@ public class ChessBoard { return false; } - public List<ChessCoordinate> getPlayerPieces(ChessPlayer player) { - List<ChessCoordinate> playerPieces = new ArrayList<ChessCoordinate>(); - for(int i=1; i<=ChessCoordinate.MAX; i++) - for(int j=1; j<=ChessCoordinate.MAX; j++) { - ChessPiece piece = ChessPiece.find(state.get(new ChessCoordinate(j,i))); - if(piece.getColor() == player.getColor()) - playerPieces.add(new ChessCoordinate(j,i)); - } - return playerPieces; - } + public List<ChessCoordinate> getPieces(ChessColor color) { + List<ChessCoordinate> playerPieces = new ArrayList<ChessCoordinate>(); + for(int i=1; i<=ChessCoordinate.MAX; i++) + for(int j=1; j<=ChessCoordinate.MAX; j++) { + ChessPiece piece = ChessPiece.find(state.get(new ChessCoordinate(j,i))); + if(piece.getColor() == color) + playerPieces.add(new ChessCoordinate(j,i)); + } + return playerPieces; + } //CHECK public String printState() { diff --git a/src/main/java/chess/ChessGame.java b/src/main/java/chess/ChessGame.java @@ -31,30 +31,10 @@ public class ChessGame { // our turn while(status.isReady()) { - ChessRules.INSTANCE.setLog(false); - - List<ChessCoordinate> playerPieces = - board.getPlayerPieces(player); - - List<ChessMove> moves = new ArrayList<ChessMove>(); - - for(ChessCoordinate src : playerPieces) { - List<ChessMove> possibleMoves = - ChessMove.possibleMoves(src, board.getState()); - for(ChessMove move : possibleMoves) - moves.add(move); - } - - // just a test - int i = new java.util.Random().nextInt(moves.size()); - ChessMove move = moves.get(i); - ChessClock clock = new ChessClock(status.getSecondsLeft()); - // TODO evaluate capture/protection points - // TODO store tree in memory (or other storage option) - // TODO eval clock and pick best move + ChessMove move = player.bestPossibleMove(board); MoveResponse response = server.push(board.getState(), move); if(response.isResult() && board.move(move)) { diff --git a/src/main/java/chess/ChessMove.java b/src/main/java/chess/ChessMove.java @@ -12,6 +12,7 @@ public class ChessMove { private ChessCoordinate coordinate; private ChessDirection direction; + private int evaluation; private int steps; public ChessMove( @@ -63,6 +64,14 @@ public class ChessMove { return moves; } + public int getEvaluation() { + return evaluation; + } + + public void setEvaluation(int evaluation) { + this.evaluation = evaluation; + } + public String toString() { return coordinate+" "+direction+" "+steps+" steps"; } diff --git a/src/main/java/chess/ChessPlayer.java b/src/main/java/chess/ChessPlayer.java @@ -1,6 +1,10 @@ package chess; import chess.utils.ChessColor; +import chess.utils.ChessType; + +import java.util.ArrayList; +import java.util.List; /** * Check @@ -35,6 +39,83 @@ public class ChessPlayer { moves = 0; } + + + public List<ChessMove> possibleMoves(List<ChessCoordinate> pieces, ChessState state) { + List<ChessMove> moves = new ArrayList<ChessMove>(); + for(ChessCoordinate src : pieces) { + List<ChessMove> possibleMoves = + ChessMove.possibleMoves(src,state); + for(ChessMove move : possibleMoves) + moves.add(move); + } + return moves; + } + + public ChessMove bestPossibleMove(ChessBoard board) { + ChessRules.INSTANCE.setLog(false); + List<ChessCoordinate> pieces = board.getPieces(color); + List<ChessMove> moves = possibleMoves(pieces, board.getState()); + + ChessMove bestMove = null; + int eval = -999999999; + + while(!moves.isEmpty()) { + ChessMove move = moves.get(0); + + ChessBoard tmpBoard = board; + tmpBoard.move(move); + int ourscore = evaluate(move,tmpBoard); + int oppEval = evaluateOpponentMove(tmpBoard, ourscore); + if(oppEval > eval){ + bestMove=move; + eval= oppEval; + } + + moves.remove(0); + } + return bestMove; + } + + public int evaluateOpponentMove(ChessBoard board, int ourscore) { + + List<ChessCoordinate> pieces = board.getPieces(color.opposite()); + List<ChessMove> moves = possibleMoves(pieces, board.getState()); + + int eval = 999999999; + while(!moves.isEmpty()) { + ChessMove move = moves.get(0); + int moveEval = ourscore - evaluate(move, board); + + if(eval > moveEval) { // we have a minimum + if(eval == 999999999) + eval = moveEval; + else // prune + return moveEval; + } + moves.remove(0); + } + return eval; + } + + private int evaluate(ChessMove move, ChessBoard board) { + ChessCoordinate src = move.getCoordinate(); + ChessCoordinate dest = src.getCoordinate(board.getState(), move); + + ChessPiece srcPiece = ChessPiece.find(board.getState().get(src)); + ChessPiece destPiece = ChessPiece.find(board.getState().get(dest)); + + ChessType srcType = srcPiece.getType(); + ChessType destType = destPiece.getType(); + + // CAPTURE + if(destType != ChessType.NA) { + return destType.getValue(); + } else { + return 0; + } + } + public ChessColor getColor() { return color; } diff --git a/src/main/java/chess/utils/ChessColor.java b/src/main/java/chess/utils/ChessColor.java @@ -17,4 +17,9 @@ public enum ChessColor { public String toString() { return symbol; } + + public ChessColor opposite() { + if(this==WHITE) return BLACK; + else return WHITE; + } }