Huo Philosopher is a tiny open source program for Commodore. With just 10 lines of code, it is able to conduct clever conversations about philosophy with deep meaning…
There is a weird but very interesting programming contest happening every year.
It is the BASIC 10Liners contest, where contestants are asked to create programs in BASIC with just 10 lines of code!
You would be amazed on what things can be done with just ten (10) lines of code.
There are three categories for programming a game depending on the length of each line (80, 120 or 256 characters) and an additional fourth category (SCHAU) for programming an application in 10 lines. (check here for the rules of the BASIC 10Liners contest of 2021)
The program HUOPHIL1 (Huo Philosopher v2.0) is a tiny program by Spyridon Kakos that can make deep philosophical conversations about any available subject. Its deep irrational understanding of the cosmos is based on nothing more than sets of random phrases the program brilliantly combines in order to produce phrases that will make any philosopher shiver from the sheer terror of its non-knowledge of metaphysics.
How the program works
The program uses three sets of arrays that contain…
An initial phrase. (Table X$)
A middle phrase: This is the more complex one and uses three arrays that hold the start, the middle and the ending of the second phrase. (Tables Y$ + Z$ + W$)
An ending phrase. (Table E$)
The program initially initializes the values in the tables and asks for user input. Then it generates random numbers and combines elements from the tables mentioned above to generate the three phrases. A delay between the phrases as they appear on the screen add to the mystery and the tension…
One can download the program code and the relative documentation from the official entry page for the BASIC 10Liners 2021 here.
Alternatively, one can download the source code of the program and the relative documentation below.
Please contact us for any comments and/ or suggestions.
Appendix I – The source code
The source code is presented below.
10DIMZ$(17):DIMW$(18):DIML$(10):B=1:PRINTCHR$(147):PRINT"HUO PHILOSOPHER V2.0 BY S.KAKOS (2021)":PRINT:INPUT"ACTIVATE NEURAL LEARNING? (Y/N)";N$:PRINT:PRINT"COME, SAY SOMETHING":INPUTA$:X$(1)="INTERESTING, BUT...":X$(2)="YOU NEVER KNOW. YOU SEE..."
20X$(3)="WHY?":X$(6)="SO?":X$(4)="THINK WITHOUT THINKING":X$(5)="ANALYSIS DESTROYS THOUGHT":Y$(1)="GOD":Y$(2)="BEING":Y$(3)="EXISTENCE":Y$(4)="LIFE":Y$(5)="SELF":Y$(6)="DEATH":Y$(7)="REALITY":Y$(8)="CHANGE":Y$(9)="THE UNIVERSE":Y$(10)="KNOWLEDGE"
30Z$(1)=" DEFINES ":Z$(2)=" CREATES ":Z$(3)=" SUSTAINS ":Z$(4)=" TRANSCENDS ":Z$(5)=" DESTROYS ":Z$(6)=" ALLOWS ":Z$(7)=" MANIFESTS THROUGH ":Z$(8)=" OBSCURES ":Z$(9)=" AFFECTS ":Z$(10)=" CONTAINS ":Z$(12)=" SUPPORTS ":Z$(13)=" STEMS FROM "
40Z$(11)=" IS ":Z$(14)=" PRODUCES ":Z$(15)=" LEADS TO ":Z$(16)=" BREEDS ":Z$(17)=" NEEDS ":W$(1)="EXISTENCE":W$(2)="GOD":W$(3)="LIFE":W$(4)="THE SELF":W$(5)="BEING":W$(6)="OTHERS":W$(7)="DEATH":W$(8)="REALITY":W$(9)="THE COSMOS":W$(10)="CHANGE"
50W$(11)="PERCEPTION":W$(12)="NOTHINGNESS":W$(13)="TRUTH":W$(14)="ONE":W$(15)="FAITH":W$(16)="HUMANS":W$(17)="MEMORY":W$(18)="FAITH":E$(1)="LOGIC IS IRRATIONAL":E$(2)="STOP THINKING...":E$(3)="FEEL THE ABYSS...":E$(4)="BEING IS ME..."
60E$(5)="CLOSE YOUR EYES TO SEE":E$(6)="DO YOU SEE?":E$(7)="I ONLY KNOW WHAT I KNOW":E$(8)="ALL IS ONE":X=RND(-TI):X=INT(6*RND(1))+1:Y=INT(10*RND(1))+1:Z=INT(17*RND(1))+1:W=INT(18*RND(1))+1:E=INT(8*RND(1))+1
65FOR I=1 TO B:IFL$(I)=STR$(X)+STR$(Y)+STR$(Z)+STR$(W)+STR$(E) THEN GOTO 60:NEXTI
70PRINT:PRINTX$(X):FORI=1TO2000:NEXTI:PRINTY$(Y)+Z$(Z)+W$(W):FORI=1TO2000:NEXTI:PRINTE$(E):PRINT:IFN$="Y" THEN INPUT"WAS THAT ANSWER SATISFACTORY (Y/N)";V$:IFV$="N" THEN L$(B)=STR$(X)+STR$(Y)+STR$(Z)+STR$(W)+STR$(E):PRINT "COMBINATION TO CANCEL:"+L$(B):B=B+1
80IF B>10 THEN B=10
90PRINT:INPUT"TELL ME MORE (Q TO EXIT)";A$:IFA$<>"Q"THENGOTO60
The code is free for someone to reuse it, as long as the source is properly mentioned.
What is common between programming and philosophy?
Well, at first glance… nothing!
Yet, if one scratches below the surface he or she may find some peculiar correlations.
People like philosophy.
Because they like to ask questions and seek their answers. Because they are interested in the major questions of humankind and would like to reach that holy grail we seek since we were born: Truth.
People like programming.
Because they like to create things that work. They like it because it enables them to bring life to their ideas and to an extent, even touch the idea of life itself via artificial intelligence and neural networks.
In both cases the most primitive of instincts are the cause of our actions.
Instincts that make us “do things”.
Instincts that make us “create things”.
Instincts that make us ask and then answer. And with every knew answer, seek ways to ask new questions and improve the answers even more.
That was since the dawn of civilization our best quality.
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).
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).   .
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 .
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)  
WinForms C# NET application for the Huo Chess GUI application (DO NOT select the .NET Framework console application, this is the old framework) 
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…
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]  .
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!
2021-02-14: Updated phrases the AI uses. Added more comments to make the code more readable and easier to configure new phrases.
The goal of Huo Writer is to be a program that thinks philosophically. By getting user input on a specific topic, it can generate phrases with deep philosphical meaning so as to trigger thoughts on the human user.
The goal of the article is to serve as a simple tutorial on how to build a program that can have a conversation with a human, for people with limited or no programming skills.
An Appendix describes how the program can be enhanced with neural network capabilities, by showing a totally primitive way of helping the program improve its responses based on human feedback.
Go directly at the end to get the code of the program.
It is easy in the sense that all you have to do in order to do it, is… do it! As in all things. There is no magic words to use, no secret key, no hidden doors to unlock. Simply open your computer and start programming. As simple as getting up in the morning and making coffee.
Of course, you must know how to make coffee.
That is the difficult part of programming. But do not worry. As in all other programming tutorials in our portal, we will try to keep it simple.
First of all, we will use the simplest high-level language for our tutorial, i.e. QBasic (and in particular, the 64-bit version which can run in any modern Operating System, QB64). BASIC is, as the name implies, basic. Very easy to learn. There are tons of resources in the Internet on the language; be sure to search for QB64 (QBasic 64 bit) mainly, so as to make sure you search for the right thing.
Secondly, the program itself is ultra-simple. The code is based on a very limited set of commands (mainly PRINT, IF, CASE, INPUT, RANDOMIZE) which you can easily learn. And even if you don’t you are able to understand what they do by reading this article!
Yet and despite the above, the actual result is very good! The program actually does sound like a philosopher and writes deep stochastic phrases which will trouble you and invoke thoughts.
Look at the text below…
Never do faith supports us. Would faith exist without you? Ignorant men. Others create reality. Don’t you remember? Stop thinking. And you will see…
~ HUO Writer, 2020-09-01
It was written by the program when discussing about the tags faith, helping, problems. Taking into account how simple and ultra-light the program is, it is really good! Don’t you agree? (Note the small gramatical errors, these are still part of the problems still to be solved)
Is it Artificial Intelligence though?
Well, surely it wasn’t created on its own, so yes it is artificial. And it does include some very basic rules to randomly generate what it says. Last but not least, the result seems like it is intelligent, so that is the greatest argument in favor of answering yes to this question. After all, how to I know that you are not robot?
I. How the program works
The program works in the following simple steps:
Ask input from the user: The program needs from the user to enter some tags related to topic of discussion. For each tag, the gender (male, female, neutral, adjective, indifferent) and the number (plural, single, indifferent) must be defined. Note that some of the values are not exactly ‘correct’, for example the ‘adjective’ is not a gender. The values entered are then used by the program to properly formulate the phrases it will generate to speak with the human.
Generate the phrases to say, by not-fully randomly combining the tags provided by the user with specific words and phrases in the database of the program.
Well, it is!
The most difficult part is to enter meaningful and cleverly selected words and phrases in the database so that the phrases generated by the program can sound as philosophical and meaningful. As in any other thing, the ‘Garbage in-Garbage out’ principle stands strong.
II. Step 1: Get user input
Getting user input is as simple as using the… INPUT command in QBasic and ask from the user the input.
Just see the code below on how the program asks from that input.
PRINT "What is our theme of discussion to-day?"
INPUT "Number of tags: ", tagsNo
PRINT "Thank you"
PRINT "": PRINT "Now…": PRINT ""
PRINT "Please enter related tags one by one…"
PRINT "One word only per tag please. All in small letters."
PRINT "Enter Bye or just press Enter to exit."
'Read related tags for the subject of discussion
FOR I = 1 TO tagsNo
INPUT "Enter Tag: ", Tags$(I, 1)
IF Tags$(I, 1) = "Bye" OR Tags$(I, 1) = "" THEN END
INPUT "ENTER THE TAG'S GENDER (m, f, n, a, i) : ", Tags$(I, 2)
IF Tags$(I, 2) <> "m" AND Tags$(I, 2) <> "f" AND Tags$(I, 2) <> "n" AND Tags$(I, 2) <> "a" AND Tags$(I, 2) <> "i" THEN GOTO TagGender
INPUT "ENTER THE NUMBER OF THE TAG (s, p, i) : ", Tags$(I, 3)
IF Tags$(I, 3) <> "s" AND Tags$(I, 3) <> "p" AND Tags$(I, 3) <> "i" THEN GOTO TagNumber
Initially the program asks for the number of the tags to be entered and then, for each tag (hence the FOR… NEXT loop), the user is asked to enter the parameters (gender, number) of the tag.
As you can see, all the tags entered as placed inside the Tags$ table. This table will be then used to generate the phrases.
The tag itself is stored in dimension 1 of the table, while the parameters of the tag are stored in the dimensions 2 and 3 of the table.
Tags table dimentions
Dimension 1: The tag itself
Dimension 2: This stores the gender
Dimension 3: This stores the number
These parameters will be used later on in validation rules necessary for the correct creation of the phrases.
III. Step 2: Generating the phrases
Based on the input of the user, the program combines the tags with specific phrases or words in the database of the program.
The program generates the following phrases:
Phrase H.1: The first phrase, combining phrases from tables H1$, H2$, one of the tags and a phrase from table H3$.
Phrase H.2: The second phrase, combining a phrase from table H4$, one of the tags and a phrase from table H5$.
Intermediate phrase 1: A connecting phrase, which includes a phrase from table I1$.
Phrase K: The third phrase, combining phrases from tables K1$, K2$ and K3$.
Intermediate phrase 2: A connecting phrase, which includes a phrase from table I2$.
Terminating phrase: The closing phrase, which includes a phrase from table T$.
As mentioned, the elements used for each phrase as documented in the program’s database. By ‘database’ we do not refer to a relational database, but to tables (e.g. tables H1$, H2$, H3$ used for the first phrase) which are populated with data with the code of the program.
As you can see, as with tags, dimensions 2 and 3 are used to store the gender and the number of the elements.
The tables documented above are for the creation of the K Phrase (i.e. the third phrase). The program randomly selects an element from each table and finally creates the phrase to show to the use.
The phrases are generated, by generating random number and then using these numbers to get the relevant entries from the tables defined above.
An example of the code used to get random numbers and create the phrases (the example is from Phrase K) is depicted below.
'Generate third phrase
A = INT(RND * 9) + 1: B = INT(RND * 7) + 1: C = INT(RND * 9) + 1
IF C = A THEN GOTO PhraseK
'If number is not equal (plural with plural, single with single) or the number of the next element is not indifferent, then generate phrase again
IF K1$(A, 3) <> K2$(B, 3) AND K2$(B, 3) <> "i" THEN GOTO PhraseK
As said before, the code is simple. In most cases it is. It is the idea that could be complex either in percieving it, implementing it or both. (or selling it I would say, but that is part of another bigger discussion)
Phrases generation rules
There are some basic validation rules applied for the phrases generation. As the program progresses, these rules will be amended and improved.
One rule for example is the following: the number of an element must match with the number of the tag combined with that element. The code below does exactly that thing: If the number (i.e. the 3rd dimension) of the first and the second element do not match, then the program is instructed to go back and generate the phrase again.
IF K1$(A, 3) <> K2$(B, 3) AND K2$(B, 3) <> "i" THEN GOTO PhraseK
If the validation fails, then the program generates a new phrase.
Printing the phrase
After the phrases are generated, they are printied on the screen. With what else than the… PRINT command.
A philospher at your own hands!
APPENDIX I – Neural Network
Neural networks are all about having a program learn from its mistakes. Usually this happens with feedback from its user, while the most advanced programs have the ability to learn also on their own. I attempted to start implementing a primitive type of neural network capability.
If the user activates the Learning Mode, the program asks for input after each phrase it produces. If the input is negative (i.e. the user says that he did not like the phrase generated) then the program stores the combination in a table storing ‘bad’ combinations with the code below.
PRINT "": PRINT "Was this sentence a good one? (y/n)"
e$ = ""
hyn$ = INKEY$
LOOP WHILE hyn$ = ""
SELECT CASE hyn$
CASE "y", "Y"
e$ = ""
CASE "n", "N"
BadCombinationsK(Kcounter, 1) = A
BadCombinationsK(Kcounter, 2) = B
BadCombinationsK(Kcounter, 3) = C
e$ = "A"
LOOP WHILE e$ <> ""
PRINT "Thank you for your input.": PRINT ""
The next time the program speaks with the user, the bad combinations are not used in the phrase generation. In that sense, the program learns from the human input. One can visualize the nodes and their combinations are human brain neurons – the neurons which are not used often are gradually disabled while the neurons which are used often are strengthened. Now the program only has the capability to totally ‘delete’ one set of nodes from the possible responses, but future enhancements could see it behave in a more elaborate way.
An example of the code doing that is depicted below.
'Neural network: Check if the combination selected was discarded by human previously. If yes, generate a different one!
FOR I = 1 TO Kcounter
IF BadCombinationsK(I, 1) = A AND BadCombinationsK(I, 2) = B AND BadCombinationsK(I, 3) = C THEN GOTO PhraseK
As mentioned above, this is the simplest form of a neural network: The program ‘learns’ from human interaction and adjusts the ‘nodes’ (elements used for the phrases) inside its ‘brain’ (tables holding the elements used for the phrases) accordingly.
Note that this works only inside the same instance of the program. Whenever you restart the program the ‘bad nodes’ are forgotten, since they are not stored permanently anywhere.
Improvements that are coming soon
Make the learning not only disable nodes (0 or 1), but also decrease the likelihood of a node being used (with probability values between 0 and 1).
Store what the program has learned into a txt file, so that the next time you execute it, it still ‘remembers’ what it has learnt.
APPENDIX II – The source code
You can click at the link below to get the source code.
Simply copy-paste it into a QBasic editor and execute.
APPENDIX III – How to configure the program
The program is easy to configure. And that is why it is so fun! I have added phrases which are related to my personality and the way I am thinking. You can alter them to reflect yours!
You can also add new elements for the phrases! Simple go and add new elements in the relative tables. When doing that, rememeber to also define the gender and number of the element.
After having added the new element, do not forget to increase the relative constant which defines the size of the table! The constants defining the size of the elements’ tables can be found in the beginning of the program.
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?
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
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
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!
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.
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
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?
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).