Click here to Skip to main content
Click here to Skip to main content

C# / C++ CLI Micro Chess (Huo Chess)

, 23 Sep 2012
Rate this:
Please Sign up or sign in to vote.
An article about Huo Chess, a chess program in C++ and C# that attempts to be smaller in size than the Commodore-era Microchess

 

Huo Chess (GUI edition) 

Summary

Huo Chess is a chess program of just 57 KB in size (this size refers to the 0.95 C# console application version without GUI). Two versions currently exist: One without GUI (C# console application) and one with GUI (C# windows application). Previous versions included C++, Visual Basic and XNA-based editions (they were maintained up to 0.82 version - I intend to update them as soon as I have time).  In its current version (Huo Chess v0.95 – C#) can think up to 20 half-moves [Kakos-Minimax edition] (e.g. 10 half-moves for white and 10 half-moves for black pieces when computer plays with White) and has an opening book capability (the other editions will be shortly updated). An Opening Book Editor (written in C++) is also distributed. Huo Chess plays decent chess and has managed to draw Microchess, the first microchess from the Commodore era (see the Huo Chess Games Archive below). Its algorithm is based on brute-force analysis while utilizing the MiniMax algorithm. It can be used to study the underlying logic of a chess program or as a basis for your own chess program. The source code is heavily commented in English and easily customizable, since all variables have distinct and understandable names. The source code is continually improving and is distributed under The Code Project Open License. In this article, I also analyze its programming logic, with emphasis on the general flow inside the computer’s "mind," from the initial scanning of the chessboard up to the final decision on which move to play. Any comments are welcome! 

 

Introduction 

What is most important when you program? Is it the program design? Yes? If "yes," then why is it that every program today is bigger than 123876 GB and requires 120987 MB of RAM to run? Why is every new project and program — by default — larger in size and slower in speed than the previous version? The answer is simple: because of the increasing speed of computers, no one actually cares about optimizing the code structure and the software design, since the new processor will definitely make the program look fine for the end user. During the time of Commodore computers, memory was rather limited. That is why programmers tried to make the code small and efficient. This resulted in Microchess, which was a very efficient, small (as the name "micro," which means "small" in Greek, implies) chess program that was able to play chess in the few KB available in computers of that time.

What I Accomplished

Driven by the above, I started developing a program in CLI C++ v8.0 (with Visual Studio 2008 Express Edition, while now the latest edition is developed in Visual Studio 2012) to play chess with the intention of making a small in size (Micro)chess, even smaller than the Commodore-era Microchess. Now, one version in C# programming language and one version with Graphical User Interface also exist (you can find them here for downloading). I named it "Huo Chess" for personal reasons. The program plays decent chess, but unfortunately will probably lose if it plays with Garry Kasparov. Its size is currently 57 KB (in the C# edition v0.95), while the respective emulation of Microchess in C is 56 KB. However, it must be noted that the original Microchess, written in pure Assembly, was about 1 KB…something that I believe no one will ever match! In matches against Microchess, version 0.4 has managed to draw Microchess (see below the section of Huo Chess Games Archive).

How to Customize - Optimize the Program

The program has an opening book capability, which means that anyone can optimize the program by adding his/her own opening moves data in the respective folder Huo Chess Opening Book (which should be in the same directory with the executable) with Huo Opening Book Editor. You can also add more thinking depth capability, by adding new ComputerMove functions (like ComputerMove2, ComputerMove3, etc. for each new thinking depth layer) and make the necessary adjustments to the filters applied to the moves analyzed (these are needed to increase the speed of the program – see FindAttackers / FindDefenders). You can also optimize the way Huo Chess thinks by changing the CountScore function and the way the computer (or its human opponent) values the pieces or the chessboard position. For example, if you change the score of the Queen in the CountScore function from 9 to 12, then the HY will play aggressively to attack the opponent's queen and at the same time try harder to defend its own queen. You can also — for example — give a high scoring to the existence of an opening column with a rook controlling it, so as to make the computer play more with its rooks and try to take over columns with them. Any FEEDBACK is WELCOME with better configurations of the Opening Book or the CountScore functions which are actually the heart of the system!

I. Chess Algorithm Analysis

The algorithm used in this program for the implementation of the computer thinking is the MiniMax algorithm for the latest version (C# 0.93) and the "Brute Force Algorithm" for the older C++ / VB / C# version. Huo Chess plays with the material in mind, while its code has some hints of positional strategic playing embedded (e.g. it is good to have your Knights closer to the center of the chessboard in the beginning). More analytically: When the program starts thinking, it scans the chessboard to find where its pieces are (see ComputerMove function) and then tries all possible moves it can make. It analyzes these moves up to the thinking depth I have defined (via the ComputerMove => ComputerMove2 => ComputerMove3 => ComputerMove4 => ComputerMove5 path), measures the score (see CountScore function) of the final position reached from all possible move variants and – finally – chooses the move that leads to the most promising (from a score point of view) position (ComputerMove function).

C# v0.93 Kakos-Minimax algorithm summary

A high-level example of the progress of the main algorithm for versions 0.84 and older is as follows:

  1. ComputerMove: Scans the chessboard and makes all possible moves
  2. CheckMove: Checks the legality and correctness of these possible moves
  3. (if thinking depth not reached) => call HumanMove
  4. HumanMove: Checks and finds the best answer of the human opponent
  5. ComputerMove2: Scans the chessboard and makes all possible moves at the next thinking level
  6. CheckMove: Checks the legality and correctness of these possible moves
  7. (if thinking depth not reached) => call HumanMove
  8. HumanMove: Checks and finds all possible answers of the human opponent (Note: Previous (v0.84 and older) versions found only the best answer of the human opponent (by finding with which move the human earns more)
  9. ComputerMove4 /ComputerMove6 / ... ComputerMove20: Scans the chessboard and makes all possible moves at the next thinking level
  10. CheckMove: Checks the legality and correctness of these possible moves
  11. (if thinking depth reached) => record the score of the final position in the Nodes of the MiniMax algorithm
  12. The algorithm continues until all possible moves are scanned
  13. The MiniMax algorithm is finally used to calculate the best move via the analysis of the thinking tree Nodes

C# 0.95 Minimax algorithm summary

cpp_microchess/huoChess_2.jpg

A high-level description of the progress of the main algorithm (for version 0.93 Simple Minimax) is as follows:

  1. ComputerMove: Scans the chessboard and makes all possible moves
  2. MoveFilter: A function to filter the moves scanned in order to increase speed.
  3. ComputerMove: The program checks the legality and correctness of these possible moves.
  4. (if thinking depth not reached) => call ComputerMove2 (next depth level)
  5. Note: In the older 0.82 versions, the AI calls HumanMove. The difference is that in the older versions the AI selects the human move which results in the largest material gain and proceeds only with that move in the ComputerMove2 (version 0.94 checks for ALL possible human moves)
  6. ComputerMove2: Scans the chessboard and makes all possible moves at the next thinking level.
  7. ComputerMove3: Scans the chessboard and makes all possible moves at the next thinking level.
  8. ComputerMove4: Scans the chessboard and makes all possible moves at the next thinking level.
  9. ComputerMove5: Scans the chessboard and makes all possible moves at the next thinking level.
  10. (if thinking depth reached) => record the score of the final position in the NodesAnalysis array.
  11. ---------------------------------------------------------------------------
  12. The score before every human opponents move and after any human opponents move are stored in the
  13. Temp_Score_Human_before_2 (i.e. the score after the first move of the H/Y and before the 1st move of human
  14. While at the 2nd -ply of computer thinking), Temp_Score_Human_after_2, etc. variables.
  15. ---------------------------------------------------------------------------
  16. At every level of thinking, the scores are stored in the NodesAnalysis table. This table is used for the implementation of the MiniMax algorithm.

You can SET huo_debug to TRUE to see live the progress of the computer thought while the computer thinks. Just press a key to move step-by-step into the Huo Chess inner mechanism… You can also uncomment the code lines that record the time the program requires to think its move, so as to have an idea of the time required by the processor to complete the thinking process.

Huo Chess 0.94 with huo_DEBUG set to true: you can see how computer thinks and optimize it

II. Huo Chess Thought Flow (Minimax algorithm)

Below, I analyze the thought flow of the chess program. I will describe only the main steps and code segments, so as to show the way the computer scans the chessboard, conducts all possible moves and finally finds the better one. The function names appear in bold, i.e. ComputerMove - Start indicates the beginning of the ComputerMove() function. Be aware that some code segments may be slightly different from the code in the distributed ZIP file since I continuously change the program. As it appears, the "constant beta" state is the trend nowadays.

ComputerMove – Start

When the computer thinking starts, the first thing to do is to initialize all the variables and store the initial chessboard position in an array.

    // store the initial position in the chessboard
    for (int iii1 = 0; iii1 <= 7; iii1++)
    {
        for (int jjj1 = 0; jjj1 <= 7; jjj1++)
        {
            Skakiera_Thinking_init[(iii1), (jjj1)] = Skakiera_Thinking[iii1, jjj1];
        }
    } Call: CheckMove

ComputerMove – Dangerous Squares filter

The program then scans the chessboard and analyzes it in order to find the Dangerous Squares. These squares are the squares where the computer cannot move its pieces to, since they are protected by pieces of the other side. These Dangerous Squares analysis is conducted for every level of thinking and serves as a “filter”, so as to reduce the number of moves analyzed (this helps to the program speed) and make sure both sides do not “make” stupid moves.

DangerousSquares(Skakiera_Thinking, "ComputerMove0", m_PlayerColor);

ComputerMove – Main Thinking

  • Scan the chessboard to first map the "dangerous" squares in it (see  FindAttackers and  FindDefenders functions). These will be later be used to see if the computer attempts to move into a dangerous square or to check if a piece of the computer is under danger. 
  • Scan the chessboard to find any possible move (MoveFilter makes a pre-scanning of valid moves so as to increase the thinking speed).
  • Make the move temporarily

(Versions 0.82 and earlier called CheckHumanMove to find the move of the human which wins more material – However newer versions analyze all possible moves of the human with MiniMax algorithm)

  • Call ComputerMove2 [Chessboard with the move analyzed applied, is passed over as an argument]
ComputerMove_2(Skakiera_Thinking);

CheckHumanMove2 / CheckHumanMove 3 / CheckHumanMove 4...

Deeper thinking is implemented by respective thinking functions.

Each one has as input the chessboard array from the previous one.

CountScore

Every move score is measured (if the move is legal and correct). These scores are stored in the NodesAnalysis array (see below). The scoring function is the heart of the program. It currently takes into account mainly material values, with some positional considerations for the opening phase of the game (i.e. if Move < 11 it is not good to move your Queen or else a small “scoring penalty” is imposed). The optimization of that function is key to the increasing of the computer play strength.

Thinking Depth - End

When we have reached the thinking depth (i.e. when we have reached the ComputerMove function which we have defined as the last one in the chain of analysis), we store the chessboard scores of the thinking tree nodes for every thinking depth level (applies for version 0.93 and newer).

These nodes are then going to be used in the MiniMax algorithm to find the best move.

// Record the node in the Nodes Analysis array (to use with MiniMax algorithm) skakos
NodesAnalysis[NodeLevel_1_count, 1, 0] = Temp_Score_Human_before_2;
NodesAnalysis[NodeLevel_2_count, 2, 0] = Temp_Score_Human_after_2;
NodesAnalysis[NodeLevel_3_count, 3, 0] = Temp_Score_Human_before_4;
NodesAnalysis[NodeLevel_4_count, 4, 0] = Temp_Score_Human_after_4;
NodesAnalysis[NodeLevel_5_count, 5, 0] = Temp_Score_Human_before_6;
NodesAnalysis[NodeLevel_6_count, 6, 0] = Temp_Score_Human_after_6;

For every node, we also store the number of the parent node:

// Store the parents (number of the node of the upper level)
NodesAnalysis[NodeLevel_1_count, 1, 1] = 0;
NodesAnalysis[NodeLevel_2_count, 2, 1] = NodeLevel_1_count;
NodesAnalysis[NodeLevel_3_count, 3, 1] = NodeLevel_2_count;
NodesAnalysis[NodeLevel_4_count, 4, 1] = NodeLevel_3_count;
NodesAnalysis[NodeLevel_5_count, 5, 1] = NodeLevel_4_count;

This is required for the MiniMax algorithm implementation (see http://en.wikipedia.org/wiki/Minimax on how this algorithm works): We start from the lower level nodes and go up to the beginning of the tree, like in the schema that follows:

Suppose the game being played only has a maximum of two possible moves per player each turn. The algorithm generates the tree shown in the figure above, where the circles represent the moves of the computer AI running the algorithm (maximizing player), and squares represent the moves of the human opponent (minimizing player). For the example’s needs, the tree is limited to a look-ahead of 4 moves.

The algorithm evaluates each leaf node using the CountScore evaluation functions, obtaining the values shown. The moves where the maximizing player wins are assigned with positive infinity, while the moves that lead to a win of the minimizing player are assigned with negative infinity (this is again for illustration purposes only – infinity will not happen in the game as it is currently developed). At level 3, the algorithm will choose, for each node, the smallest of the child node values, and assign it to that same node (e.g. the node on the left will choose the minimum between "10" and "+8", therefore assigning the value "10" to itself). The next step, in level 2, consists of choosing for each node the largest of the child node values. Once again, the values are assigned to each parent node. The algorithm continues evaluating the maximum and minimum values of the child nodes alternately until it reaches the root node, where it chooses the move with the largest value (represented in the figure with a blue arrow). This is the move that the player should make in order to minimize the maximum possible loss.

In order for the program to calculate the best move, a number of “for loops” are applied so as to make the abovementioned backwards computation possible.

        for (counter7 = 1; counter7 <= NodeLevel_7_count; counter7++)
        {
            for (counter8 = 1; counter8 <= NodeLevel_8_count; counter8++)
            {
                if (NodesAnalysis[counter8, 8, 1] == counter7)
                {
                    if (counter8 == 1)
                        NodesAnalysis[counter7, 7, 0] = NodesAnalysis[counter8, 8, 0];
 
                    if (counter8 > 1)
                        if (NodesAnalysis[counter8, 8, 0] < NodesAnalysis[counter7, 7, 0])
                            NodesAnalysis[counter7, 7, 0] = NodesAnalysis[counter8, 8, 0];
                }
            }
        }

After the algorithm has reached the root node, the move with the best score is selected.

ComputerMove[Maximum thinking depth] – End

III. Huo Chess Thought Flow (v0.95 Kakos-Minimax or all v0.83 and older versions)

In this section, I analyze the thinking algorithm for version 0.93-Kakos-Minimax or for versions 0.84 and older. Below, I illustrate the step-by-step process of the computer's thought for a thinking depth of 2. Let's see the "step" boxes to understand the way the program is structured.

Scenario Details

  • Computer Level: Maitre (ThinkingDepth = 2)

ComputerMove - Start

Step 1

START

Move_Analyzed = 0

1.       If the first time called -> store initial chessboard position.
2.       if( Move_Analyzed >Thinking_Depth )
3.       Stop_Analyzing = true;
4.       if( Stop_Analyzing = false)
5.       Scan chessboard.
         for iii, jjj
6.       Scan chessboard, find a piece of the HY , conduct move, 
         check correctness and legality of move,
         and if all is OK, then call CheckMove to measure the score of the move.

Call: CheckMove

CheckMove - Start

  1. Number of moves analyzed ++.
  2. Check correctness and legality of move.
  3. Check if there is a mate on the chessboard.
  4. If the move is correct and legal, then do it.
  5. Check if there is a pawn to be promoted.
  6. Store move to ***_HY variables because, after many calls of ComputerMove and CheckMove functions, the initial values of the move analyzed will be lost.
  7. If this is the first move analyzed, then record it as the correct "best" move, no matter how bad it is.

Step 2

IF result: FALSE
Move_Analyzed = 0
  1. if(Move_Analyzed = Thinking_Depth)
  2. Measure the score of the move and record it as "best" move if it is larger than the score of the so-far best move score.

Step 3

IF result: TRUE
Move_Analyzed = 1
  1. if (Move_Analyzed < Thinking_Depth)

HumanMove - Start [HumanMove_Template for v0.93]

Step 4

Find the best answer of the Human (Move_Analyzed = 1).

Version 0.93: Find ALL possible human moves

  • Scan the chessboard -> find any possible move.
  • Call CheckHumanMove. [redundant in v0.93]

Store the chessboard score before and after the human move.

CheckHumanMove - Start

voidCheckHumanMove(array<String^, 2>^ CMSkakiera_Human_Thinking)

Count the score of the move and record it as "best"if its score is better than the so-far best move.
In v0.93 and newer: Record the score before and after the human opponents makes his move.
Those scores are recorded in the Nodes Analysis array and will be used for the MiniMax algorithm at the end (to evaluate the best move).

CheckHumanMove - End

Conduct the best move of the human [conduct all possible human moves in v0.93].

Move_Analyzed = Move_Analyzed + 1;
Who_Is_Analyzed = "HY";
 
for(i = 0; i <= 7;i++)
{
for(j = 0; j <= 7; j++)
{
Skakiera_Move_After[(i),(j)]=Skakiera_Human_Thinking[(i),(j)];
}

Step 5

Move_Analyzed = 2

Step 6

CALL next ComputerMove function for next-level move analysis.

Move_Analyzed = 2
if(Move_Analyzed == 2)
this->ComputerMove2(Skakiera_Move_After);
elseif(Move_Analyzed == 4)
this->ComputerMove4(Skakiera_Move_After);
elseif(Move_Analyzed == 6)
this->ComputerMove6(Skakiera_Move_After);
elseif(Move_Analyzed == 8)
this->ComputerMove8(Skakiera_Move_After);
 
// Call ComputerMove2 to find the best next move of the HY (deeper thinking)

Step 7

Scan the chessboard and find the best move for the computer.

Move_Analyzed = 2
voidComputerMove2(array<STRING^, />^ Skakiera_Thinking_2)
{
// Same as…ComputerMove
 
if(Move_Analyzed has not reached thinking depth)
{
// Same as…ComputerMove: Call CheckMove -> HumanMove -> next ComputerMove etc
// (If we haven't reached the desired level of analysis, then the HumanMove
// will be called again, then again the ComputerMove function etc.)
}

Step 8

Return to a previous ComputerMove (i.e. ComputerMove4 calls ComputerMove2) function to continue the analysis.

Move_Analyzed = 2 (at the end of the analysis this variable will be equal to 0, see Step 9).

// Return to the ComputerMove function of the 'previous' thinking
// level to continue the analysis
 
Move_Analyzed = Move_Analyzed - 2;
Who_Is_Analyzed = "HY";
 
for(i = 0; i <= 7; i++)
{
for(j = 0; j <= 7; j++)
{
Skakiera_Thinking[i,j] = Skakiera_Move_0[i,j];
}
}
}

ComputerMove2 - End

HumanMove - End

CheckMove - End

// close for iii, jjj loop
// close if( Stop_Analyzing = false ) segment

If no legal move is found -> we have MATE!

Step 9

Version 0.93: Apply the MiniMax algorithm to reach to the best move.

Play the move with the highest score. Now it is the Human's turn to play.

if (move_analyzed==0){
  1. Check if it is good to conduct castling.
  2. "Redraw" the chessboard with the best move found.
  3. Move the rook next to the king, if castling occurred.
  4. Check if a pawn is promoted (at the current version computer always promotes a pawn to queen).
  5. Now it is the turn of the other player (human) to play!
}
20. else
21. {
22. Move_Analyzed = Move_Analyzed - 2;
23. Who_Is_Analyzed = "HY";
24.
25. for(i = 0; i <= 7; i++)
26. {
27. for(j = 0; j <= 7;j++)
28. {
29. Skakiera_Thinking[i,j] = Skakiera_Move_0[i,j];
30. }
31. }
}

ComputerMove – End

IV. Huo Chess Thinking Flow (v0.93 Kakos-Minimax or v0.84 and older)

ComputerMove()
{
for
{
    // First level of thought
    CheckMove()
    {
    if (Move_Analyzed <Thinking_Depth)
    {
        Move_Analyzed++;
        // Find the best possible human move-answer and continue the thinking tree
        Find Best Human Move (HumanMove function) / Find all possible human moves (v0.93);
         Record chessboard scores before and after the human move;
        Move_Analyzed++;
        Go to next thinking depth
 
            ComputerMove2()
            {
                for
                {
                    CheckMove();
 
                    // Think deeper if you have not reached the thinking depth
                    if (Move_Analyzed <Thinking_Depth)
                        [Think deeper, if necessary!];
 
                    // Record move analyzed as Best Move, if it has the best score
                    if (Move_Analyzed = Thinking_Depth)
                        CountScore();
                        [Record if best move];
                }
 
            // Return to the initial level of thinking to start
            // analyzing a new thread
            Move_Analyzed = Move_Analyzed – 2;
    }
    }
}
 
Do the best move;
}

V. Huo Chess Thinking Flow (v0.95 Simple-Minimax)

ComputerMove()
{
 
DangerousSquares
MoveFilter
 
for all possible moves
{
    Temporarily make all possible moves
    Count the score of these moves
    Call ComputerMove2 (with the temporary chessboard as input)
 
    // Second level of thought
    ComputerMove2()
    {
         ...
         ComputerMove5()
         {
         Record the moves and their scores in the Nodes Analysis array
         }
    }
}
 
Do the best move (MiniMax);
}

VI. Huo Chess Micro Edition

I attempted to create a "Micro edition" of Huo Chess by stripping the program off every unnecessary line of code or file. In particular, in order to reduce the size, I used Huo Chess version 0.6 (programmed in C++) (you can find it in the Downloads section in the "Older versions") and did the following:

  1. Reduced all string/text in the program (i.e. "White Rook" => "WR")
  2. Reduced the length of variable names (in every variable in the program, specific strings were replaced with smaller ones). I don't really know why, but this played a role! Try it yourself to see...
  3. Icon was replaced with smaller one
  4. Removed all unnecessary files (resources, assembly.ccp, stdafx, etc.)

With the above steps implemented, the size was reduced from 53.5 KB to 47.5 KB. However, the code of the program can't be read at all! There is a price for small code...

After processing the final executable file with .NETZ (can be obtained for free from http://www.madebits.com/netz/) the size was reduced to a mere 36 KB. .NETZ is a compression tool that started in Codeproject [see http://www.codeproject.com/KB/dotnet/ReduceDotNetSize.aspx]. You can also look at http://www.jot.fm/issues/issue_2005_09/article1/ in order to see how this reduction in size of the PE (portable executable) is realized. The file is distributed as well tagged as 'Micro Edition' (see the downloadable files at the top of the article).

VII. Huo Chess GUI Edition

I created a Huo Chess edition with Graphical User interface (GUI). For the development of that edition, I used the C# and Visual Studio 2012. In previous versions the  XNA Game Studio version 3.0 (based on Microsoft Visual Studio 2008) was used. It consists of a simple chessboard which shows the current chessboard state. It does support mouse move so you do not have to enter the moves via keyboard. More advanced GUI editions with come in the future. It must be noted that the GUI did not affect the total size of the program much. The Huo Chess C# 0.95 GUI edition has a total size of 93 KB in the 0.95 version.

VIII. Huo Chess Games Archive

That segment contains games played by Huo Chess versus other micro chess programs.

GAME 1

Date: 2007-11-11
Place: Athens, Greece
White: HuoChess v0.4 (with Opening Book) [as distributed by The Code Project]
Black: Microchess (as provided by BenLo Park)
Result: Draw by threefold repetition

1.       d4 Nc6
2.       d5 Nb4
3.       Nc3 e5
4.       Bg5 Qxg5
5.       Nh3 Qg4
6.       e4 Qh4
7.       Be2 d6
8.       Bb5+ Kd8
9.       Nf4 Qxf4
10.      h3 Nf6
11.      f3 Qe3+
12.      Be2 Bd7
13.      f4 Qg3+
14.      Kd2 Qxf4+
15.      Ke1 Qg3+
16.      Kd2 Qf4+
17.      Ke1 Qg3+
18.      Kd2 Qf4+
19.      Ke1 Qg3+
20.      Kd2 Qf4+
21.      Ke1 [draw by threefold repetition]

GAME 2

Date: 2007-11-11
Place: Athens, Greece
White: Microchess (as provided by BenLo Park)
Black: HuoChess v0.4 (with Opening Book) [as distributed by The Code Project]
Result: Draw by threefold repetition

1.       e4 e6
2.       Qh5 d6
3.       Bb5+ Ke7
4.       Qg5+ f6
5.       Qh5 h6
6.       d4 g6
7.       Qxg6 Nd7
8.       Bf4 f5
9.       exf5 Ndf6
10.      fxe6 Bxe6
11.      a4 Bg7
12.      Qxg7+ Bf7
13.      Qxh8 Bh5
14.      Qg7+ Bf7
15.      Nc3 h5
16.      Nf3 Nh7
17.      Nd5+ Ke6
18.      c4 c6
19.      Nc7+ Qxc7
20.      d5+ cxd5
21.      Nd4+ Ke7
22.      Nf5+ Ke6
23.      Nd4+ Ke7
24.      Nf5+ Ke6
25.      Nd4+ Ke7
26.      Nf5+ Ke6
27.      Nd4+ Ke7
28.      Nf5+ [draw by threefold repetition]

GAME 3

Date: 2008-01-22
Place: Athens, Greece
White: Microchess (as provided by BenLo Park)
Black: HuoChess v0.5 (with Opening Book) [as distributed by The Code Project]
Result: Draw by threefold repetition

1.       e2-e4 e7-e6
2.       d1-h5 c7-c5
3.       f1-b5 g8-f6
4.       h5-e5 f6-g4
5.       e5-f4 g4xf2
6.       e1xf2 g7-g5
7.       f4-e5 a7-a6
8.       b5-c4 f7-f6
9.       e5-g3 d7-d6
10.      g1-h3 h7-h6
11.      h1-e1 e8-e7
12.      b1-a3 d8-b6
13.      d2-d4 b6-a5
14.      c1-d2 a5xd2+
15.      e1-e2 d2xd4+
16.      16.f2-f3 d4xb2
17.      a1-d1 b2xa3+
18.      c2-c3 a3xc3+
19.      c4-d3 a6-a5
20.      f3-g4 e7-d7
21.      d3-b5+ d7-e7
22.      g3xc3 f8-g7
23.      e2-f2 e7-f7
24.      d1xd6 a8-a7
25.      c3xc5 b8-c6
26.      f2-f3 b7-b6
27.      c5xb6 c8-d7
28.      f3-c3 e6-e5+
29.      d6xd7+ a7xd7
30.      b5-c4+ f7-e7
31.      b6-c5+ d7-d6
32.      c3-d3 c6-d4
33.      c5-c7+ d6-d7
34.      c7-c5+ d7-d6
35.      c5-c7+ d6-d7
36.      c7-c5+ d7-d6 [draw by threefold repetition]

GAME 4

Date: 2008-02-22
Place: Athens, Greece
White: Microchess (as provided by BenLo Park)
Black: HuoChess v0.6 (without Opening Book) [as distributed by The Code Project]
Result: Draw by threefold repetition

1.       Nf3 d5
2.       Nc3 Qd6
3.       Na4 Qf4
4.       c3 Bd7
5.       d4 Qe4
6.       Ng5 Qg4
7.       f3 Qh4+
8.       g3 Qh5
9.       Nc5 Bb5
10.      b3 f6
11.      Nge6 b6
12.      e3 Bc6
13.      Nd3 Bd7
14.      Nxf8 Kxf8
15.      Nf4 Qg5
16.      Ne2 Nc6
17.      f4 Qg4
18.      h3 Qf3
19.      Rh2 Nh6
20.      Kd2 Nf5
21.      Kc2 Qe4+
22.      Kb2 Qf3
23.      Kc2 Qe4+
24.      Kb2 Qf3
25.      Kc2 Qe4+

Huo Chess (even without Opening Book) managed to play a very good game, during which it played well-structured chess. It didn't conduct any wrong moves, didn't give up any pieces and had a better position than Microchess at the end of the game (when the threefold repetition resulted in a draw).

GAME 5

Date: 2009-01-25
Place: Athens, Greece
White: Microchess (as provided by BenLo Park)
Black: HuoChess v0.82 (with Opening Book) [as distributed by The Code Project]
Result: Draw by threefold repetition

1. e4   e6
2. Qh5  Qe7
3. Bc4  Kd8
4. d4   a6
5. Bf4  d5
6. exd5 f5
7. dxe6 Bxe6
8. Bxe6 g6
9. Qe2  Nd7
10. Bxc7+ Kxc7
11. Qc4+ Nc5
12. dxc5 Qg7
13. Qf4+ Kc6
14. Qf3+ Kxc5
15. Qd5+ Kb6
16. Qb3+ Kc7
17. Qc4+ Kd6
18. Qd5+ Kc7
19. Qc4+ Kd6
20. Qd5+ Kc7
21. Qc4+ Kd6
22. Qd5+  draw by threefold repetition

Huo Chess played a good game. It did not give up pieces without reason and did not lose chances to kill opponent’s pieces when possible.

History

  • 3 October, 2007 -- Original version posted
  • 15 October, 2007 -- Version 0.2
  • 22 October, 2007 -- Version 0.3
  • 15 November, 2007 -- Version 0.4
  • 25 January, 2008 -- Version 0.5
  • 28 January, 2008 -- License info and download updated
  • 28 February, 2008 -- Article content and downloads updated
  • 3 July, 2008 -- Version 0.721 - Article content and downloads updated
  • 8 January, 2009 -- Version 0.722 - Article content and downloads updated
  • 22 April, 2009 - Version 0.82 - Article content and downloads updated
  • 8 September, 2011 – Version 0.93 (C# only) – MiniMax algorithm update
  • 19 September 2012 – Version 0.95 (C# only) - Update dangerous squares check & CountScore 

Versioning

Huo Chess is intelligently designed, but it also evolves. Currently, the program is at version 0.95. The timeline of versions and the respective changes conducted in the program's code are depicted below.

Version 0.95 (C#)

Changes in Huo Chess 0.95:

1. Merged the CountScore and CountScore_Human in one function. Also added parameters to the function so as to better control its parameterization.

2. Added functions to find the dangerous squares in the chessboard (see FindAttackers and FindDefenders functions). Added a "danger" check in the CountScore function. This will check whether the piece in a square is threatened by one or more pieces of the opponent (see DangerWeight variable)

3. Removed unused variables to eliminate all warnings. Reach a Maintenance Index of 19 (from 16 in the previous versions).

4. Fixed the program to take into account Danger_penalty (and removed the similar danger_penalty which was used in some places and caused confusion, actually nulling the effect of Danger_penalty in CountScore)

5. Uncomment the "Find value of piece in Skakiera(y,u)" part in ComputerMove, so as to find the value of Value_of_piece_in_square.+++

Size: 57 KB (without GUI), 93 KB (with GUI) 

0.93 Versions (only C#)

Implemented the MiniMax algorithm for thinking. Two types of versions are distributed:

  1. Huo Chess (Kakos-MiniMax edition): A version where the existing Kakos algorithm for searching in depth is used, with the MiniMax algorithm added for the evaluation of the best move.
  2. Huo Chess (Simple-MiniMax): A new simpler version where the searching in depth has been written from scratch (in an attempt to "clean" the code). MiniMax algorithm is again used for the evaluation of the best move. In this simpler method, the following changes have taken place: Deleted the CheckMoveCountScore_HumanHumanMoveCheckHumanMove HumanMove_template functions. Reorganized and simply Increased thinking depths from 8 to 20. Reduced the size by using a template ComputerMove function for all thinking depths (instead of ComputerMove2ComputerMove4ComputerMove6, etc.). The C++ edition is still in 0.81 version (separate ComputerMove functions still exist) and XNA / VB versions are still in 0.82 versions and are still distributed for educational purposes. Size of C# edition: 52.5 KB.
Version 0.82Changed the ComputerMoveHumanMoveCountScoreElegxosOrthotitas functions. Increased thinking depths from 8 to 20. Reduced the size by using a template ComputerMove function for all thinking depths (instead of ComputerMove2ComputerMove4ComputerMove6 etc). The C++ edition is still in 0.81 version (separate ComputerMove functions still exist), for educational purposes. Size of C# edition: 52.5 KB.
Version 0.722 XNAHuo Chess (C# edition) with Graphical User Interface based on XNA.
Version 0.722 cs Huo Chess port in C# programming language.
Version 0.722Fixed some issues with the HumanMove function.
Version 0.721More thinking depth analysis capability has been added to the program. Huo Chess uses the ComputerMove2ComputerMove4ComputerMove6 and ComputerMove8 functions to think at a depth of 8 moves (4 half-moves for the white and 4 half-moves for the black pieces). Size: 56.5 KB
Version 0.6 (Micro edition)It was based on version 0.6. Reduced all string/text (i.e. "White Rook" => "WR"). Reduced the length of variable names (in every variable in the program, specific strings were replaced with smaller ones). Icon was replaced with smaller one. Removed all unnecessary files (resources, assembly.cpp, stdafx, etc.). Size: 47.5 KB
Version 0.6Removed the empty try...catch statement in line 3959 at HumanMove, which caused the bug at ElegxosNomimotitas not to show. Optimized the CountScore function. Fixed the bug at ElegxosNomimotitas in the part that checks moves of Rook-Queen-Bishop at lines 3143-32173. Added penalty in case the computer moves its pieces next to an opponent' pawn. Made the computer eat the opponent's queen when there is a chance. Lowered the value of the opponent's king, so as to avoid the computer continuously going after him and sacrifice pieces for that. Optimized the CountScore_Human function. Size: 53.5 KB
Version 0.5Fixed HumanMove function. Optimized CountScore and ComputerMove functions. Size: 51.5 KB
Version 0.4Added random playing capability. Optimized CheckForWhiteCheck and CheckForBlackCheck functions. Size: 51.0 KB
Version 0.3Stronger playing capabilities. Added opening book capability. Optimized ElegxosNomimotitas and ElegxosOrthotitas functions. Size: 91.5 KB
Version 0.2Fixed some bugs due to which computer played illegal moves. Thanks to everyone who gave me feedback! Size: 99.5 KB
Version 0.1Initial version. Known problems: the program plays some illegal moves sometimes. Not too strong at all. 49.0 KB

++Keep coding! 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Palavos
Software Developer Kakos Bros Solutions
Greece Greece
Spiros [Spyridon or Spyros are also used] Kakos (huo) lives in Athens, Greece. He is currently working as an IT consultant in a large firm. Begun programming during the Commodore era in MS Basic and is still trying to learn (mostly in C++ and C#)...
He likes chess and has recently bought a new (old) modem for one of his Commodores 128 (yes, he has two of them!) to set up a server based on 8-bit technology. He thinks that when the World Wide Web crashes completely by an alien cyber attack, he will be the only one capable of surfing with his Commodore computer and will eventually save the day...
He likes reading and writting philosophy and is a fond admirer of Aristotle and Alfred Russel Wallace. His main heritage is Harmonia Philosophica.
At his free time he is researching the application of polypyrrole (PPy) in the PCB manufacturing process (through-hole plating) at the National Technical University of Athens - Advanced Materials section.
Follow on   Twitter

Comments and Discussions

 
QuestionOpening book PinmemberMember 1074412924-May-14 1:14 
SuggestionConsole App UI PinmemberMichael-Kirk-197911-Oct-13 5:16 
GeneralMy vote of 5 Pinmemberfredatcodeproject8-May-13 11:20 
GeneralRe: My vote of 5 PinmemberPalavos15-May-13 2:05 
SuggestionEndgame Tablebase Support PinmemberLogi Guna26-Jan-13 6:05 
GeneralRe: Endgame Tablebase Support PinmemberPalavos11-Mar-13 23:51 
QuestionI really like Pinmemberaustinhgaca24-Sep-12 0:35 
AnswerRe: I really like PinmemberPalavos24-Sep-12 1:24 
GeneralMy vote of 5 Pinmemberravithejag23-Sep-12 18:15 
GeneralRe: My vote of 5 PinmemberPalavos23-Sep-12 21:13 
GeneralMy vote of 5 Pinmemberfredatcodeproject23-Sep-12 12:21 
GeneralRe: My vote of 5 PinmemberPalavos23-Sep-12 13:22 
GeneralMy vote of 5 PinmemberJusitn_H21-Sep-12 10:34 
GeneralRe: My vote of 5 PinmemberPalavos22-Sep-12 2:09 
Bugnull reference bug PinmemberYustme20-Sep-12 22:12 
GeneralRe: null reference bug [modified] PinmemberPalavos21-Sep-12 6:29 
GeneralRe: null reference bug PinmemberPalavos21-Sep-12 8:30 
GeneralRe: null reference bug PinmemberYustme24-Sep-12 3:22 
GeneralRe: null reference bug PinmemberPalavos24-Sep-12 5:13 
AnswerSOLUTION for null reference bug [modified] PinmemberPalavos24-Sep-12 10:32 
GeneralMy vote of 5 PinmvpKanasz Robert20-Sep-12 1:32 
GeneralRe: My vote of 5 PinmemberPalavos20-Sep-12 2:26 
QuestionVersion 0.95 published PinmemberPalavos19-Sep-12 20:01 
Questionen passant support? PinmemberMember 471711418-Dec-11 3:19 
AnswerRe: en passant support? PinmemberPalavos23-Dec-11 13:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 24 Sep 2012
Article Copyright 2007 by Palavos
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid