import java.applet.Applet; import java.awt.*; import java.awt.Color; import java.awt.Graphics; import java.awt.event.*; import java.lang.Math; public class _chess10 extends Applet implements MouseListener { //////////////////////////////////////////////////////// // // Image wPawn; Image bPawn; Image wKnight; Image bKnight; Image wBishop; Image bBishop; Image wRook; Image bRook; Image wQueen; Image bQueen; Image wKing; Image bKing; int fromBoard; int toBoard; //////////////////////////////////////////////////////// // // int[] board; int[][] from; int[][] to; int[][] spec; int[][] capt; int[] pawnDrc; int[] bishopDrc; int[] rookDrc; int[] knightDrc; int[] queenDrc; int[] kingDrc; //////////////////////////////////////////////////////// // // int maxExtend; int maxDepth; int captNo; int[] captures; int move; int colorToMove; //////////////////////////////////////////////////////// // // final int WHITE = 1; final int BLACK = -1; final int MAXPLY = 16; final int MAXPSN = 128; final int EMPTY = 0; final int BORDER = 1; final int PAWN = 112; final int KNIGHT = 296; final int BISHOP = 300; final int ROOK = 512; final int QUEEN = 896; final int KING = 9999; final int ENDDIR = 0; //////////////////////////////////////////////////////// // // public void init() { setBackground(Color.gray); board = new int[120]; from = new int[MAXPLY][MAXPSN]; to = new int[MAXPLY][MAXPSN]; spec = new int[MAXPLY][MAXPSN]; capt = new int[MAXPLY][MAXPSN]; pawnDrc = new int[] {-11, -9,-10,-20, ENDDIR}; bishopDrc = new int[] {-11, 11, -9, 9, ENDDIR}; rookDrc = new int[] {-10, 10, -1, 1, ENDDIR}; knightDrc = new int[] {-21, 21, -8, 8, -12, 12, -19, 19, ENDDIR}; queenDrc = new int[] {-10, 10, -1, 1, -11, 11, -9, 9, ENDDIR}; kingDrc = new int[] {-10, 10, -1, 1, -11, 11, -9, 9, ENDDIR}; captures = new int[256]; maxExtend = 4; maxDepth = 2; colorToMove = WHITE; initBoard (); wPawn = getImage(getCodeBase(), "WPawn.gif"); bPawn = getImage(getCodeBase(), "BPawn.gif"); wKnight = getImage(getCodeBase(), "WKnight.gif"); bKnight = getImage(getCodeBase(), "BKnight.gif"); wBishop = getImage(getCodeBase(), "WBishop.gif"); bBishop = getImage(getCodeBase(), "BBishop.gif"); wRook = getImage(getCodeBase(), "WRook.gif"); bRook = getImage(getCodeBase(), "BRook.gif"); wQueen = getImage(getCodeBase(), "WQueen.gif"); bQueen = getImage(getCodeBase(), "BQueen.gif"); wKing = getImage(getCodeBase(), "WKing.gif"); bKing = getImage(getCodeBase(), "BKing.gif"); addMouseListener (this); } //////////////////////////////////////////////////////// // // public void start () {} public void stop () {} public void destroy() {} public void mouseExited (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseClicked (MouseEvent e) {} //////////////////////////////////////////////////////// // // public void initBoard () { for (int square= 0; square<120; square++) board[square] = BORDER; for (int square=31; square< 39; square++) board[square] = -PAWN; for (int square=41; square< 49; square++) board[square] = EMPTY; for (int square=51; square< 59; square++) board[square] = EMPTY; for (int square=61; square< 69; square++) board[square] = EMPTY; for (int square=71; square< 79; square++) board[square] = EMPTY; for (int square=81; square< 89; square++) board[square] = PAWN; board[21] = -ROOK; board[91] = ROOK; board[22] = -KNIGHT; board[92] = KNIGHT; board[23] = -BISHOP; board[93] = BISHOP; board[24] = -QUEEN; board[94] = QUEEN; board[25] = -KING; board[96] = BISHOP; board[26] = -BISHOP; board[95] = KING; board[27] = -KNIGHT; board[97] = KNIGHT; board[28] = -ROOK; board[98] = ROOK; colorToMove = 1; captNo = 0; captures[0] = 0; } //////////////////////////////////////////////////////// // // public int getFigure (int psn) { if ((psn < 0) || (psn > 119)) return BORDER; else return board[psn]; } //////////////////////////////////////////////////////// // // int evaluatePosition (int color) { int psn; int no; int pColor = 0; int value = 0; for (psn = 0; psn < 120; psn++) { if (board[psn] >= PAWN) pColor = 1; if (board[psn] <= -PAWN) pColor = -1; switch (board[psn]) { case PAWN : case -PAWN : value += board[psn]; if ((psn == 54) || (psn == 55) || (psn == 64) || (psn == 65)) value += pColor *16; if (((psn >= 73) && (psn <= 76)) || ((psn >= 43) && (psn <= 46))) value += pColor *10; value += pColor *(8- Math.abs (9- ((psn %10) *2))); if (((psn %10 == 4) || (psn %10 == 5)) && (board[psn -pColor *10]) == EMPTY) value += pColor *10; if ((getFigure(psn - 1 ) == pColor *PAWN) || (getFigure(psn + 1 ) == pColor *PAWN) || (getFigure(psn - 9 *pColor) == pColor *PAWN) || (getFigure(psn -11 *pColor) == pColor *PAWN)) value += pColor* +3; if ((getFigure(psn -10 *pColor) == pColor *PAWN) || (getFigure(psn -20 *pColor) == pColor *PAWN) || (getFigure(psn -30 *pColor) == pColor *PAWN)) value += pColor* -20; break; case KNIGHT : case -KNIGHT : value += board[psn]; no = 0; if (-pColor *board[psn -12] >= ROOK) no++; if (-pColor *board[psn - 8] >= ROOK) no++; if (-pColor *board[psn +12] >= ROOK) no++; if (-pColor *board[psn + 8] >= ROOK) no++; if (-pColor *board[psn -21] >= ROOK) no++; if (-pColor *board[psn -19] >= ROOK) no++; if (-pColor *board[psn +21] >= ROOK) no++; if (-pColor *board[psn +19] >= ROOK) no++; if (no >= 2) value += pColor *72; value += pColor *((8- Math.abs (9- ((psn %10 ) *2))) << 1); value += pColor *((8- Math.abs (9- ((psn /10 -1) *2))) << 1); break; case BISHOP : case -BISHOP : value += board[psn]; value += pColor *((8- Math.abs (9- ((psn %10 ) *2))) ); value += pColor *((8- Math.abs (9- ((psn /10 -1) *2))) << 1); break; case ROOK : case -ROOK : value += board[psn]; if ((pColor == WHITE) && (psn <= 40)) value += 32; if ((pColor == BLACK) && (psn >= 80)) value += -32; value += pColor *((8- Math.abs (9- ((psn %10) *2)))); if ((getFigure(psn -10 * pColor) != pColor *PAWN) && (getFigure(psn -20 * pColor) != pColor *PAWN) && (getFigure(psn -30 * pColor) != pColor *PAWN) && (getFigure(psn -40 * pColor) != pColor *PAWN)) value += pColor *16; if ((getFigure(psn -10 * pColor) == pColor *ROOK) || (getFigure(psn -20 * pColor) == pColor *ROOK) || (getFigure(psn -30 * pColor) == pColor *ROOK) || (getFigure(psn -40 * pColor) == pColor *ROOK)) value += pColor *16; break; case QUEEN : case -QUEEN : value += board[psn]; if ((pColor == WHITE) && (psn < 80) && ((board[92] == KNIGHT) || (board[97] == KNIGHT))) value -= 32; if ((pColor == BLACK) && (psn > 40) && ((board[22] == -KNIGHT) || (board[27] == -KNIGHT))) value -= -32; break; case KING : case -KING : value += board[psn]; if ((getFigure(psn - 9 * pColor) * pColor >= PAWN) || (getFigure(psn -18 * pColor) * pColor >= PAWN)) value += pColor *16; if ((getFigure(psn -11 * pColor) * pColor >= PAWN) || (getFigure(psn -22 * pColor) * pColor >= PAWN)) value += pColor *16; if ((getFigure(psn -10 * pColor) * pColor >= PAWN) || (getFigure(psn -20 * pColor) * pColor >= PAWN) || (getFigure(psn -30 * pColor) * pColor >= PAWN)) value += pColor *16; break; } } return value; } //////////////////////////////////////////////////////// // // public void setMove (int ply, int no, int _from, int _to) { from[ply][no] = _from; to [ply][no] = _to; spec[ply][no] = EMPTY; if ((board[_from] == PAWN) && (_to < 30)) spec[ply][no] = QUEEN; if ((board[_from] == -PAWN) && (_to > 90)) spec[ply][no] = -QUEEN; } //////////////////////////////////////////////////////// // // public int generateMoves (int color, int ply) { int psn; int no; int drc; int moves; for (psn = 0, moves = 0; psn < 120; psn++) { switch (board[psn] *color) { case PAWN : if (board[psn +color *pawnDrc[0]] *-color >= PAWN) setMove (ply, moves++, psn, color *pawnDrc[0] +psn); if (board[psn +color *pawnDrc[1]] *-color >= PAWN) setMove (ply, moves++, psn, color *pawnDrc[1] +psn); if (board[psn +color *pawnDrc[2]] == EMPTY) setMove (ply, moves++, psn, color *pawnDrc[2] +psn); if ((board[psn +color *pawnDrc[2]] == EMPTY) && (board[psn +color *pawnDrc[3]] == EMPTY) && (((color == 1) && (psn > 80)) || ((color == -1) && (psn < 40)) )) setMove (ply, moves++, psn, color *pawnDrc[3] +psn); break; case KNIGHT : for (no = 0; no < 8; no++) if ((board[psn +knightDrc[no]] == EMPTY) || (board[psn +knightDrc[no]] *-color >= PAWN)) setMove (ply, moves++, psn, knightDrc[no] +psn); break; case BISHOP : for (no = 0, drc = bishopDrc[ no]; no < 4; drc = bishopDrc[++no]) do if ((board[psn +drc] == EMPTY) || (board[psn +drc] *-color >= PAWN)) setMove (ply, moves++, psn, drc +psn); while (board[psn +(drc += bishopDrc[no])- bishopDrc[no]] == EMPTY); break; case ROOK : for (no = 0, drc = rookDrc[ no]; no < 4; drc = rookDrc[++no]) do if ((board[psn +drc] == EMPTY) || (board[psn +drc] *-color >= PAWN)) setMove (ply, moves++, psn, drc +psn); while (board[psn +(drc += rookDrc[no])- rookDrc[no]] == EMPTY); break; case QUEEN : for (no = 0, drc = queenDrc[ no]; no < 8; drc = queenDrc[++no]) do if ((board[psn +drc] == EMPTY) || (board[psn +drc] *-color >= PAWN)) setMove (ply, moves++, psn, drc +psn); while (board[psn +(drc += queenDrc[no])- queenDrc[no]] == EMPTY); break; case KING : for (no = 0; no < 8; no++) if ((board[psn +kingDrc[no]] == EMPTY) || (board[psn +kingDrc[no]] *-color >= PAWN)) setMove (ply, moves++, psn, kingDrc[no] +psn); break; } } return(moves); } //////////////////////////////////////////////////////// // // public void moveForward (int ply, int psn) { capt[ply][psn] = board[ to[ply][psn]]; board[ to[ply][psn]] = board[from[ply][psn]]; board[from[ply][psn]] = EMPTY; if (spec[ply][psn] != 0) board[to[ply][psn]] = spec[ply][psn]; captNo ++; if (capt[ply][psn] == 0) captures[captNo] = 0; else captures[captNo] = captures[captNo -1] +1; } //////////////////////////////////////////////////////// // // void moveBack (int ply, int psn) { board[from[ply][psn]] = board[to[ply][psn]]; board[ to[ply][psn]] = capt[ply][psn]; if (spec[ply][psn] != 0) { if (spec[ply][psn] == QUEEN) board[from[ply][psn]] = PAWN; if (spec[ply][psn] == -QUEEN) board[from[ply][psn]] = -PAWN; } captNo--; } //////////////////////////////////////////////////////// // // public int Extend (int color, int alpha, int beta, int depth) { int no; int noMoves; int value = evaluatePosition (color); if (color *value > color *alpha) alpha = value; if (depth > (maxDepth +maxExtend -1)) if ((depth > maxDepth +maxExtend) || ((captures[captNo]) % 2) == 0) return value; noMoves = generateMoves(color, depth); for (no=0; no < noMoves; no++) { if (board[to[depth][no]] != EMPTY) { if (board [to[depth][no]] == KING) return -32000; if (board [to[depth][no]] == -KING) return 32000; moveForward (depth, no); value = Extend (-color, beta, alpha, depth +1); if (color == WHITE) if (value > alpha) alpha = value; if (color == BLACK) if (value < alpha) alpha = value; moveBack (depth, no); if (color == WHITE) if (alpha > beta) return alpha; if (color == BLACK) if (alpha < beta) return alpha; } } return alpha; } //////////////////////////////////////////////////////// // // public int alphaBeta (int color, int alpha, int beta, int depth) { if (depth > maxDepth) return Extend (color, alpha, beta, depth); else { int no; int noMoves; int value; noMoves = generateMoves(color, depth); for (no=0; no < noMoves; no++) { if (depth == 1) showThinking (noMoves, no, alpha); if (board [to[depth][no]] == KING) return -32000; if (board [to[depth][no]] == -KING) return 32000; moveForward (depth, no); value = alphaBeta (-color, beta, alpha, depth +1); if (color == WHITE) if (value > alpha) { alpha = value; if (depth == 1) move = no; } if (color == BLACK) if (value < alpha) { alpha = value; if (depth == 1) move = no; } moveBack (depth, no); if (color == WHITE) if (alpha > beta) return alpha; if (color == BLACK) if (alpha < beta) return alpha; } return alpha; } } //////////////////////////////////////////////////////// // // public void showMove(int value) { char fromLine = (char) (96 +(from[1][move] % 10)); char fromRow = (char) (58 -(from[1][move] / 10)); char toLine = (char) (96 +( to[1][move] % 10)); char toRow = (char) (58 -( to[1][move] / 10)); showStatus ("My move: " +fromLine +fromRow + toLine + toRow +" Value: " +value); } //////////////////////////////////////////////////////// // // public void showThinking(int noMoves, int no, int alpha) { showStatus ("Thinking (" +noMoves +"/" +no +") Value: " +alpha); } //////////////////////////////////////////////////////// // // public void chessMove() { int _from; int _to; int value; value = alphaBeta (colorToMove, colorToMove *-32000, colorToMove * 32000, 1); _from = from[1][move]; _to = to[1][move]; _from = (_from %10 -1) +(_from /10 -2) *8; _to = (_to %10 -1) +(_to /10 -2) *8; moveFigure (_from, _to); showMove (value); } //////////////////////////////////////////////////////// // // public void drawSquare (Graphics graphic, int square) { int row = square /8; int line = square &7; if ((line +row & 1) == 1) graphic.setColor (Color.white); else graphic.setColor (Color.lightGray); graphic.fillRect (line *36 +6, row *36 +6, 36, 36); } //////////////////////////////////////////////////////// // // public void drawFigure (Graphics graphic, int figure, int square) { int row = square /8; int line = square &7; switch (figure) { case PAWN : graphic.drawImage ( wPawn,line *36 +6, row *36 +6,this); break; case -PAWN : graphic.drawImage ( bPawn,line *36 +6, row *36 +6,this); break; case KNIGHT : graphic.drawImage (wKnight,line *36 +6, row *36 +6,this); break; case -KNIGHT : graphic.drawImage (bKnight,line *36 +6, row *36 +6,this); break; case BISHOP : graphic.drawImage (wBishop,line *36 +6, row *36 +6,this); break; case -BISHOP : graphic.drawImage (bBishop,line *36 +6, row *36 +6,this); break; case ROOK : graphic.drawImage ( wRook,line *36 +6, row *36 +6,this); break; case -ROOK : graphic.drawImage ( bRook,line *36 +6, row *36 +6,this); break; case QUEEN : graphic.drawImage ( wQueen,line *36 +6, row *36 +6,this); break; case -QUEEN : graphic.drawImage ( bQueen,line *36 +6, row *36 +6,this); break; case KING : graphic.drawImage ( wKing,line *36 +6, row *36 +6,this); break; case -KING : graphic.drawImage ( bKing,line *36 +6, row *36 +6,this); break; } } //////////////////////////////////////////////////////// // // public void movePiece (int from, int to) { board[to ] = board[from]; board[from] = EMPTY; } //////////////////////////////////////////////////////// // // public void moveFigure (int from, int to) { int fromSquare = 20 +((from &7) +1) +(from /8) *10; int toSquare = 20 +((to &7) +1) +(to /8) *10; if ((board[fromSquare] == PAWN) && (toSquare < 30)) board[fromSquare] = QUEEN; if ((board[fromSquare] == -PAWN) && (toSquare > 90)) board[fromSquare] = -QUEEN; movePiece (fromSquare, toSquare); if ((board[toSquare] == KING) && (toSquare -fromSquare == 2)) moveFigure (63, 61); if ((board[toSquare] == KING) && (toSquare -fromSquare == -2)) moveFigure (56, 59); if ((board[toSquare] == -KING) && (toSquare -fromSquare == 2)) moveFigure ( 7, 5); if ((board[toSquare] == -KING) && (toSquare -fromSquare == -2)) moveFigure ( 0, 3); drawSquare (this.getGraphics(), from); drawSquare (this.getGraphics(), to); drawFigure (this.getGraphics(), board[fromSquare], from); drawFigure (this.getGraphics(), board[ toSquare], to); } //////////////////////////////////////////////////////// // // public void drawBoard (Graphics graphic, int[] board) { for (int psn=0, square=0; psn<120; psn++) if (board[psn] != BORDER) { drawSquare (graphic, square); drawFigure (graphic, board[psn], square++); } } //////////////////////////////////////////////////////// // // public void mousePressed (MouseEvent e) { fromBoard = ((e.getX() -6) /36) +((e.getY() -6) /36) *8; } public void mouseReleased (MouseEvent e) { toBoard = ((e.getX() -6) /36) +((e.getY() -6) /36) *8; if (fromBoard != toBoard) { moveFigure (fromBoard, toBoard); colorToMove = -colorToMove; chessMove(); colorToMove = -colorToMove; } } //////////////////////////////////////////////////////// // // public void paint(Graphics g) { drawBoard (g, board); } }