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);
}
}