How to develop a chess program from scratch (for total beginners) Ep. 3

[Previous episode]

[Previous episode]

Overview

In the previous episode we started thinking about the algorithm of the program we are to create. Now it is time to start building the thinking mechanism of the computer.

And we will start from… Step 1.

Step 1: Scan the chessboard

The first thing one should do when thinking what to play in chess is to scan the chessboard for his/ her pieces and then think about all possible moves.

How can we scan the chessboard? Easy. By using two nested ‘for’ statements, we can tell the program to render all the 8×8 squares of the board and for each one…

IF it finds a piece of the same colour with the computer THEN think of all possible moves

IF it finds a piece of different colour than the colour of the computer THEN skip and go to the next square

The commands that make this happen can be shown below for all different editions of Huo Chess (BASIC, C#, Java).

C# code

                    #region checkAllMoves
                    for (iii = 0; iii <= 7; iii++)
                    {
                        for (jjj = 0; jjj <= 7; jjj++)
                        {
                            //v0.980: Reduce all texts ("White King" for "Wh King", "White Knight" for "Wh Knight" and so on...)
                            //v0.9923 improvement: Remove the (Who_Is_Analyzed.CompareTo("HY") == 0)!!!
                            if (((Who_Is_Analyzed.CompareTo("HY") == 0) && ((((Skakiera_Thinking[(iii), (jjj)].CompareTo("White King") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Queen") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Rook") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Knight") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Bishop") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Pawn") == 0)) && (m_PlayerColor.CompareTo("Black") == 0)) || (((Skakiera_Thinking[(iii), (jjj)].CompareTo("Black King") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Queen") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Rook") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Knight") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Bishop") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Pawn") == 0)) && (m_PlayerColor.CompareTo("White") == 0)))) || ((Who_Is_Analyzed.CompareTo("Hu") == 0) && ((((Skakiera_Thinking[(iii), (jjj)].CompareTo("White King") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Queen") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Rook") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Knight") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Bishop") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Pawn") == 0)) && (m_PlayerColor.CompareTo("White") == 0)) || (((Skakiera_Thinking[(iii), (jjj)].CompareTo("Black King") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Queen") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Rook") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Knight") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Bishop") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("Black Pawn") == 0)) && (m_PlayerColor.CompareTo("Black") == 0)))))
                            {

                                for (int w = 0; w <= 7; w++)
                                {
                                    for (int r = 0; r <= 7; r++)
                                    {
                                        // v0.992 - Initialization (if we don't, the target piece value from the previous run
                                        // will be still in the variables if in the next pass there is no target piece at the
                                        // target square, thus leading to problems - activate the logs to see the difference
                                        // if the initialization does not happen)
                                        ProsorinoKommati = "";
                                        ValueOfMovingPiece = 0;
                                        ValueOfTargetPiece = 0;

                                        //v0.980: Removed. It was not used.
                                        //Danger_penalty = false;
                                        MovingPiece = Skakiera_Thinking[(iii), (jjj)];
                                        m_StartingColumnNumber = iii + 1;
                                        m_FinishingColumnNumber = w + 1;
                                        m_StartingRank = jjj + 1;
                                        m_FinishingRank = r + 1;
                                        // v0.992
                                        ProsorinoKommati = Skakiera_Thinking[(m_FinishingColumnNumber - 1), (m_FinishingRank - 1)];

[Code scanning all possible moves]

                    }

                        }

                            }

                                }

                                    }

BASIC code

    'Scan the chessboard...
    FOR i = 1 TO 8
        FOR j = 1 TO 8

            'If you find a piece of the computer...
            IF ((MID$(chessboard$(i, j), 1, 1) = "w" AND playerColor$ = "b") OR (MID$(chessboard$(i, j), 1, 1) = "b" AND playerColor$ = "w")) THEN

                'Scan all possible destination squares...
                FOR ii = 1 TO 8
                    FOR jj = 1 TO 8

                        startingColumn = i
                        startingRank = j
                        finishingColumn = ii
                        finishingRank = jj

                        MovingPiece$ = chessboard$(i, j)
                        ProsorinoKommati$ = chessboard$(ii, jj)


[Code scanning all possible moves]

                    NEXT jj
                NEXT ii

        NEXT j
    NEXT i

Java code

        //---------------------------------------
        // CHECK ALL POSSIBLE MOVES!
        //---------------------------------------

        for (iii = 0; iii <= 7; iii++)
        {
                for (jjj = 0; jjj <= 7; jjj++)
                {
                        //v0.980: Reduce all texts ("WK" for "Wh King", "WN" for "Wh Knight" and so on...)
                        if (((Who_Is_Analyzed.equals("HY")) && ((((Skakiera_Thinking[(iii)][(jjj)].equals("WK")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WQ")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WR")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WN")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WB")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WP"))) && (m_PlayerColor.equals("b"))) || (((Skakiera_Thinking[(iii)][(jjj)].equals("BK")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BQ")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BR")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BN")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BB")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BP"))) && (m_PlayerColor.equals("w"))))) || ((Who_Is_Analyzed.equals("Human")) && ((((Skakiera_Thinking[(iii)][(jjj)].equals("WK")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WQ")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WR")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WN")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WB")) || (Skakiera_Thinking[(iii)][(jjj)].equals("WP"))) && (m_PlayerColor.equals("w"))) || (((Skakiera_Thinking[(iii)][(jjj)].equals("BK")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BQ")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BR")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BN")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BB")) || (Skakiera_Thinking[(iii)][(jjj)].equals("BP"))) && (m_PlayerColor.equals("b"))))))
                        {

for (int w = 0; w <= 7; w++)
{
      for (int r = 0; r <= 7; r++)
      {
//v0.980: Removed. It was not used.
//Danger_penalty = false;
MovingPiece = Skakiera_Thinking[(iii)][(jjj)];
m_StartingColumnNumber = iii + 1;
m_FinishingColumnNumber = w + 1;
m_StartingRank = jjj + 1;
m_FinishingRank = r + 1;

[Code scanning all possible moves]

        }

                }

                        }

                                }
                                    
                                        }

Reading the code should be fairly simple. Again, since Huo Chess focuses of readability and its purpose is educational, it does not use techniques that could reduce the size of the code.

For each square of the 8×8 chessboard the program checks to see whether the color of the piece (if any) is the same as the color of the computer (or the opposite of the colour of the player) and if yes, then it moves on to ‘think’ for all possible moves.

More analytically…

IF the program analyzes the computer thought…

(Who_Is_Analyzed.CompareTo("HY") == 0)

AND it finds white pieces…

(Skakiera_Thinking[(iii), (jjj)].CompareTo("White King") == 0) || (Skakiera_Thinking[(iii), (jjj)].CompareTo("White Queen") == 0) || ...

AND the color of the computer is White (or, vice versa, the color of the player is Black)…

(m_PlayerColor.CompareTo("Black") == 0)

THEN go and check for all possible moves!

How this thinking of all the possible moves is done, we will see in the next chapter. However, you can get a glimpse of how this is done by the code you already see here…

Along with the initial set of two nested ‘for’ loops (used to scan the chessboard for the pieces of the computer) there is an additional pair of nested ‘for’ loops that are used to ‘create’ the possible end squares for the moves of the computer. Feel free to analyze this on your own.

Until the next chapter…

Keep coding!

Keep experimenting!

Next episode: Thinking of all possible moves for a piece

[Next episode]

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: