Pixelpusher - sourcecode
// Copyright by Hans Bodlaender and Eli Bachmutsk (c) 1998.
// Non-commercial or educational use permitted.
import java.awt.*;
import java.net.*;
public class ChessCanvas extends java.applet.Applet
{
// 0 = empty square
// 1,2 = white & black king 3,4 = white & black queen
// 5,6 = white & black rook 7,8 = white & black knight
// 9,10 = white & black bishop 11,12 = white & black pawn
Image img[] = new Image[13]; // Piece images - null as default
int board [][]; // position (i,j) (a1 = 0,0; b3= 2,3; h8 = 7,7, etc.)
ChessMoveChecker control;
int sqsize = 32; // square size in pixels
int rows = 8, columns = 8 ; // Number of rows and columns on the board
int rowClicked, colClicked; // Clicked row & column,-1 if not clicked
int computercolor = 1; // Computer always played black
int moveNumber;
String setup = "rnbqkbnr/pppppppp/////PPPPPPPP/RNBQKBNR" ; // Board setup
Panel links;
MediaTracker tracker = new MediaTracker(this);
String version = "PIXELPUSHER V0.3";
TextField ta = new TextField(50);
public void init()
{
reset();
resize (sqsize*columns, sqsize*rows+40); // + TextArea on south
links = new Panel();
links.setLayout( new BorderLayout ());
setLayout( new BorderLayout ());
add ("West", links);
LoadImages();
// Area for messages
ta.setFont( new Font ("Helvetica", Font.BOLD, 12));
ta.setEditable(false);
ta.setBackground( Color.white);
add("South", ta);
}
public void reset ()
{ moveNumber = 0;
rowClicked = -1;
board = new int [columns][rows]; // default is 0 - empty
ForsytheToBoard();
control = new ChessMoveChecker(this);
ta.setText(version);
}
public void setText (String text) { ta.setText(moveNumber+". "+text);}
public boolean mouseDown (Event e, int x, int y)
{
if (e.modifiers != 0) // right mouse button - reset
reset();
else
clickProcessing ( x/sqsize, rows - y/sqsize - 1);
repaint();
return true;
}
void clickProcessing (int i, int j) // i - column, j - row
{
if (rowClicked == -1) // First click : from where the player should move ?
{
if ( (board[i][j] > 0) && control.RightPlayer(i,j)) // not empty and ...
{ colClicked = i;
rowClicked = j;
}
}else // Second click : to which squre player should move
{
if (i == colClicked && j == rowClicked)
rowClicked = -1; // if clicked on same square, clicking undone
else if ( control.LegalMove (colClicked,rowClicked,i,j) &&
control.RightPlayer (colClicked,rowClicked) )
{
control.DoMove (colClicked,rowClicked,i,j);
rowClicked = -1;
MakeComputerMove();
}
}
}
public void paint (Graphics g)
{
for (int i = 0; i-1) {board[x][y]=" KkQqRrNnBbPp".indexOf(c);x++;}
}
}
public void MakeComputerMove()
{
moveNumber++;
setText("Black move");
Move computermove = ComputerPlayer.findmove(control,computercolor);
if (!computermove.isvoid()) control.DoMove(computermove);
if(control.Mated(1-computercolor)) setText("BLACK WIN: MATE!!!");
else if(control.InCheck(1-computercolor)) setText("White in check!!!");
else if(control.Stalemated(1-computercolor))setText("STALEMATE !!!");
else if(control.Mated(computercolor)) setText("WHITE WIN: MATE!!!");
else if(control.Stalemated(computercolor)) setText("STALEMATE !!!");
else setText("White move");
}
}
///////////////////////////////////////////////////////////////////////
class Move
{
public int startrow, endrow, startcol, endcol;
Move()
{ startrow = endrow = startcol = endcol = 0; }
Move(int k1, int r1, int k2, int r2)
{ startcol = k1; startrow = r1; endcol = k2; endrow = r2; }
boolean isvoid() // Return true if void move (all zeros)
{ return (startrow+endrow+startcol+endcol)==0 ? true : false; }
}
///////////////////////////////////////////////////////////////////////
class ComputerPlayer
{
static int plydepth=2;
// Overloading: findmove tries to find the best move for given position
// ChessMoveChecker and Move: evaluate how good this particular move is.
public static Move findmove (ChessMoveChecker position, int player)
{
Move themove = new Move();
int bestmove = -50000;
for (int i1=0; i1< position.columns; i1++)
for (int j1=0; j1 < position.rows; j1++)
if (!position.EmptySquare(i1,j1))
if (position.PieceOwner(i1,j1)==player)
for (int i2=0; i2< position.columns; i2++)
for (int j2=0; j2< position.rows; j2++)
if (position.SemiLegalMove(i1,j1,i2,j2))
{
ChessMoveChecker aftermove = new ChessMoveChecker(position);
aftermove.DoMove(i1,j1,i2,j2);
if ( aftermove.InCheck(player) ) continue;
int tryevaluate = Evaluate(aftermove,plydepth -1);
if (tryevaluate > bestmove)
{ themove = new Move(i1,j1,i2,j2);
bestmove = tryevaluate;
}
}
return themove;
}
// This one gives a value for the player that moved to this position.
static int Evaluate (ChessMoveChecker position, int plies)
{
if (plies <=0) return Evaluate(position);
int otherplayer = 1-position.lastplayermoved;
// what is the best move for the other player?
int bestmove = -50000;
for (int i1=0; i1 bestmove)
bestmove = tryevaluate;
}
return 1-bestmove;
}
static int Evaluate (ChessMoveChecker position)
{
int otherplayer = 1- position.lastplayermoved;
if (position.Mated(otherplayer)) return 50000; // Mate : value is high
if (position.Stalemated(otherplayer)) return 0; // Stalemate : draw is zero
//compute the difference in value of the pieces
int totvalue = diffvalueofpieces(position,1-otherplayer);
int ran = 1+ (int) (Math.random() * 10); // Random from 1 to 10
return ran + 10*totvalue;
}
// what is the value of the pieces of player minus the value of its opponent?
static int diffvalueofpieces (ChessMoveChecker position, int player)
{
int totvalue = 0;
for (int k=0; k0; i--)
if (!EmptySquare(i,0) || Attacked(1,i,0)) return false;
return whitelongcastling;
}
boolean LegalBlackLongCastling() // is it legal for black to castle long?
{
if (InCheck(1)) return false;
for (int i= kingcol - 1; i >0; i--)
if ( !EmptySquare(i,rows-1) || Attacked(0,i,rows-1) ) return false;
return blacklongcastling;
}
boolean LegalBlackShortCastling() // is it legal for black to castle short?
{
if (InCheck(1)) return false;
for (int i= kingcol + 1; i < columns -1; i++)
if (!EmptySquare(i,rows-1) || Attacked(0,i,rows-1)) return false;
return blackshortcastling;
}
// Determine if the move is a pawn promotion.
boolean DeterminePawnPromotion (int k1, int r1, int k2, int r2)
{
if (board[k1][r1]==11 && r2 == rows-1) return true;
if (board[k1][r1]==12 && r2 == 0) return true;
return false;
}
public void SetLastPlayerMoved(int i)
{
lastplayermoved = i;
}
// returns the owner of the piece on square (k,r)
public int PieceOwner(int k, int r)
{
return 1- (board[k][r] %2) ; // 0 if white owns the piece,1-if black
}
// checks if the right player wants to make a move
public boolean RightPlayer(int k1, int r1)
{
return (PieceOwner(k1,r1) != lastplayermoved);
}
// Checks if player is in check
boolean InCheck (int player)
{ // first find the king piece of the player.
int kingpiece = 1 + player;
for (int k=0; k< columns; k++)
for (int r=0; r < rows; r++)
if (board[k][r]==kingpiece)
// crude: check if any piece could move to the kings position
for (int k2=0; k22) || (Math.abs(k1-k2)<2)) ? false : true;
boolean whiteenpassant = LegalWhitePawnEnPassantCapture (k1, r1, k2, r2);
boolean blackenpassant = LegalBlackPawnEnPassantCapture (k1, r1, k2, r2);
// update status
lastmove = new Move (k1,r1, k2, r2);
SetLastPlayerMoved(PieceOwner(k1,r1));
ChangeCastlingStatus(k1,r1,k2,r2);
// do the move
board[k2][r2] = board[k1][r1];
board[k1][r1]=0;
// additional work if promotion, castling, enpassant
if (promotion) board[k2][r2] = DeterminePromotionPiece(k2,r2);
if (castled) HandleCastling(k1,r1,k2,r2);
if (whiteenpassant) board[k2][r2-1]=0; // remove captured pawn
if (blackenpassant) board[k2][r2+1]=0; // remove captured pawn
}
void HandleCastling(int k1,int r1,int k2,int r2)
{
if (k1 > k2) // castling to left of board
{ board[k2+1][r2] = board[0][r2];
board[0][r2] = 0;
} else // castling to right of board
{ board[k2-1][r2] = board[columns -1][r2];
board[columns-1][r2]=0;
}
}
// Determinate pawn promoted piece (always queen at this stage)
int DeterminePromotionPiece (int k, int r)
{
return 3+PieceOwner(k,r); // Promoted to queen
}
boolean Mated(int player)
{
if (lastplayermoved != player)
if (InCheck(player))
return (!HasALegalMove(player));
return false;
}
boolean Stalemated(int player)
{
if (lastplayermoved != player)
if (!InCheck(player))
return (!HasALegalMove(player));
return false;
}
boolean HasALegalMove(int player)
{
for (int k=0; k
WWW page by Hans Bodlaender. Programming by Hans Bodlaender and Eli
Bachmupsky.
WWW page created: April 3, 1998.