Free Blogging Advice (FBA) – Episode 3: Develop your story.

Advertisements

FBA Episodes

Now that we have decided to start writing (see previous episodes), we need to develop the story of our site.

Story: The narrative that describes the intent of your blog. The story will explain to the visitor why he or she is here, what they should expect to read and what the blog will offer them.

You need to publish the story in your About page. In that way you will establish the identity of your site for anyone to see.

But what should a story look like? First of all it needs to be simple. If you do not have it clear in your head then your readers will be confused as well (and most probably will not come back to you site).

Secondly, it needs to be emotional. Emotions is what drive the world around and you need to invest in the emotions of your readers to capture their interest.

Last but not least, your story needs to be a… story! What I mean by this is that you need to convey your message to your readers through an actual story, i.e. an anecdote, a tale that will have a hero, a problem that her or she needs to overcome, a climax and a resolution. This is easier said than done. But you need the story element in order to reach to your readers with a compelling and attractive way. Just stating what your site is about is not enough. If you just just wrote down the goal of your site like a corporate statement then it would look like a… corporate statement. You need more than that to engage with the visitor of your blog.

Stories captivated us when we were children. And still do. Everyone likes a good story. It is more probable to remember something that you heard in a story than something you just read.

As an example you can read the story of Harmonia Philosophica here. It is a short one, as a story for a site must be. And it tries to convey the message of this site, i.e. that being irrational and non-thinking is the best way to think.

Whether you like it or not is another story…

To be continued…

Free Blogging Advice (FBA) – Episode 2: What to write about…

Advertisements
Writing is so easy. Writing is so hard…

Free Blogging Advice: Writing is hard. And easy. The goal of the Free Blogging Advice (FBA) series of short articles is to provide some free advice on… blogging! All you have to add is some time and effort. And love. Lots of love.

FBA Episodes

FBA Episode 2: What to write about

So you made the decision to start writing.

The world is split in two categories of people: Creators and consumers.

You chose to be the first. Good for you!

But now that you did, there comes the first big decision that you must make: What to write about?

There exist millions and millions of possible things that can be the subject of a good blog/ site. From philosophy to cooking, from military aviation up to jokes for atheism and religion. How do you choose?

The answer: You do not!

If you already have made up your mind to write (see Episode 1), it is most probable (almost certain actually) that you have already made that decision without knowing it!

Wanting to write is always accompanied by the urge to write about something specific. Do not try to analyze what will have the greatest potential for more readers, or what is more viral these days. Don’t lose time trying to figure out what subject is the most promising when it comes to attracting viewers in your site and do not spend time thinking what subject would be more amazing to show to your fiancé (or fiancée).

Creating content is all about you!

And your heart already knows what it loves.

Just stop thinking and listen to your self.

(I know what I like…)

This is your subject!

No matter how weird or niche this subject might be, the basic advantage is that it is what you like! And this makes it not only an excellent choice but also the only choice at hand! You can only sustain writing about what you really love. Anything else is just work. But with blogging you want to enjoy yourself! And what better way to do that than by writing about things you enjoy writing about? (Yes, this is a tautology and that is why it is true – read more Harmonia Philosophica about this)

And who knows…

You passion for what you love might one day convert that small blog into a multi-million dollar business.

(Although I would never recommend that, but we will speak more on that in another episode)

Free Blogging Advice (FBA) – Episode 1: The beginning…

Advertisements
Writing is so easy. Writing is so hard…

Free Blogging Advice: Writing is hard. And easy. The goal of the Free Blogging Advice (FBA) series of short articles is to provide some free advice on… blogging! All you have to add is some time and effort. And love. Lots of love.

FBA Episode 1: The beginning

How does every journey starts but with a first step? And how important that first step is cannot be exaggerated enough. Whether you do it or not will determine whether you will be called a writer or not. Whether or not you take it will determine if you will be a creator instead of just a consumer of creations.

So before everything else, one should do the obvious: Start writing!

It is as easy as it sounds. And exactly because of that, it is so difficult!

Many people dream of writing but never do. There exist a ton of excuses not to. It takes courage to overcome that first hurdle and doing so is solely on you. There is no magic pill, no magic recipe, no magic advice. If you cannot just open your computer and start writing then this series of articles is not for you. If you cannot open Word or any other writing application and start producing content then there is no need to discuss advice in good blogging and writing.

So that’s it.

If you have already started writing and you have content already created then you have successfully passed the first stage for successful blogging.

If not, then do so immediately.

Next FBA episode: Decide what to write about!

HUO Writer: A simple AI writer with basic Neural Network capabilities (QB64)

Advertisements

News

  • 2021-02-14: Updated phrases the AI uses. Added more comments to make the code more readable and easier to configure new phrases.

Goal

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.

Go directly at the end to get the code of the program.

Other programming tutorials

Introduction

Programming is easy. And difficult.

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!

