Interested in chess programming? You are interested in philosophy too! What is thinking? Can AI be conscious? What does it mean to do something? Can the AI understand that it does play chess? Explore the AI related articles in Harmonia Philosophica and understand why you are already a philosopher!
Goal
Some years have passed since the latest major update of Huo Chess. The goal of this article is to catch up with the developments of the latest years and show how an application built in previous versions of the Visual Studio can be ported into Visual Studio 2022. We will also show what is new with the newest .NET 6.0 Platform and what are the implications of the latest developments in the tools provided by Microsoft for building applications with C#. We will use the Huo Chess micro-chess engine published in this site as an example to show all the above in a short and concise way.
Important Notes: The new versions of the Huo Chess application in Visual Studio 2022 C# NET 6.0 are called ‘Huo Chess DV’ (from Huo Chess Delta Version).
Overview
Things in computers evolve over time. In the ‘old days’ we had BASIC. Then we had .NET Framework. Now we have .NET Platform (see also here), the latest weapon in the arsenal of Microsoft that allows developers to develop cross-platform applications with a single framework.
And yes, .NET Platform is not the same with .NET Framework. In fact the latter is almost dead, as its support will soon end, whereas .NET is the latest framework (without the word… Framework in its tile, computer world always finds ways to confuse the uninitiated as alchemy used to do in the old days) you should choose. It has been around for some years now and its latest version is .NET 6.0. The .NET platform contains all the necessary tools, drivers and libraries to allow the modern programmer develop their programs.
And just to add more complexity to the already complex landscape, one needs to know that .NET Framework was initially succeeded by .NET Core. It was only after .NET Core 3.1 that it was decided to name the new framework .NET (without the ‘Core’) and that is what we now have .NET. Net (pun intended). [1] [2] [3].
The new .NET Platform allows for easier development of applications for various platforms, from Android to Mac. Details on how this is done is beyond the limited scope of this article.
The purpose of this article is to show how the open source micro-chess engine of Huo Chess was ported into Visual Studio 2022 and .NET 6.0. The next sections will present the problems and obstacles one might face when using the new platform and how they can be used to minimize the size of the application as much as possible.
Tutorials for building a chess program
There are many available tutorials on how to build a chess program. These are all based on Huo Chess open source code and will come in handy when trying to create your own first program. The logic of the program is explained, the functions used and the way the program thinks.
Tutorials on how to develop a chess program include:
This article only covers the porting of Huo Chess into Visual Studio 2022 and .NET 6.0, so in case you are lacking the basic understanding on how to program a chess application please visit these articles first. In any case, you are more than welcomed to continue reading and use the source code provided below as it is. Many times learning to program entails starting directly to… program. That is how I used to learn programming in Commodore and that is always the best way to start. Learning should always go hand in hand with practice.
After all remember: There is no way to learn without experimenting and making mistakes (but keeping a backups is always useful).
Huo Chess source code
The Huo Chess chess program is an open source micro-chess engine specifically designed for simplicity for educational purposes. One can view the code and easily understand the basic structure of a chess engine using Mini-Max algorithm for its thinking process. Reusing the code is allowed by all means (and even encouraged), as long as the source of the code is cited properly.
You can download the latest files for previous Visual Studio versions via the relative sites:
Download the code from the sites above, open them in your local Visual Studio 2022 and… let the fun begin.
In this article, I will describe how the Visual Studio 2019 Huo Chess based on .NET Framework was ported into Visual Studio 2022 and .NET 6.0. In the process I will describe some changes that were necessary and you will be asked to apply those changes to the program you downloaded yourself.
If you are impatient or find that difficult, you can always download the ported (‘fixed’) program from the last chapter at the end of this article.
First things First: Fixing dpi issues
Modern world is different than the world during the Commodore era in many ways. One of them is higher dpis. A modern program should handle that higher dpi of the screens effectively, otherwise it will look blurry. If you try to compile and run the program you already downloaded, you can see that for yourself.
Huo Chess previous version had an issue with how high-dpi screens were handled, making the UI of the chessboard look blurry without the fix. The changes described below are the changes needed to fix the Huo Chess issues for laptops with high dpi [28].
Please do try to apply those changes yourself in the project you already downloaded and see how they can improve the UI look and feel of the program.
Change 1: The application needs to add a compatibility declaration for Windows 10 in the manifest file:
Note: If you cannot find the app.config of your application read here for more.
With these changes, the application will handle high dpi of a modern screen fine. However you will still have a problem: the pieces in the chessboard will look small. Try to figure out how to fix that yourself (if you are impatient, just download the source files at the end of this article).
Tip: Try to change the zoom option in the pictureBoxes in the chessboard.
Porting in Visual Studio 2022…
The first thing to do when developing a new application is of course to download and open the IDE. So go and get the latest Visual Studio, open it and then load the program of Huo Chess. In that way you will load the application and you will also be able to build it and run it.
However, that will not make your application a .NET application. Instead, the existing (old) .NET Framework will still be used.
In order to make your application an application that utlizes the latest .NET Platform, you must create a new project and select to create…
Console C# application .NET for the Huo Chess console application (DO NOT select the .NET Framework console application, this is the old framework) [4] [5]
WinForms C# NET application for the Huo Chess GUI application (DO NOT select the .NET Framework console application, this is the old framework) [6]
After you create the applications, ‘all’ you need to do is copy the code of the old Huo Chess applications into the new projects. Do it your self and learn something through that process. You will learn that copying is not as simple as it seems. Some times you will forget times, some other times you will see that the new .NET application needs something additional in order to compile.
Follow the Visual Studio Intellisense suggestions to walk your way through the hurdles.
For example, you might be missing a ‘using’ statement in the beginning of the program for elements of the application. If that happens (and it WILL happen since the structure of the application in the new project is somewhat different that the old one), first take some time to understand the problem.
Consider for example the following example…
The problem seems to be with the StreamWriter that is highlighted accordingly. If you hover over the Intellisense lightbulb on the left, you will see some suggestions on how to fix the problem.
We will follow the first suggestion and simply add the missing ‘using’ directive in the beginning of the program. Essentially we were using the StreamWriter function without adding the relevant reference to the library containing that functionality. By simply adding the reference as below, the program compiled successfully.
Hopefully with some effort (depending on your level) you will be able to transfer Huo Chess from previous Visual Studio versions to the latest Visual Studio 2022.
So let’s move to the next and crucial step: Publishing!
Publishing the application
Once we created the application and successfully compiled it, we need to create the executable of our application that we will share with others when distributing our chess program. That is where the new .NET Platform has many options for publishing to various systems.
We will explore the best possible parameters to use so as to achieve the major goal for Huo Chess when it comes to size. And that is only one thing: Minimum size!
In summary, the following parameters are used:
Target framework: Net 6.0 – Windows 7.0
Deployment mode: Framework dependent
Target runtime: win-x86 for the console application / win-x64 for the winForms application
Other details: Set to produce a single file with no manifest
So essentially we are publishing for not the latest version of Windows, but we are using the latest framework .NET 6.0.
The publishing is conducted in Framework Dependent mode, meaning that the publishing will generate the minimum needed size of the application that will expect the host system to contain the .NET framework in order to run. Of course that is logical to expect, since the .NET framework is developed to be shared in as many computers as possible so that developers can use it – the was we used to us Java that was again supposed to be installed everywhere.
If we choose the other option to produce a Self-contained application, Visual Studio will publish a huge-sized application (counting in MBs) that will contain all needed .NET libraries for it to run. Useful to make sure your application will run even in a system without the .NET, but not useful for Huo Chess.
It is also important to select a specific target runtime for the publishing to generate code for that specific runtime. Try choosing other runtimes to see how easy it is and check out what will happen.
Last but not least, we choose to publish one single file. Doing so provides us with the true size of the application. There is no point in choosing to publish in multiple files and ‘fool ourselves’ that our application is small just because we choose to look at the size only of the .exe file in the folder…
Application trimming
Because of the changes brought by .NET, the size of the applications is somewhat (or significantly) increased vis-à-vis previous versions of the .NET Framework. Being modern, flexible and cross-platform has a price after all.
For Huo Chess this means that the console edition is now 159 KB (from 44 KB that it used to be) and the GUI edition is now 239 KB (from 96 KB that it used to be).
In order to fix that problem, Microsoft added functionalities to trim the code and optimize its size. There are many articles for application trimming in the References at the end of this article that you can read [17-20] [22] [23].
One basic thing to do in order to reduce the size of your application is to disable the implicit usings. ‘Implicit usings’ essentially tell the Visual Studio to add additional needed references to your project as it sees fit based on your code. Disabling this and selecting on your own the ‘using’ statements to have (like the one for the IO we added above) is the way to go when you need minimum size.
There is also an option to allow application trimming, however this applies only to specific publishing configurations and not to the ones we have selected above for Huo Chess. The trimming options look something like…
However as already said, you cannot use the trimming options when publishing in Framework dependent mode. If we had selected to publish a Self-contained application these options would greatly reduce the size of our application.
The following file has a nice comparison of the resulting application sizes for Huo Chess console and GUI applications for various publishing and trimming configurations.
Use these projects to learn how to program, to view them as you are reading the relative tutorials available in Harmonia Philosophica, or simple to experiment with your own ideas on how a chess program should look like! Again, re-using the code is free and encouraged, as long as you properly indicate where you found it!
Interested in chess programming? You are interested in philosophy too! What is thinking? Can AI be conscious? What does it mean to do something? Can the AI understand that it does play chess? Explore the AI related articles in Harmonia Philosophica and understand why you are already a philosopher!
2022-05-06: Huo Chess v0.7 in QBasic with graphics is released. The version addresses Out of Memory issues with the logs of the application.
2021-11-14: Created a GitHub repository of the Huo Chess Quick Basic edition.
2021-03-14: Updated thinking in levels 4 and 5; now extra analysis at these levels only happens if the move entails the capturing of a piece. Updated CountScore to include positional elements in the evaluation. Introduced the notions of mate and stalemate in the thinking process.
2020-12-16: Fixed issue with en passant move.
This is an article on how one can develop a chess program in QBasic.
It is based on Huo Chess that was developed by me and is available as open source in multiple programming languages (C#, Java, older versions in C++ and Visual Basic).
Parts of the article have been posted as separate tutorials (check here). They are all gathered here in a unique article that can provide an overall understanding of the chess programming complexity.
The tutorial is at the point at a very simple/ high level but it will be enriched as time passes by. The initial goal was to have at least a starting point for someone who needs to delve into the chess programming cosmos and this I believe I have managed to achieve.
Why in QBasic?
Well, BASIC is simple and fun!
Do you need more reasons?
Well…
Here is another one:
10 PRINT "Why not?!"
20 GOTO 10
That’s what happens when you mess with BASIC. Seriously now, at the end, the goal here is to present the algorithm. The specific language of the implementation does not play a particular role. When you are at a level to develop the next Stockfish be sure to remember that it was here from where you started your journey…
The tutorial should be read in conjunction with the source code of Huo Chess offered here. The code itself is written in a simple and structured way and it is heavily commented so that even without any prior knowledge one can easily understand how thw algorithm works.
Let’s not waste any more time!
Happy coding!
I. Beginning
Let us begin from the… beginning. And one step at a time, try to see how we can develop our chess program.
Important Notes
Refer to QB64 site for questions regarding how QBasic commands work. Essentially they are simple, but in case your are stuck with an error you cannot resolve, this is the place where you will find your answers.
Always have the source code open in a separate window. Although the tutorial only goes throug portions of the code to explain how it works, it is always beneficial to have the whole source code of the working program in front of you.
A note about the source code versions: Chapter I to IV refer to the version 0.3 of the code. Chapter V refers to the version 0.6 of the code.
The Huo Chess Quick Basic edition is available for download either from here or from the relevant Huo Chess QB64 GitHub repository.
And don’t forget: Coding is about experimenting!
Do not wait everything from this tutorial or from any other tutorial! Just open the QBasic editor and write code! Change things! See what they do! At the end it is YOU who is learning, not me teaching you!
Programming is fun.
Want to learn? Why not start now?
And what better way there is than to develop an advanced program that makes the computer “think” how to play chess?! Forget about those silly beginners’ example programs which print “Hello world”. Who in his right mind ever spends time to write a program which prints “Hello world” on the screen?
BASIC is fun.
A very easy language for kids to start learning programming. So we will use it here. (Not in the mood for BASIC? Search for the Java and C# relevant tutorials in Harmonia Philosophica!)
And in one day, you will have learnt the basic of how to program a chess program in BASIC! The actual implementation could take a bit longer but in general in some days you will have the knowledge of how the program works, thus being in a position to improve it or write your own!
The BASIC programming language is one of the simplest ones. Especially designed for simplicity, it uses simple commands to perform operations. The commands are easy to learn and use, since they are utilizing English language words which are easily recognizable. Want to print something on the screen? Use the command PRINT! Want to determine what will happen if something else happens? Use the command IF! See what I mean?
IF YOU_UNDERSTAND = "Yes" THEN PRINT "Yes I understand!"
Did you understand the above command? Great!
The only thing that might trouble you if you are new to programming is the notion of variables. A variable is an element which holds values. This element is used in various places of the program. The values could be of different types – the ones we will use are integers (1, 4, 10…) and strings/ characters (e.g. “white pawn”).
Variables could be stored also in arrays. An array is a collection of variables in one or more dimensions. It is also known as a “table”. And yes, you guessed right: we will use an array (table) to store the chessboard. Could you guess the dimensions of that table? Spot on again.
DIM SHARED chessboard$(8, 8)
The command DIM defines a variable. We do all the variable declarations in the beginning of the program. The above command declares an 8×8 array which holds the… you guessed it right: The chessboard!
By the way, we are using QBasic64, a version of Quick Basic that is available for free and pretty popular as well. Check https://www.qb64.org/portal/ to get it. The site also contains excellent tutorials and training material. You will have it as a reference throughout the whole process, so make sure you create a bookmark out of it.
After you download QBasic64 from the site, just click on the QB64.exe file and execute it. You will be presented with the IDE (programming interface) of QBasic where you will write your program. I do not need to explain the “Create new”, “Save” or “Save as” functions…
Just start writing the commands and then press “Save as”. Executing the program is easy as well. Just select Run > Start.
As said above, what is the first thing to do? (Besides the “Create new program” part and saving it in a folder of your choosing with a name of your choosing as well)
Some of the first things to do we already mentioned.
First, declare the variables. BASIC is really simple in the sense that it is not so strict in requiring you to declare all the variables before using them, in contrast to other high level languages like C#. However this is also a downside of the language. Leaving the programmer with some slack makes the programmer careless.
So we will declare all the variables we use…
DEFINT A-Z OPTION BASE 1 'Make tables dimensions start from 1
DIM SHARED chessboard$(8, 8) COMMON SHARED startingRank, startingColumn COMMON SHARED finishingRank, finishingColumn COMMON SHARED startingRankText$, startingColumnText$ COMMON SHARED finishingRankText$, finishingColumnText$ COMMON SHARED Move$ COMMON SHARED MovingPiece$ COMMON SHARED debugMode
There you go. (Read the QB64 Wiki for what DEFINT A-Z and OPTION BASE 1 commands do – Remember, learning entails the process of… learning)
What is next?
What else?
Ask the user for input!
And what else to ask than his first move! For simplicity purposes we will present the main command which tells the user to put his move. The drawing of the board on the screen will be done by the drawBoard() function. A function is an independent set of code that you can call to perform an action. In our case we call the drawBoard function (with the command… CALL DRAWBOARD – I told you it was simple). For the time being forget how the function works. (Even though reading through it and trying to understand how it works would be a lesson on its own…)
So how would you ask for the user input?
Simple by the command… INPUT!
There you go:
INPUT "Enter your move: ", Move$
This command tells the computer to wait for the user to enter something and press Enter. When this happens, the text entered by the user is saved in the Move$ variable. The dollar sign ($) indicates that the variable is a string (text) and not a number.
Let’s stay there.
For now you have learnt how to…
Create a new program.
Declare the variables you will use (including the chessboard).
Ask from the user to enter his first move.
You have also been acquainted with the notions of variables and functions and with some basic BASIC (get the joke?) commands, like IF… THEN or INPUT and PRINT. Don’t worry if you don’t get everything yet. You will as you program more and more every day.
Next lessons will include the next logical steps:
Validate that the user move is valid and legal.
Redraw the chessboard with the move of the user.
Make the computer think of an answer.
You would be surprised how the last part (the thinking of the computer) is a rather simple one. In essence the computer thinks of all possible moves, validates them (in the same way we will validate the move entered by the user) and then for the valid ones it will calculate a score of the position. The move with the best score will be the move of the computer.
II. Check legality of a move
In the previous chapter we managed to create our program in BASIC (QB64) and write the first lines of code to ask for input from the user for his move.
Now we will perform the next and one of the most important steps in a chess program: Checking the legality and validity of a move!
Remember that we asked from the user his move by the command…
INPUT "Enter your move: ", Move$
With this command the computer asks for input by the user and then stores what the user entered (after he presses Enter) into the Move$ variable. As we said in the previous lesson, the $ sign in a variable name denotes that the variable stores a string (text) value and not a number.
Now that we have the move into a single text variable, we should first of all “break it down” into four specific elements:
Starting column
Starting rank
Finishing column
Finishing rank
In that way we will have the starting and finishing coordinates of the user’s move, which we will use for the checking of the legality of the move later on.
How do we “break up” the text? By using the MID$ built-in function of BASIC which returns a specific character from a text. So if the user entered the move “g2g4” (which is Grob opening by the way, one of my favorites), then the command…
MID$(Move$, 2, 1)
will return the character “2”, since it will start from character 2 of the Move$ variable and will get 1 character.
Without further delay, here is the code which breaks up the move the user entered into the four numbers we are looking for.
SELECT CASE startingRankText$ CASE "1" startingRank = 1 CASE "2" startingRank = 2 CASE "3" startingRank = 3 CASE "4" startingRank = 4 CASE "5" startingRank = 5 CASE "6" startingRank = 6 CASE "7" startingRank = 7 CASE "8" startingRank = 8 END SELECT
SELECT CASE finishingRankText$ CASE "1" finishingRank = 1 CASE "2" finishingRank = 2 CASE "3" finishingRank = 3 CASE "4" finishingRank = 4 CASE "5" finishingRank = 5 CASE "6" finishingRank = 6 CASE "7" finishingRank = 7 CASE "8" finishingRank = 8 END SELECT
SELECT CASE startingColumnText$ CASE "A", "a" startingColumn = 1 CASE "B", "b" startingColumn = 2 CASE "C", "c" startingColumn = 3 CASE "D", "d" startingColumn = 4 CASE "E", "e" startingColumn = 5 CASE "F", "f" startingColumn = 6 CASE "G", "g" startingColumn = 7 CASE "H", "h" startingColumn = 8 END SELECT
SELECT CASE finishingColumnText$ CASE "A", "a" finishingColumn = 1 CASE "B", "b" finishingColumn = 2 CASE "C", "c" finishingColumn = 3 CASE "D", "d" finishingColumn = 4 CASE "E", "e" finishingColumn = 5 CASE "F", "f" finishingColumn = 6 CASE "G", "g" finishingColumn = 7 CASE "H", "h" finishingColumn = 8 END SELECT
The above code breaks up the Move$ into the above-mentioned four numbers and you would have noticed that the break up has two steps which we didn’t quite mention before: First we break up the text and then we ‘translate’ the four text values into numbers. This is done with the SELECT CASE commands, which essentially select different numeric value for each possible value of the columns and ranks. And yes, the text “8” needs to be translated to the number 8. As far as the computer is concerned they are completely different monsters altogether.
So now we have what we need. The starting column and rank and the finishing ones. How do we check the legality and validity of the move? Well, there is no “magic” way. We just have to write code to do that.
For clarity purposes we will gather all the code performing the check of the legality in one function (= set of code) which we will call ElegxosNomimotitas (= Check of Legality, in Greek). We will define the call parameters of the function (i.e. what parameters we need to pass over the function for it to do its job) and then write the code inside it.
What would be the input parameters?
The starting and end column and ranks of course. And we will also send the Moving Piece in a separate variable because this is a crucial part of the function. Different pieces move in a different way, right?
The function declaration would be something like…
DECLARE SUB ElegxosNomimotitas(ENSkakiera() AS STRING, startColumn AS INTEGER, startRank AS INTEGER, finishColumn AS INTEGER, finishRank AS INTEGER, MovingPieceEN AS STRING)
The ENSkakiera (=Elegxos Nomimotitas Skakiera = Check Legality Chessboard in Greek) is the array of the chessboard (= Skakiera in Greek) we will need to pass. The function will check the legality of a move not in general, but in the context of a specific chessboard of course. Then beyond the chessboard we pass over the start and end columns and ranks and the Moving piece as mentioned above.
Now we are in the function which checks the legality of the move. We will show how to do this for one piece, the rook. Then the logic is similar (not exactly, but you will get the meaning) for the other pieces.
Without further delay, here is the code…
IF (MovingPieceEN$ = "wrook" OR MovingPieceEN$ = "brook") THEN
IF debugMode = 1 THEN PRINT "Nomimotita = " + STR$(NomimotitaEN)
'Check correctness of move (Rook only moves in lines)
IF ((startColumn <> finishColumn) AND (startRank <> finishRank)) THEN NomimotitaEN = 0
IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-0"
'Check if the Rook moves beyond the limits of the chessboard
IF ((finishColumn < 1) OR (finishRank < 1)) THEN NomimotitaEN = 0
IF ((finishColumn > 8) OR (finishRank > 8)) THEN NomimotitaEN = 0
'Check if another piece is between the current and the target square
'Horizontal movement
IF (startColumn > finishColumn) AND (startRank = finishRank) THEN
FOR J = startColumn TO finishColumn STEP -1
IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0
NEXT J
END IF
IF (startColumn < finishColumn) AND (startRank = finishRank) THEN
FOR J = startColumn TO finishColumn
IF (J <> startColumn) AND (J <> finishColumn) AND ENSkakiera(J, startRank) <> "" THEN NomimotitaEN = 0
NEXT J
END IF
'Vertical movement
IF (startColumn = finishColumn) AND (startRank > finishRank) THEN
FOR J = startRank TO finishRank STEP -1
IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0
NEXT J
END IF
IF (startColumn = finishColumn) AND (startRank < finishRank) THEN
FOR J = startRank TO finishRank
IF (J <> startRank) AND (J <> finishRank) AND ENSkakiera(startColumn, J) <> "" THEN NomimotitaEN = 0
NEXT J
END IF
'If the start square is the same as the destination...
IF startColumn = finishColumn AND startRank = finishRank THEN NomimotitaEN = 0
'Check if a piece of the same colour is at the destination square
IF MID$(ENSkakiera$(finishColumn, finishRank), 1, 1) = MID$(ENSkakiera$(startColumn, startRank), 1, 1) THEN NomimotitaEN = 0
IF debugMode = 1 AND NomimotitaEN = 0 THEN PRINT "Checkpoint ROOK-5": 'INPUT a$
END IF
This code checks for many things:
If the rook moves in rows or columns
If the rook moved beyond the limits of the chessboard
If the rook is blocked by another piece before he reaches the destination square
If there is a piece of the same colour at the destination square.
If any of the above validations fail, then the Nomimotita (legality in Greek) variable is set to false (0). If not, the Nomimotita is 1 (= true). Note that we use an integer variable to indicate the Nomimotita (which takes values 0 or 1) instead of a text variable (which would take the values “True” or “False”) to use less memory. But we could anyway use a text variable with the same result.
Note: The “IF debugMode = 1” lines of code are used to print to the screen messages for debugging.
It may look complicated, but at the end it is not. The code is simple and self explanatory, with comments. Take for example the first validation: A rook must move in columns or ranks. How is this translated in the code?
IF ((startRank = finishRank) AND (startColumn <> finishColumn)) THEN NomimotitaEN = 0 IF ((startColumn = finishColumn) AND (startRank <> finishRank)) THEN NomimotitaEN = 0 IF ((startColumn <> finishColumn) AND (startRank <> finishRank)) THEN NomimotitaEN = 0
Read the code at your own pace.
At the end it is just… English. 🙂
After making sure that the move entered is valid, then all we have to do is… make it and present it to the screen.
'If move is legal, then do the move and present it in the chessbooard
IF Nomimotita = 1 THEN
IF debugMode = 1 THEN
PRINT "Now we will redraw the chessboard"
END IF
'Do the move
chessboard$(finishingColumn, finishingRank) = chessboard$(startingColumn, startingRank)
chessboard$(startingColumn, startingRank) = ""
CLS
CALL drawBoard
END IF
Go on and check the program source code (check at the end of the tutorial to find it), which contains all the other move validity checks for all the other pieces. You will find it pretty easy to read and understand. It contains comments within the code to support you in your lesson. Copy and paste the code in your QBasic interpreter/ compiler to see it and compile it.
III. Chess thinking algorithm
In the previous chapter we managed to create the function that checks the legality of a move. With that we managed to check the move entered by the user and present it to the screen.
What is next?
To make the computer think of an answer!
In essence this is easy! (the difficult part is to make the computer think of a really good move, that we will tackle later on)
What we will need besides the SUB which checks the legality of the move (ElegxosNomimotitas) is a SUB which counts the score of any given position in the chessboard. This will allow us to evaluate all the possible moves, so that the computer can select the best one.
This is done by the code below, which simply scans the chessboard for pieces and adds or subtracts the value of each piece it founds from the total score of the chessboard.
SUB countScore
positionScore = 0
FOR I = 1 TO 8
FOR J = 1 TO 8
IF chessboard$(I, J) = "wpawn" THEN positionScore = positionScore + 1
IF chessboard$(I, J) = "wrook" THEN positionScore = positionScore + 5
IF chessboard$(I, J) = "wknight" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wbishop" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wqueen" THEN positionScore = positionScore + 9
IF chessboard$(I, J) = "wking" THEN positionScore = positionScore + 100
IF chessboard$(I, J) = "bpawn" THEN positionScore = positionScore - 1
IF chessboard$(I, J) = "brook" THEN positionScore = positionScore - 5
IF chessboard$(I, J) = "bknight" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bbishop" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bqueen" THEN positionScore = positionScore - 9
IF chessboard$(I, J) = "bking" THEN positionScore = positionScore - 100
NEXT J
NEXT I
END SUB
Easy? Pretty much. All that is needed is a nested FOR loop (read in QB64 here how that works). Nothing more.
Now that we have that, let’s move on to the main course.
The ComputerMove SUB, which – you guessed right – makes the computer perform a move!
In essence, the steps needed are pretty simple:
Scan the chessboard.
If you find a piece of the computer, then…
Scan all possible moves of that piece to all squares of the chessboard.
For every possible move, check the legality of that move.
If the move is legal, then make it!
Check the score of the move.
If the score is best than the current best move (in the beginning there obviously no current best move), then this is the current best move!
After you have examined all the possible moves, do the current best move
Simple isn’t it?
How is the scanning of the chessboard and the checking of all possible moves performed? With four nested FOR loops.
Check the code below. It simple scans all the chessboard with the FOR loops of I and J and then, if it finds a piece which belongs to the computer, it scans all possible destination squares with the FOR loops of ii and jj.
How do we determine is the piece we found is one of the computer’s pieces? We compare the first letter of the piece (which would be ‘w’ or ‘b’ for white and black pieces) with the color of the player. If for example the color of the player is ‘w’ (for white) and we encounter a piece ‘brook’, then this is a piece of the computer since it is black – i.e. opposite than the color of the player.
'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)
'Check legality of the move entered
CALL ElegxosNomimotitas(chessboard$(), 0, startingColumn, startingRank, finishingColumn, finishingRank, MovingPiece$)
'If move is legal, then do the move and present it in the chessbooard
IF Nomimotita = 1 THEN
'Do the move
chessboard$(finishingColumn, finishingRank) = chessboard$(startingColumn, startingRank)
chessboard$(startingColumn, startingRank) = ""
'Count the score of the move
CALL countScore
'If the score is better than the existing best score, then this is the best move now (and the best score)
IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN
bestStartingRank = startingRank
bestStartingColumn = startingColumn
bestFinishingRank = finishingRank
bestFinishingColumn = finishingColumn
bestPositionScore = positionScore
END IF
END IF
'Undo the move
chessboard$(startingColumn, startingRank) = MovingPiece$
chessboard$(finishingColumn, finishingRank) = ProsorinoKommati$
NEXT jj
NEXT ii
END IF
NEXT J
NEXT I
If the move analyzed is legal (the ElegxosNomimotitas SUB is called to determine that) then the move is performed. The score of the position resulting after that is counted (the CountScore SUB is called for that). If the score is better than the current ‘best score’ (the initial best score is zero of course) then this move is registered as best move.
After the scanning is complete, we simply perform the best move!
'Do the best move found
chessboard$(bestFinishingColumn, bestFinishingRank) = chessboard$(bestStartingColumn, bestStartingRank)
chessboard$(bestStartingColumn, bestStartingRank) = ""
CLS
CALL drawBoard
Easy? Yes!
IV. Advanced concepts (Part 1)
The last chapters (Advanced concepts Part 1 and 2) will touch-base on some more advanced concepts in chess programming:
Thinking for more moves ahead in the game
Improving the position evaluation
Selecting the best move (miniMax concept introduction)
Up to now the program we have developed (see the previous lessons, where you can download the program) can think in one (1) move depth. This means that it simply (well, not ‘simply’ – we have gone a long way to make this happen) scans all the possible moves and then selects the one with the highest score.
This has just gave us an insight of the way a computer may think for chess, but a very limited one. The basic thing for thinking for chess is thinking in depth. Everybody would agree that thinking in more depth makes someone a better player.
How can we make that happen?
Simple!
We will copy-and-paste (sort of speak) the main computerMove SUB (Move depth 1 – Existing) two times more, so that the computer also thinks two moves more in depth. In essence, there will be two additional ‘thinking SUB-routines’: One which thinks of the potential human moves (Move depth 2) and another that thinks of the reactions of the computer to those moves (Move depth 3).
After that we will have the following structure:
DEPTH 1: computerMove: This routine thinks of the potential moves of the computer at the first level of thinking. If the thinkingDepth is not reached (i.e. if it is not set to 1, but e.g. 3) then the HumanMove1 SUB is called.
IF Move = thinkingDepth THEN
'If the score is better than the existing best score, then this is the best move now (and the best score)
IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN
bestStartingRank = startingRank
bestStartingColumn = startingColumn
bestFinishingRank = finishingRank
bestFinishingColumn = finishingColumn
bestPositionScore = positionScore
END IF
END IF
IF Move < thinkingDepth THEN CALL HumanMove1(chessboard$())
DEPTH 2: HumanMove1: This routine is scanning for all the possible answers of the human opponent. For each of those movements, the next thinking depth routine is called.
DEPTH 3: ComputerMove2: The last routine. Searches for possible moves at depth 3 (i.e. 3 half-moves). The move which ends up with the position with the best score at the end, is the one chosen.
IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN
bestStartingRank = startingRank
bestStartingColumn = startingColumn
bestFinishingRank = finishingRank
bestFinishingColumn = finishingColumn
bestPositionScore = positionScore
END IF
With these you will have the program think in depth of 3 half-moves (i.e. a move of the computer, a move of the human opponent and a last move by the computer).
We have been slowly progressing.
Yet, there is a lot more way to go…
V. Advanced concepts (Part 2): Improving the computer thinking with MiniMax
The algorithm described above is simple and does make the computer think in depth. When using the code below, you will see an obvious latency in computer’s thinking vis-a-vis the time needed by the previous version which thinks in depth of only 1 move.
When using the code however one can see that it does not make good moves! Simply by checking the score of the positions at the end, does not lead to wise decisions. The computer thinks, but not very well.
Yet.
What is needed for that to happen?
First improvement: Improvement of the position evaluation.
Now we are just counting the material in the final position.
SUB countScore
positionScore = 0
FOR I = 1 TO 8
FOR J = 1 TO 8
IF chessboard$(I, J) = "wpawn" THEN positionScore = positionScore + 1
IF chessboard$(I, J) = "wrook" THEN positionScore = positionScore + 5
IF chessboard$(I, J) = "wknight" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wbishop" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wqueen" THEN positionScore = positionScore + 9
IF chessboard$(I, J) = "wking" THEN positionScore = positionScore + 100
IF chessboard$(I, J) = "bpawn" THEN positionScore = positionScore - 1
IF chessboard$(I, J) = "brook" THEN positionScore = positionScore - 5
IF chessboard$(I, J) = "bknight" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bbishop" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bqueen" THEN positionScore = positionScore - 9
IF chessboard$(I, J) = "bking" THEN positionScore = positionScore - 100
NEXT J
NEXT I
END SUB
But material is not everything.
For example in the initial position all moves seem to result in the same material score, however it is known that in the chess opening the good player always moves hies pieces near the center of the chess board, avoid unnecessary movements of the king and the queen and avoids to move the same piece twice.
EXERCISE: Try to improve the countScore SUB to cater for the above. You might need to also introduce a new variable which will count the number of moves we are in the game, so that the computer knows if we are at the opening, the middle of the final stage of the game.
Second improvement: Apply the MiniMax algorithm
Improving the CountScore SUB does not solve our problems.
The thinking mechanism of the program we have desribed is inefficient. One could say that it is inherently flawed.
The program searches for the best score at the end of 3 half-moves, but does not cater at all for the fact that the human opponent moves (at move depth 2) will not be the ones which maximize the score for the computer, but the ones maximizing the score for the human opponent.
In other words: The variants (set of moves) which include completely stupid human opponent moves end up in high scores in favor of the computer and that is why, those variants will at the end be chosen.
But in real life the human opponent will never play his worst moves, but quite the opposite: He will play his best moves so as to win the computer!
The following example will better illustrate the problem.
Imagine we are at the following position…
Important note: The Huo Chess program was developed with simple text-like ‘graphics’. There is also a graphics-version based on Deep Basic chess program (by Thomas McBurney), which you can also download.
An initial version of Huo Chess which simply thought in terms of the best score at the end of 3-half-moves, would play… Qf7+ in this position.
But this is a bad move! Why does it play that?
Simple.
The computer assumes that at the next move human will play something stupid and then it will be able to capture the king of the opponent. The set of moves “1. Qf7+ [something stupid] 2. Qxe8” results in the best (highest) score for the computer, so this move is selected.
The algorithm did not even think that human after Qf7+ will simply play KxQf7 and take the queen, simply because this move results in low score for the computer.
But how do you take into account the best moves for the human opponent (MAXimize value) and at the same time the worst possible variants for the computer (MINImize value)? In other words, at the end, how can the computer play its best move taking into account the worst scenario, which we will have only if the human opponent plays his best move?
EXERCISE: Try to think of the above on your own, WITHOUT reading online about the MiniMax algorithm. First of all – who knows? – you might think of something better! Secondly, one only masters knowledge when he has tried on his own and failed to acquire it. Having things ready for you simply does not lead to wisdom.
The solution to the above problem is the MinMax algorithm. The current version of Huo Chess utilizes it, so you can read there how it works. However note that you can never learn anything by simply copying the program of someone else. Unless you write the program on your own, make mistakes, spend countless nights and days pondering upon them, you will never truly develop anything.
In the MinMax algorithm, we start from the lower level nodes and go up to the beginning of the tree, like in the schema that follows:
MinMax algorithm [Source: Wikipedia]
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 half-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. (source)
In simpler words: It is not enough to calculate the best end-score of a node! Because this might be the result of a combination of good computer moves and bad human moves. The human will not make stupid moves (or at least this will have to be our assumption). So in the level that the computer plays, we must maximize the score (the computer makes the best possible move), but in the levels the human opponent plays we must minimize the score of the computer (i.e. the human plays the best move for him, so the worst move for the computer).
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.
Make sure you check the relevant Huo Chess C# tutorials or the page in Codeproject which refer in more depth to the algorithm (which stays the same regardless of the programming language you use of course).
More updates coming soon!
Download Source Code
This section contains the source code of the Huo Chess QBasic application. Make sure to check here frequently for the latest updates.
Huo Chess source
The Huo Chess source code can be found below. Copy and paste the code in your QBasic interpreter/ compiler to see it and compile it.
One can also download a version with more elaborate graphics for the chessboard, where I have re-used the graphics from the Deep Chess program (by Thomas McBurney). Note that all the code is the same as the Huo Chess above, only the graphics are added – so if you need to study the engine the Huo Chess edition without these more elaborate graphics will perfectly fit your needs.
Important Note: For it to work, copy the PIECES.EGA file you will find in the Deep Chess site to the same folder as your program (this file contains the images of the pieces).
For historical purposes I have added previous versions of the code. You do not have to worry about those. Simply choose the latest one. Make sure you keep on coming to this page for updates of the code.
Important Notes
The “HUO Chess with graphics v0.6” needs a lot of memory for the logs so in some systems it may throw an Out of Memory exception. In those cases, please use the “Huo Chess v0.7” which has reduced memory needs instead.
Opening Book Editor
The latest versions (v0.6) of the code have an opening book functionality. In order to generate the files of the opening book you can use the Opening Book Editor found below.
Simply run the program, play the moves you want to store in the opening book and they will all be stored in separate txt files. These files must then be places in the same folder as the Huo Chess executable for the latter to utilize them.
Interested in chess programming? You are interested in philosophy too! What is thinking? Can AI be conscious? What does it mean to do something? Can the AI understand that it does play chess? Explore the AI related articles in Harmonia Philosophica and understand why you are already a philosopher!
Hello again!
After having published various tutorials on basic chess programming, it is time to move on to more advanced concepts.
Programming for kids – How to program a chess program in BASIC
This article will touch-base on some more advanced concepts in chess programming:
Thinking for more moves ahead in the game
Improving the position evaluation
Selecting the best move (miniMax concept introduction)
Up to now the program we have developed (see the previous lessons, where you can download the program) can think in one (1) move depth. This means that it simply (well, not ‘simply’ – we have gone a long way to make this happen) scans all the possible moves and then selects the one with the highest score.
This has just gave us an insight of the way a computer may think for chess, but a very limited one. The basic thing for thinking for chess is thinking in depth. Everybody would agree that thinking in more depth makes someone a better player.
How can we make that happen?
Simple!
We will copy-and-paste (sort of speak) the main computerMove SUB (Move depth 1 – Existing) two times more, so that the computer also thinks two moves more in depth. In essence, there will be two additional ‘thinking SUB-routines’: One which thinks of the potential human moves (Move depth 2) and another that thinks of the reactions of the computer to those moves (Move depth 3).
After that we will have the following structure:
DEPTH 1: computerMove: This routine thinks of the potential moves of the computer at the first level of thinking. If the thinkingDepth is not reached (i.e. if it is not set to 1, but e.g. 3) then the HumanMove1 SUB is called.
IF Move = thinkingDepth THEN
'If the score is better than the existing best score, then this is the best move now (and the best score)
IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN
bestStartingRank = startingRank
bestStartingColumn = startingColumn
bestFinishingRank = finishingRank
bestFinishingColumn = finishingColumn
bestPositionScore = positionScore
END IF
END IF
IF Move < thinkingDepth THEN CALL HumanMove1(chessboard$())
DEPTH 2: HumanMove1: This routine is scanning for all the possible answers of the human opponent. For each of those movements, the next thinking depth routine is called.
DEPTH 3: ComputerMove2: The last routine. Searches for possible moves at depth 3 (i.e. 3 half-moves). The move which ends up with the position with the best score at the end, is the one chosen.
IF ((playerColor$ = "b" AND positionScore >= bestPositionScore) OR (playerColor$ = "w" AND positionScore <= bestPositionScore)) THEN
bestStartingRank = startingRank
bestStartingColumn = startingColumn
bestFinishingRank = finishingRank
bestFinishingColumn = finishingColumn
bestPositionScore = positionScore
END IF
With these you will have the program think in depth of 3 half-moves (i.e. a move of the computer, a move of the human opponent and a last move by the computer).
You can download the program below.
Download Source Code
Simply copy and paste the code in your QBasic editor and try it out!
One can also download a graphics version, where I have added the graphics engine by Deep Chess (by Thomas McBurney).
Important: For it to work, copy the PIECES.EGA file you will find in the Deep Chess site to the same folder as your program (this file contains the images of the pieces).
Make sure you keep on coming to this page for updates of the code.
Opening Book Editor
The latest versions (v0.6) of the code have an opening book functionality. In order to generate the files of the opening book you can use the Opening Book Editor found below.
Simply run the program, play the moves you want to store in the opening book and they will all be stored in separate txt files. These files must then be places in the same folder as the Huo Chess executable for the latter to utilize them.
As with Huo Chess, make sure you visit this page again to check for any updates or improvements in the code!
Advanced concepts: Improving the computer thinking
The algorithm described above is simple and does make the computer think in depth. When using the code below, you will see an obvious latency in computer’s thinking vis-a-vis the time needed by the previous version which thinks in depth of only 1 move.
However it does not make good moves!
What is needed for that to happen?
First improvement: Improvement of the position evaluation.
Now we are just counting the material in the final position.
SUB countScore
positionScore = 0
FOR I = 1 TO 8
FOR J = 1 TO 8
IF chessboard$(I, J) = "wpawn" THEN positionScore = positionScore + 1
IF chessboard$(I, J) = "wrook" THEN positionScore = positionScore + 5
IF chessboard$(I, J) = "wknight" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wbishop" THEN positionScore = positionScore + 3
IF chessboard$(I, J) = "wqueen" THEN positionScore = positionScore + 9
IF chessboard$(I, J) = "wking" THEN positionScore = positionScore + 100
IF chessboard$(I, J) = "bpawn" THEN positionScore = positionScore - 1
IF chessboard$(I, J) = "brook" THEN positionScore = positionScore - 5
IF chessboard$(I, J) = "bknight" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bbishop" THEN positionScore = positionScore - 3
IF chessboard$(I, J) = "bqueen" THEN positionScore = positionScore - 9
IF chessboard$(I, J) = "bking" THEN positionScore = positionScore - 100
NEXT J
NEXT I
END SUB
But material is not everything.
For example in the initial position all moves seem to result in the same material score, however it is known that in the chess opening the good player always moves hies pieces near the center of the chess board, avoid unnecessary movements of the king and the queen and avoids to move the same piece twice.
Make sure to check the latest version of Huo Chess uploaded, to see how qualitative criteria were added in the countScore SUB!
EXERCISE: Try to improve the countScore SUB to cater for the above. You might need to also introduce a new variable which will count the number of moves we are in the game, so that the computer knows if we are at the opening, the middle of the final stage of the game.
Second improvement: Apply the MiniMax algorithm
The thinking mechanism of the program we have desribed is inefficient. One could say that it is inherently flawed.
The program searches for the best score at the end of 3 half-moves, but does not cater at all for the fact that the human opponent moves (at move depth 2) will not be the ones which maximize the score for the computer, but the ones maximizing the score for the human opponent.
In other words: The variants (set of moves) which include completely stupid human opponent moves end up in high scores in favor of the computer and that is why, those variants will at the end be chosen.
But in real life the human opponent will never play his worst moves, but quite the opposite: He will play his best moves so as to win the computer!
The following example will better illustrate the problem.
Imagine we are at the following position…
Important note: The Huo Chess program was developed with simple text-like ‘graphics’. There is also a graphics-version based on Deep Basic chess program (by Thomas McBurney), which you can also download.
An initial version of Huo Chess which simply thought in terms of the best score at the end of 3-half-moves, would play… Qf7+ in this position.
But this is a bad move! Why does it play that?
Simple.
The computer assumes that at the next move human will play something stupid and then it will be able to capture the king of the opponent. The set of moves “1. Qf7+ [something stupid] 2. Qxe8” results in the best (highest) score for the computer, so this move is selected.
The algorithm did not even think that human after Qf7+ will simply play KxQf7 and take the queen, simply because this move results in low score for the computer.
But how do you take into account the best moves for the human opponent (MAXimize value) and at the same time the worst possible variants for the computer (MINImize value)? In other words, at the end, how can the computer play its best move taking into account the worst scenario, which we will have only if the human opponent plays his best move?
EXERCISE: Try to think of the above on your own, WITHOUT reading online about the MiniMax algorithm. First of all – who knows? – you might think of something better! Secondly, one only masters knowledge when he has tried on his own and failed to acquire it. Having things ready for you simply does not lead to wisdom.
The solution to the above problem is the MinMax algorithm. The current version of Huo Chess utilizes it, so you can read there how it works. However note that you can never learn anything by simply copying the program of someone else. Unless you write the program on your own, make mistakes, spend countless nights and days pondering upon them, you will never truly develop anything.
Make sure you check the relevant Huo Chess C# tutorials which refer in more depth to the algorithm (which stays the same regardless of the programming language you use of course).
Interested in chess programming? You are interested in philosophy too! What is thinking? Can AI be conscious? What does it mean to do something? Can the AI understand that it does play chess? Explore the AI related articles in Harmonia Philosophica and understand why you are already a philosopher!
Introduction
Coding is easy.
Today there are a lot of people learning how to do it.
Why not you?
And you know what is the most difficult step in learning how to code?
TO START LEARNING.
You know there is an old Buddhist saying claiming that “When the student wants, the teacher appears”. So the question is not whether there are tutorials out there to teach you. There are a lot. Here or elsewhere, you can easily find articles showing how to code.
The question is: Are you willing enough?
(And yes, Harmonia Philosophica is mainly a philosophy portal, so feel free to read about philosophy while trying to debug your first chess program)
For this ultra quick training I will use a Java edition of my Huo Chess program. This edition lacks basic functionalities like deep searching, but it can however play chess according to the rules and choose the best move at the current position based on which move earns the most material.
Places to download Huo Chess (source code and executable)
(A journey of a thousand miles begins with a single step)
~ Lao Tzu, Tao Te Ching
Step 1: Get a programming interface
This tutorial will show you how to code a demo chess program in one day, even without any prior knowledge of programming. All you need is a programming interface to write and compile (i.e. make an executable program out of your code) the code that you will write. These are also known as Programming IDEs (Integrated Development Interfaces). This could be the Microsoft Visual Studio (the Express edition of which can be downloaded for free) for C# or any Java compiling studio available out there (like NetBeans for example, which again can be downloaded for free).
The tutorial will not cover the details on how to use these programming interfaces. But this is not something hard to learn anyway. Just go to the web (or the page of the tool itself) and you will gain an understanding on how to write a small console program (this is what we are going to do here) in less than an hour. When I refer to a console program I mean a program which does not have graphics but only displays text. We will start with building such a program since writing code for graphics will surely need an additional effort to learn how to do it. And it will be easy to later on add graphics to your program, once you have the AI logic of the chess engine up and ready, don’t you think?
Open the IDE and select to create a new project…Select to create a simple application…Your program is created. All you have to do is add the code…
Tools to use for coding your program
Microsoft Visual Studio (free edition)
Java NetBeans
After you download the IDE, install it in your computer and go to the option New Project. Select to create a simple C# console application (in Visual Studio) or a simple Java program (in NetBeans). Click Create and there you are. You have the shell in which you will add your chess program code!
Step 2: Design the chess program structure
Let’s go into the chess program now.
But wait!
Don’t we need to learn the programming language first?
The answer is simple: NO!
You will learn them as you go.
This is how I (and many others) learned programming in the first place. I opened my Commodore computer and started typing my first program by copying the code from the manual. After I typed it in and spent time to get it right (even copying can be difficult, especially if you are a rookie) I typed RUN and I had my first game! Forget the long chapters of books trying to teach you – after reading 100 pages – how to just print “Hello world” on a screen. Programming is for people who like experimenting and are not afraid to simply start trying things on their machine.
So just go ahead!
You will read here about the basic structure needed for the program, and then you will see the commands required to code that structure into a C# or Java program. The commands are fairly simple and you will understand what they do as you write the program. Do you really need a programming language manual to understand what an “if” command does anyway?
The main structure of the program is depicted in the following schema.
Fairly simple isn’t it?
The story goes like this…
You get input from the user for his move. [EnterMove function]
You check the legality and the validity of the move entered [ElegxosNomimotitas and ElegxosOrthotitas functions, which also utilize the CheckForWhiteCheck and CheckForBlackCheck functions to check if there is a check in the position]
If the move is legal and valid, then do the move. [call drawPosition function to redraw the chessboard; note that the Java edition of the program only prints the chessboard in text]
Exercise for you: Add graphics to the application. (use the C# edition ot get some insight on how you could do that)
Call the function which makes the computer think. [ComputerMove function]
Scan the chessboard to find all the pieces of the computer. In the sample code provided for Java, this means that it scans for all the black pieces since the program is made only for the computer to play with black.
Exercise for you: Add the ability for the program to play with white as well)
For each piece of the computer, check all possible moves to all possible squares of the chessboard.
If you find a valid move (by invoking the ElegxosNomimotitas and ElegxosOrthotitas functions) then do the move and count the score of the position. [CountScore function: This is one of the most central functions of the program; changing it makes the computer play differently according to the values you assign to pieces or to elements of the chessboard like empty ranks, concentration of the pieces at the center et cetera]
If the score of the move is better than the so far better score, then store this position as the best one. (Note: The program stores the first position analyzed as ‘best’ anyway, so that there is a starting point for the best score)
Exercise for you: Change the values in the CountScore function to improve the playing abilities of the computer)
Do the best move found and redraw the chessboard.
Wait for next user input. [call EnterMove function again]
The Java edition of the program does not think in more depth. It just finds the move which earns the more material and makes it. This is not chess isn’t it? Well actually it is. The basis for a good chess program. All you have to do is improve it.
Look at the C# version of “Huo Chess” (search the web for it, there are many repositories where I have uploaded the code, including MSDN Library, CodePlex and Codeproject) to gain a small insight on how the chess program can search into more depth.
Exercise for you: Make the Java edition of the program to think in more depths, by adding more “ComputerMove”-like functions to analyze the next potential moves for the human and the computer. Be careful how you pass over the chessboard between these functions. (yes, Google will be your best friend)
This last section contains the source code of the chess program in Java.
As mentioned above, look for “C# Huo Chess” in the web (See the Recourse listed above) to see the full source code of that Huo Chess edition. This code is also heavily commented to make it easy to read and re-use, while the names of the functions are the same as in the Java edition of the program.
Look also at the “How to program a chess program for Beginners” series here in Harmonia Philosophica, to get some more details on the Huo Chess program. (the tools used in those articles are a bit outdated, but yet the logic is still the same)
Paste that code into the main java file in your NetBeans project and compile it.
Execute your program and enjoy your new chess game.
Epilogue
So there it is. Depending on your copy-paste and reading comprehension skills, you now have a working chess program on your hands and some knowledge on how it could be improved. Everything is up to you now.