© Corel The implementation of the chess rules

Until now we only wrote an interface a human can use to communicat with the programm. Now we start to write the artificial intelligense. As first step we teach our programm the chess rules.

We have to make a list with valid moves at two places: On one side to control the input of the human, on the other side to calculate the best move for the AI. We don't wan't to write everything twice, so implement the control of the moves of the human in such a way that we define an array in which we save all valid moves. The isvalid ()method goes through the array and returns true if the move is in the list.

To start we declare the variables we need:

//varibales for the AI
int [] movelist = new int [250];
int movecounter = 0;
int color = 1; //the color of the player that moves

We change the method isvalid ():

//this method checks if a move is valid
public boolean isvalid (int move) {
   for (int i = 0; i < movecounter; i++) {
      if (movelist [i] == move)
         return true;
   }
   return false;
}

We also need the methods simulize (), multisimulize () and genmove (). We start with the method simulize ():

//here we simulize a move
public void simulize (int start, int end) {
   if ((board [end] == 99) ||
         (board [end] % 100 / 10 == color))
      return;

   movelist [movecounter] = start * 100 + end;
   movecounter++;
}

The method checks first if the move crosses the border. If it does not, the move will be add to the movelist. Let's go to the multisimulize () methode. It simulizes the moves of the queen, bishop and rook.

//simulize the moves for queen, rook and bishop
public void multisimulize (int start, int inc) {
   int to = start;

   while ((board [to + inc ] != 99) && (board [to + inc] % 100 / 10 != color)) {
      to += inc;

      if (board [to] != 0) {
         simulize (start, to);
         return;
       }

       simulize (start, to);
   }
   simulize (start, to);
}

This method gets the start field and the distance as parameter. Distance means the direction the piece moves to. Then the method simulizes moves until a barrier is in the way.

The most complicate method is genmove (). Here the single moves are generated. You remember on the lines of the theory part in which we explained that every move can be expressed with a addition or subtracion? Now we implement that principe. Of course the numbers changes if you switch from a 8x8 board to a 12x10 board.

//This method generates all valid moves
public void genmove () {
   for (int i = 21; i < 99; i++) {
      //right color?
      if (board [i] % 100 / 10 == color) {
         switch (board [i] % 10) {
            case 1: //pawn
               if (color == 1) //white pawn
               {
                  if (board [i-10] == 0)
                     simulize ( i, i-10);
                  if (board [i- 9] % 100 / 10 == 2)
                     simulize ( i, i-9 );
                  if (board [i-11] % 100 / 10 == 2)
                     simulize ( i, i-11);
                  if ( (i>80) && ( ( board [i-10] == 0) && (board [i-20] == 0)))
                     simulize ( i, i-20);
               } else { //black pawn
                  if (board [i+10] == 0)
                     simulize ( i, i+10);
                  if (board [i+9] % 100 / 10 == 1)
                     simulize (i, i+9);
                  if (board [i+11] % 100 / 10 == 1)
                     simulize (i, i+11);
                  if ( (i<39) && ( (board [i+10] == 0) && (board [i+20] == 0)))
                     simulize (i, i+20);
               }
               break;
            case 2: //knight
               simulize (i, i+12);
               simulize (i, i-12);
               simulize (i, i+21);
               simulize (i, i-21);
               simulize (i, i+19);
               simulize (i, i-19);
               simulize (i, i+8 );
               simulize (i, i-8 );
               break;
            case 5: //queen
            case 3: //bishop
               multisimulize ( i, -9);
               multisimulize ( i, -11);
               multisimulize ( i, +9);
               multisimulize ( i, +11);
               if (board [i] % 10 == 3)
                  break;
            case 4: //rook
               multisimulize (i, -10);
               multisimulize (i, +10);
               multisimulize (i, -1);
               multisimulize (i, +1);
               break;
            case 6: //king
               simulize (i, i+1);
               simulize (i, i-1);
               simulize (i, i+10);
               simulize (i, i-10);
               simulize (i, i+9);
               simulize (i, i-9);
               simulize (i, i+11);
               simulize (i, i-11);
         }
      }
      if ( i%10 == 8)
         i += 2;
   }
}

We don't implement castling and en passant capturing. We will implement the castling in the part "final works", but we leave the en passant capturing because it isn't used really often. of course we have to call genmove () from anywhere. We call it in two methods: newgame () and execute (). So we add the following code at the end of the method newgame ():

movecounter = 0;
color = 1;
genmove ();

In the method execute () we have to change the move color so that white and black moves one after the other. The code looks out like this:

//other player
if (color == 1)
   color = 2;
else
   color = 1;

//set movelist back
movecounter = 0;

//calculate valid moves
genmove ();

Now it should be clear why we use a 10x12 chess board, i.e. why we added a border. So it is much more easy to check if a move leads out of the regular board.

show applet step 5
source code of step 5


to the overview | back | continue