chessai
college code for ai playing chess in java
git clone https://9o.is/git/chessai.git
commit 7b9c8e786deb73691d0ecce8a74301bf3fb5adbd Author: Jul <jul@9o.is> Date: Fri, 30 Nov 2012 20:02:46 -0500 initialized Diffstat:
| A | .gitignore | | | 26 | ++++++++++++++++++++++++++ |
| A | src/chess/ChessBoard.java | | | 118 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/chess/ChessCoordinate.java | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/chess/ChessGame.java | | | 29 | +++++++++++++++++++++++++++++ |
| A | src/chess/ChessRules.java | | | 82 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/chess/ChessState.java | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/chess/Player.java | | | 20 | ++++++++++++++++++++ |
| A | src/chess/piece/ChessColor.java | | | 20 | ++++++++++++++++++++ |
| A | src/chess/piece/ChessMove.java | | | 11 | +++++++++++ |
| A | src/chess/piece/ChessPiece.java | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/chess/piece/ChessType.java | | | 30 | ++++++++++++++++++++++++++++++ |
11 files changed, 496 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -0,0 +1,26 @@ +*.class + +# Package Files # +*.jar +*.war +*.ear + +# Intellij IDEA +*.iws +*.ipr +*.iml +*.eml +*.userlibraries + +# Eclipse & Netbeans +.project +.settings +.classpath +.idea* +.scala_dependencies + +# swap files +*~ +*# +*.sw[op] +._* diff --git a/src/chess/ChessBoard.java b/src/chess/ChessBoard.java @@ -0,0 +1,118 @@ +package chess; + +import chess.piece.*; + +/** + * Created with IntelliJ IDEA. + * User: julio + * Date: 11/29/12 + * Time: 12:57 PM + * To change this template use File | Settings | File Templates. + */ +public class ChessBoard { + private ChessState board; + private ChessRules rules; + private Player player; + private int moves; + + public ChessBoard(Player player) { + rules = new ChessRules(player); + board = new ChessState(); + this.player = player; + this.moves = 0; + } + + //CHECK + public void init() throws Exception { + board.set(new ChessCoordinate('a',8), ChessPiece.BLACK_ROOK); + board.set(new ChessCoordinate('b',8), ChessPiece.BLACK_KNIGHT); + board.set(new ChessCoordinate('c',8), ChessPiece.BLACK_BISHOP); + board.set(new ChessCoordinate('d',8), ChessPiece.BLACK_QUEEN); + board.set(new ChessCoordinate('e',8), ChessPiece.BLACK_KING); + board.set(new ChessCoordinate('f',8), ChessPiece.BLACK_BISHOP); + board.set(new ChessCoordinate('g',8), ChessPiece.BLACK_KNIGHT); + board.set(new ChessCoordinate('h',8), ChessPiece.BLACK_ROOK); + + for(int i=1; i<= ChessCoordinate.MAX; i++) + board.set(new ChessCoordinate(i,7), ChessPiece.BLACK_PAWN); + + board.set(new ChessCoordinate('a',1), ChessPiece.WHITE_ROOK); + board.set(new ChessCoordinate('b',1), ChessPiece.WHITE_KNIGHT); + board.set(new ChessCoordinate('c',1), ChessPiece.WHITE_BISHOP); + board.set(new ChessCoordinate('d',1), ChessPiece.WHITE_QUEEN); + board.set(new ChessCoordinate('e',1), ChessPiece.WHITE_KING); + board.set(new ChessCoordinate('f',1), ChessPiece.WHITE_BISHOP); + board.set(new ChessCoordinate('g',1), ChessPiece.WHITE_KNIGHT); + board.set(new ChessCoordinate('h',1), ChessPiece.WHITE_ROOK); + + for(int i=1; i<= ChessCoordinate.MAX; i++) + board.set(new ChessCoordinate(i,2), ChessPiece.WHITE_PAWN); + } + + //CHECK + public void move( + ChessCoordinate coor, + ChessMove move, + int steps) throws Exception { + move(coor, getCoordinate(coor, move, steps)); + } + + //CHECK + public void move( + ChessCoordinate coor, + ChessMove firstMove, + int steps1, + ChessMove secondMove, + int steps2) throws Exception { + ChessCoordinate coor1 = getCoordinate(coor, firstMove, steps1); + ChessCoordinate coor2 = getCoordinate(coor1, secondMove, steps2); + move(coor, coor2); + } + + //CHECK + public void move(ChessCoordinate coor, ChessCoordinate coor1) { + if(!rules.invalidMove(board, coor, coor1)) { + rules.applyCaptureRule(); + board.move(coor, coor1); + moves++; + } + } + + //CHECK + public String getState() { + byte[][] state = board.getState(); + String result = "Move: "+moves+"\n"; + + for(int i=0; i< ChessCoordinate.MAX; i++) { + for(int j=0; j< ChessCoordinate.MAX; j++) + result += ChessPiece.find(state[i][j])+" | "; + result += "\n"; + } + return result; + } + + //CHECK + private ChessCoordinate getCoordinate( + ChessCoordinate coor, + ChessMove move, + int steps) throws Exception { + int x = coor.getFileNumber(); + int y = coor.getRank(); + + if(player.getColor() == ChessColor.WHITE) { + if(move == ChessMove.FORWARD) y += steps; + else if(move == ChessMove.BACK) y -= steps; + else if(move == ChessMove.LEFT) x -= steps; + else if(move == ChessMove.RIGHT) x += steps; + } else if(player.getColor() == ChessColor.BLACK) { + if(move == ChessMove.FORWARD) y -= steps; + else if(move == ChessMove.BACK) y += steps; + else if(move == ChessMove.LEFT) x += steps; + else if(move == ChessMove.RIGHT) x -= steps; + } else + throw new Exception( + this.getClass()+": player is invalid color."); + + return new ChessCoordinate(x,y); + } +} diff --git a/src/chess/ChessCoordinate.java b/src/chess/ChessCoordinate.java @@ -0,0 +1,57 @@ +package chess; + +/** + * Check + */ +public class ChessCoordinate { + + public static final int MAX = 8; + private static final String ERROR_MSG = + ChessCoordinate.class+": Invalid coordinate."; + + private char file; + private int rank; + + + public ChessCoordinate(char file, int rank) throws Exception { + if(isInvalid(file, rank)) + throw new Exception(ERROR_MSG); + + this.file = file; + this.rank = rank; + } + + public ChessCoordinate(int file, int rank) throws Exception { + this((char) (file-1+97), rank); // 97 = 'a' + } + + public void set(char x, int y) throws Exception { + if(isInvalid(x,y)) + throw new Exception(ERROR_MSG); + + this.file = x; + this.rank = y-1; + } + + public char getFile() { + return file; + } + + public int getRank() { + return rank; + } + + public int getFileNumber() { + return file - 96; // 97 = 'a' + } + + private boolean isInvalid(char x, int y) { + if(x > 'h' || x < 'a' || y > 8 || y < 1) + return true; + return false; + } + + public String toString() { + return ""+file+rank; + } +} diff --git a/src/chess/ChessGame.java b/src/chess/ChessGame.java @@ -0,0 +1,29 @@ +package chess; + +import chess.piece.ChessColor; +import chess.piece.ChessMove; + +/** + * Created with IntelliJ IDEA. + * User: julio + * Date: 11/29/12 + * Time: 2:06 PM + * To change this template use File | Settings | File Templates. + */ +public class ChessGame { + + public static void main(String[] args) { + Player player = new Player(ChessColor.WHITE); + ChessBoard game = new ChessBoard(player); + + try { + game.init(); + game.move(new ChessCoordinate('d',2), ChessMove.FORWARD, 1); + game.move(new ChessCoordinate('b',1), ChessMove.FORWARD, 2, ChessMove.RIGHT, 1); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println(game.getState()); + } +} diff --git a/src/chess/ChessRules.java b/src/chess/ChessRules.java @@ -0,0 +1,82 @@ +package chess; + +import chess.piece.ChessPiece; + +/** + * Check + */ +public class ChessRules { + + private ChessState state; + private ChessCoordinate src; + private ChessCoordinate dest; + + private static final String failurePrefix = + ChessRules.class + ": FAILED -> "; + + private static final String capturePrefix = + ChessRules.class + ": CAPTURE -> "; + + private Player player; + + public ChessRules(Player player) { + this.player = player; + } + + // must be called after testing invalid is false + // eg. if(!invalidMove(...)) applyCaptureRule(); + // CHECK + public void applyCaptureRule() { + final ChessPiece srcPiece = ChessPiece.find(state.get(src)); + final ChessPiece destPiece = ChessPiece.find(state.get(dest)); + + // are the source and destination pieces different colors? + if(srcPiece.getColor() != destPiece.getColor() && + srcPiece != ChessPiece.NA && + destPiece != ChessPiece.NA) { + System.out.println(capturePrefix + + srcPiece + src + destPiece + dest); + } + } + + // CHECK + public boolean invalidMove( + ChessState state, + ChessCoordinate src, + ChessCoordinate dest) { + this.state = state; + this.src = src; + this.dest = dest; + + return empty() || selfOccupied(); + } + + /* + * Checks if source coordinate has a chess piece. + */ + private boolean empty() { + final ChessPiece srcPiece = ChessPiece.find(state.get(src)); + if(srcPiece == ChessPiece.NA) { + System.err.println(failurePrefix+"Empty test"); + return true; + } else + return false; + } + + /* + * Checks if player moved a chess piece onto one of his own pieces. + */ + private boolean selfOccupied() { + final ChessPiece srcPiece = ChessPiece.find(state.get(src)); + final ChessPiece destPiece = ChessPiece.find(state.get(dest)); + + // are the source and destination pieces same color? + if(srcPiece.getColor() == destPiece.getColor()) { + System.err.println(failurePrefix+"Self Occupied"); + return true; + } else + return false; + } + + //private boolean +} diff --git a/src/chess/ChessState.java b/src/chess/ChessState.java @@ -0,0 +1,50 @@ +package chess; + +import chess.piece.ChessPiece; + +/** + * Check + */ +public class ChessState { + private byte[][] state; + + public ChessState() { + state = new byte[ChessCoordinate.MAX][ChessCoordinate.MAX]; + } + + public byte[][] getState() { + return state; + } + + public void set(ChessCoordinate coor, ChessPiece piece) { + int rank = fixRankOrder(coor.getRank()); + state[rank-1][coor.getFileNumber()-1] = (byte) piece.getNum(); + } + + public byte get(ChessCoordinate coor) { + int rank = fixRankOrder(coor.getRank()); + return state[rank-1][coor.getFileNumber()-1]; + } + + public void move(ChessCoordinate coor, ChessCoordinate coor1) { + int rank = fixRankOrder(coor.getRank()); + int rank1 = fixRankOrder(coor1.getRank()); + + state[rank1-1][coor1.getFileNumber()-1] = + state[rank-1][coor.getFileNumber()-1]; + state[rank-1][coor.getFileNumber()-1] = 0; + } + + private int fixRankOrder(int rank) { + final int max = ChessCoordinate.MAX; + if(rank > max/2) { + return max % rank + 1; + } else { + // TODO algorithm? + if(rank==4) return 5; + if(rank==3) return 6; + if(rank==2) return 7; + else return 8; + } + } +} diff --git a/src/chess/Player.java b/src/chess/Player.java @@ -0,0 +1,20 @@ +package chess; + +import chess.piece.ChessColor; + +/** + * Check + */ +public class Player { + private int points; + private ChessColor color; + + public Player(ChessColor color) { + this.color = color; + points = 0; + } + + public ChessColor getColor() { + return color; + } +} diff --git a/src/chess/piece/ChessColor.java b/src/chess/piece/ChessColor.java @@ -0,0 +1,20 @@ +package chess.piece; + +/** + * Check + */ +public enum ChessColor { + BLACK ("B"), + WHITE ("W"), + NA (" "); + + private String symbol; + + ChessColor(String symbol) { + this.symbol = symbol; + } + + public String toString() { + return symbol; + } +} diff --git a/src/chess/piece/ChessMove.java b/src/chess/piece/ChessMove.java @@ -0,0 +1,11 @@ +package chess.piece; + +/** + * Check + */ +public enum ChessMove { + FORWARD, + BACK, + LEFT, + RIGHT; +} diff --git a/src/chess/piece/ChessPiece.java b/src/chess/piece/ChessPiece.java @@ -0,0 +1,53 @@ +package chess.piece; + +/** + * Check + */ +public enum ChessPiece { + BLACK_KING (12, ChessColor.BLACK, ChessType.KING), + BLACK_QUEEN (11, ChessColor.BLACK, ChessType.QUEEN), + BLACK_BISHOP (10, ChessColor.BLACK, ChessType.BISHOP), + BLACK_KNIGHT (9, ChessColor.BLACK, ChessType.KNIGHT), + BLACK_ROOK (8, ChessColor.BLACK, ChessType.ROOK), + BLACK_PAWN (7, ChessColor.BLACK, ChessType.PAWN), + WHITE_KING (6, ChessColor.WHITE, ChessType.KING), + WHITE_QUEEN (5, ChessColor.WHITE, ChessType.QUEEN), + WHITE_BISHOP (4, ChessColor.WHITE, ChessType.BISHOP), + WHITE_KNIGHT (3, ChessColor.WHITE, ChessType.KNIGHT), + WHITE_ROOK (2, ChessColor.WHITE, ChessType.ROOK), + WHITE_PAWN (1, ChessColor.WHITE, ChessType.PAWN), + NA (-1, ChessColor.NA, ChessType.NA); + + private int num; + private ChessColor color; + private ChessType type; + + ChessPiece(int num, ChessColor color, ChessType type) { + this.num = num; + this.color = color; + this.type = type; + } + + public ChessType getType() { + return type; + } + + public ChessColor getColor() { + return color; + } + + public int getNum() { + return num; + } + + public String toString() { + return color.toString() + type.toString(); + } + + public static ChessPiece find(int num) { + for (ChessPiece piece : ChessPiece.values()) + if(piece.getNum() == num) return piece; + + return ChessPiece.NA; + } +} diff --git a/src/chess/piece/ChessType.java b/src/chess/piece/ChessType.java @@ -0,0 +1,30 @@ +package chess.piece; + +/** + * Check + */ +public enum ChessType { + KING ("K", 1000), + QUEEN ("Q", 9), + BISHOP ("B", 3), + KNIGHT ("N", 3), + ROOK ("R", 5), + PAWN ("P", 1), + NA (" ", 0); + + private int value; + private String symbol; + + ChessType(String symbol, int value) { + this.symbol = symbol; + this.value = value; + } + + public int getValue() { + return value; + } + + public String toString() { + return symbol; + } +}