Huo Writer on faith, problems, helping…

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:

  1. 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.
  2. 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.

Simple huh?

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?"
PRINT ""
INPUT "Number of tags: ", tagsNo
PRINT "Thank you"
SLEEP 2
PRINT "": PRINT "Now…": PRINT ""
SLEEP 2
PRINT "Please enter related tags one by one…"
SLEEP 2
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

PRINT ""
INPUT "Enter Tag: ", Tags$(I, 1)
IF Tags$(I, 1) = "Bye" OR Tags$(I, 1) = "" THEN END

TagGender:
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

TagNumber:
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

NEXT I

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:

  1. Phrase H.1: The first phrase, combining phrases from tables H1$, H2$, one of the tags and a phrase from table H3$.
  2. Phrase H.2: The second phrase, combining a phrase from table H4$, one of the tags and a phrase from table H5$.
  3. Intermediate phrase 1: A connecting phrase, which includes a phrase from table I1$.
  4. Phrase K: The third phrase, combining phrases from tables K1$, K2$ and K3$.
  5. Intermediate phrase 2: A connecting phrase, which includes a phrase from table I2$.
  6. 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.

These rables are filled in as follows…

'PHRASE 3 (Phrase K)
'Set Variables for third phrase (Phrase K) generation
'----------------------------------------------------
K1$(1, 1) = "Death": K1$(1, 2) = "i": K1$(1, 3) = "i"
K1$(2, 1) = "Life": K1$(2, 2) = "i": K1$(2, 3) = "i"
K1$(3, 1) = "Self": K1$(3, 2) = "i": K1$(3, 3) = "i"
K1$(4, 1) = "God": K1$(4, 2) = "i": K1$(4, 3) = "i"
K1$(5, 1) = "Existence": K1$(5, 2) = "i": K1$(5, 3) = "i"
K1$(6, 1) = "Being": K1$(6, 2) = "i": K1$(6, 3) = "i"
K1$(7, 1) = "Reality": K1$(7, 2) = "i": K1$(7, 3) = "i"
K1$(8, 1) = "Others": K1$(8, 2) = "i": K1$(8, 3) = "p"
K1$(9, 1) = "Thought": K1$(9, 2) = "i": K1$(9, 3) = "i"
K1$(10, 1) = "Knowledge": K1$(10, 2) = "i": K1$(10, 3) = "i"
'-----------------------------------------------------
K2$(1, 1) = " defines ": K2$(1, 2) = "i": K2$(1, 3) = "s"
K2$(2, 1) = " is defined by ": K2$(2, 2) = "i": K2$(2, 3) = "s"
K2$(3, 1) = " creates ": K2$(3, 2) = "i": K2$(3, 3) = "s"
K2$(4, 1) = " is created by ": K2$(4, 2) = "i": K2$(4, 3) = "s"
K2$(5, 1) = " define ": K2$(5, 2) = "i": K2$(5, 3) = "p"
K2$(6, 1) = " are defined by ": K2$(6, 2) = "i": K2$(6, 3) = "p"
K2$(7, 1) = " create ": K2$(7, 2) = "i": K2$(7, 3) = "p"
K2$(8, 1) = " are created by ": K2$(8, 2) = "i": K2$(8, 3) = "p"
'------------------------------------------------
K3$(1, 1) = "death.": K3$(1, 2) = "i": K3$(1, 3) = "i"
K3$(2, 1) = "life.": K3$(2, 2) = "i": K3$(2, 3) = "i"
K3$(3, 1) = "self.": K3$(3, 2) = "i": K3$(3, 3) = "i"
K3$(4, 1) = "being.": K3$(4, 2) = "i": K3$(4, 3) = "i"
K3$(5, 1) = "others.": K3$(5, 2) = "i": K3$(5, 3) = "i"
K3$(6, 1) = "existence.": K3$(6, 2) = "i": K3$(6, 3) = "i"
K3$(7, 1) = "reality.": K3$(7, 2) = "i": K3$(7, 3) = "i"
K3$(8, 1) = "God.": K3$(8, 2) = "i": K3$(8, 3) = "i"
K3$(9, 1) = "thought.": K3$(9, 2) = "i": K3$(9, 3) = "i"
K3$(10, 1) = "knowledge.": K3$(10, 2) = "i": K3$(10, 3) = "i"

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
'----------------------
PhraseK:
RANDOMIZE TIMER
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.

Voila!

A philospher at your own hands!

APPENDIX I – Neural Network

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$ = ""
DO
    DO
        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
        CASE ELSE
            e$ = "A"
    END SELECT
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.

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
NEXT I

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.

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.

Programming for kids: Developing a chess program in BASIC – Part 4: Advanced concepts

Advertisements

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

Existing chess tutorials

Huo Chess resources

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).

More updates coming soon!

Until next time…

Happy coding!

Exit mobile version
%%footer%%