So far, I “have” few chess engines which are pure vaporware, with the only exception of one, which did play against itself, but it was a mess already and then it was scratched away.
By そらみみ (Soramimi) - Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=47231683
Currently I’ve put more efforts in finding names for this vaporware of mine than in completing just one chess engine — and it’s so despite the fact that I know the chess engines arena needs more engines!
As a pro memoria for myself, and to show how tempus fugit, and to leave tracks in the dust — just in case of unfortunate events — here the current list of anything but actual chess engines of mine. Planned without a plan.
- Principe (“prince” in Italian); imagined in Ada.
- Tired horse; imagined in C
- Pellegrino; the only almost non-vaporware… still imagined in Raku;
- Hawk; imagined in GNU AWK
- Furetto; imagined in Fortran (ça va sans dire: modern Fortran)
- Etrof; imagined in Forth
- LAME; imagined in Lisp (or maybe Clojure? Scheme? …)
- Their; imagined in Erlang
- Ærless; imagined in Erlang
- Atthlo; imagined in Smalltalk
- Tx1 (or EOES); imagined in (maybe Go)
- Bali; imagined in Java (why? why?)
Ok, these are all vaporware, but it doesn’t mean I haven’t few ideas for some of them. Since I “imagined” them almost always in specific languages, a core idea should be to do them as idiomatically as possible. Am I able to do so in so many languages? I bet the answer is no. Nevertheless…
The second core idea deals with my dissatisfaction of the current approach used by classical chess engines, even if it’s the only one which gives results. That is, brute force.1 Hence I want to try different approaches. Chess engines’ history teaches that trying to imitate how humans might think about chess moves is a cul-de-sac: you can’t create a strong chess engine this way. Nevertheless… My purpose is not to create strong chess engines: I already know well that none of my future creations can compete in the serious business of the giant chess engines — those which can defeat the strongest human player2. I want just to have fun and make engines which play as an amateur chess player.
Indulge me while I tell few vaporized drops about those. At least about the names…
I found AdaChess because I searched for “chess engines written in Ada”: I was planning to use Ada for the task and wanted to check if someone else did it. Of course at least one did it. It’s not vaporware: AdaChess can actually play, and well enough to compete with other engines. And it’s written by an Italian. Not a feature, but an interesting (to me) fact: the intersection between the set of chess engine programmers and the set of Italian programmers is small3; the intersection between the set of Ada programmers and the set of Italian programmers is small too… The chance that the intersection between these two small sets is not empty was small (in my mind, at least). And so…
Then I thought: as first experiment of a chess engine written in Ada, maybe I can tweak this one to experiment few ideas. But looking at AdaChess I thought: maybe I can do an Ada interface which should allow me to plug different engines on top of a base which handle all the boring details…4
Hence this vaporware Principe was planned, so to speak. That is, I started thinking about the minimal interface a core should have in order to focus on the important big things and to leave the rest to others.
Creating a specific “chess character” should look just as
I haven’t other ideas for Principe: it should be just another classical chess engine written in Ada (not so common, but not unique).
This exists just because I feel more comfortable with C than other languages. The name tells something about its style: the horses will be considered more than the usual, and its aim must be to keep at least one horse (and the king!) until the end of the game. That horse will be very tired then…
Pellegrino means pilgrim in Italian; from Latin peregrinus. It was a pun (sort of) with Perl, r > l, Pell-…
I was thinking about Perl6, now called Raku. I was playing with the language and thought: well, let’s try Raku doing something easy as a chess engine… A first basic test was started and played a game or two against itself.
Now, Raku has a lot of features that I would like to use while making the engine. I think there’s a place for junctions, lazyness, parallelism and/or concurrency (race, promises, supplies5/channels, and whatever).
AWK isn’t the language you would pick first to write a chess engine, is it? The reason behind the name is pretty obvious. But why AWK at all? First, because I don’t expect it to be fast (not enough to exploit brute force), so it must use all kinds of tricks to try and be decent.
Just because Fortran, I mean, modern Fortran is cool. I didn’t “plan” to use coarrays and images, but I think I should: parallelising should benefit the search and evaluation of positions (at least having more than one core…)
Anyway, let’s imagine to have an elemental function that evaluates a position. Finding the best among several positions could look like this:
This gives the location (index of the array
positions) of the board positions with the maximum score.
Unfortunately my Fortran is more rusty than I’d wish and it is not exactly updated to the latest standard I know of (it’s 20188); therefore I can’t imagine right now more “tricks”, but perusing the array and matrix capabilities and scattering do concurrent here and there could be enough.9
Etrof is the Italian word Forte backward; Forte means strong and the fact that it is written backward suggests that the engine isn’t strong…
Forth is a language I’ve played a bit in the past, but I’ve never passed the threshold beyond which you can say you know a language (that’s true for a lot of other languages mentioned here), but you know, it’s enough to consult a manual (…) and get a feel of it to become a little bit idiomatic… Isn’t it?
The L stands for Lisp, and the rest was chosen because it will be a lame attempt at using lisp for a daunting task. It would be my first serious program written in lisp (likely Common Lisp), a language I don’t love particularly, even if I “feel” its power and its great capabilities.
I was thinking: there must be room for macros somewhere! And for the not-so-lispy loop.
Their and Ærless
The Erlang language is another of those language that in my opinion should be among the tools of every enterprises, en lieu de all the Java ecosystem, or at least a big part of it.10
These chess engines should exploit the Erlang’s ability to create many light processes which can easily communicate and be distributed.
Their was my first thought at it, but used indeed other engines to do the actual work (hence its their work which makes the chess engine). This idea is now “transferred” to the Tx1 engine. That is, Their should be compared to Tx1.
Likely Their will be even more vaporware than the rest, since if I’ll do Tx1, unlikely I’ll do also Their.
Ærless stands for “a Erl(ang) (ch)ess (engine)”. This one would be made of several processes too, but without using other engines.
E.g., there should be a bishop process that take a look at the board (given by a board process) and pass possible moves to a collect-moves process, which collects also other possible moves from other processes and passes the resulting positions (i.e., the board position we have after playing the move) to an evaluate process, which in turn collects evaluations from other specialized processes able to evaluate particular situations, and finally decides a set of promising moves which then are passed to a strategy process which will choose one move in order to implement a strategy (or a policy), and then it will communicate the move to the executor process, or manager process, or player process, which understands UCI (alas) and will give the move back to the GUI/client.
A piece like the king, represented by its own process, could raise a flag to signal that he’s in danger; the strategy process (or processes) can see the flag and devise a defence strategy, altering the behaviour of the evaluators processes, if necessary.
It’s vague, but these are the guide lines to follow.
Can such an architecture produce a good enough chess engine? This long list of chess engines includes also weak engines (the lower has an ELO of 1379, even if one must remember that this ELO is given playing against other engines… so, it can be weak among engines, but maybe still beats easily an amateur player); and this other list even weaker engines.11
The only idea behind this vaporware engine is to make it play aggressively. The letter H in Italian is read as “acca”; if you expand it inside its name, you obtain AttACCAlo, which can be translated as “attack it!”
This engine is eager of pieces and may underestimate defence, and hence be defeated easily. But it should at least care very much for pawn structures.
If it makes it to the end game, he will try to draw (abusing the rules, if it can).
Tx1 stands for “Tutti per uno” (one for all), part of the Musketeers’ motto.
The idea is to use several chess engine to evaluate the same position and to suggest moves. Then, pick a move, randomly or according to a criterion.
Let us suppose that we have two engines A and B, and that A defeats always B (e.g., A is Stockfish, B is one of mine). Then of course using B m/N times makes Tx1 weaker, not stronger. But if B is a decent engine, it could give nuances to the game.
With more than two engines, some sort of consensus can be implemented. At the end of the game, one can count how many moves per engine, and use these weights to judge this recipe for Tx1. Then weights can be adjusted or mutated for the next game. Again, this is not intended to make Tx1 stronger but to give it “personality” — a schizophrenic one, indeed.
This is a last minute addition. Even if I think that the presence of Java in the industry should be less than it is because other “technologies” can do better and more easily some of the tasks Java is used for, still Java is an important language, and its VM is good, and there are other languages which target it — like Clojure, which I could use instead of Lisp for LAME (I won’t, but I could).
Recent revisions of the language has some feature that can be misused, and the main idea around the Bali chess engine is to abuse those features, no matter if it makes sense or not.
Why the Bali name? Well, Java is an Indonesian island, and so is Bali — which is, by the way, not so far from Java.
More and more!
Making a full working chess engine is too much? Then just imagine it, and you’ll get great vaporware!
Creting a good chess engine is a serious effort, and a serious business if you plan to compete with the strongest chess engines, which nowadays must include also Leela chess Zero or alike.
A chess engine written in VHDL that can be put on a FPGA (one FPGA or more FPGAs)…12
The current theory says that chess engines do not use pure brute force: Shannon told us about what he called type B strategy. Chess engines explore only a selection of all the moves; they prune not so promising branches, and use other tricks to reduce the incredible number of moves they should analyze to play perfect chess. Practice proves that the strategy works. Anyway, I state that all chess engines use brute force. This fragment from Chess Programming wiki tells me I am not wrong: with the advent of alpha-beta and all its enhancement, brute-force got very successful from the 70s until present, since the task of classifying and excluding “not plausible” moves, turned out to be quite difficult and error-prone. Basically, even using all the same tricks and tools, computational power matters alot, that is, it’s fundamental — and that’s a clue of the fact that the algorithm uses “brute force” in a sense. Engine A running on a powerful computer can defeat itself running on a less powerful computer. That’s because the power of the engine is very sensible to the brute computational force of the machine where it runs. This fact suggests that brute computational force is a key factor, and this can be so only if the algorithms need brute force to do a lot of computation; and what is this computation about? Of course, trying moves and evaluating the board after each moves. If we define “brute force” as a strategy that tries all the moves down to a certain depth, then modern classical chess engines don’t use brute force. But I contend that this definition isn’t accurate and shouldn’t be used. Successful type B strategy is still a brute force strategy. Successful type A strategy is simply impossible (currently…); hence, type B strategy is the only bullet chess engines can fire. The imitation game of how humans play chess is over. Massive parallelism, quantistic computers, … altogether with the latest neural network research… could these things give new hope for the imitation game? So far, I don’t think so. Prodigies like AlphaZero still use brute force after all. Before and/or during the game. Humans can’t beat those monsters anymore, maybe, but humans don’t need brute force at all to be a Karpov or a Carlsen. (Unless you define the needed hard-work and study as the human version of brute force…)↩︎
What about all the other not-so-strong chess engines? Pages like this or this make me think that there can be room for my chess engines, too, after all! How do I submit my future engines to those competitions? I don’t know yet.↩︎
Indeed by heart I can think about only two: one of the authors of Stockfish has Italian origin, and AdaChess’s author…↩︎
Of course the same effect can be achieved by modification of functions and procedures. But the idea was to keep the “fixed” part separated from the parts which can be changed in order to make a different chess engine, so that it would be enough to adhere to the interface in order to make another chess engine…↩︎
I imagine that a part of the code supplies the moves and another part checks and evaluates them… Still unclear, but I think there can be plenty of fun and learning more actual use of the language.↩︎
CECP (WinBoard/XBoard) is better, but it is also true that it is harder to implement. That’s why everybody’s going UCI: it’s inferior, but easier to implement, and when you are thinking about a chess engine, you don’t want to cope with a protocol that makes your life harder. This is the only reason I can find for the success of UCI: if you take a look at it, in fact, it does not feel right. Few contra here. My 2 cents: with UCI, part of the “intelligence” of the engine is indeed inside the GUI. This means that engines can’t do all the reasonings they could do with CECP.↩︎
AWK isn’t multithreaded. Hence, while thinking, it can’t receive commands. This could be a serious problem… But AWK can handle TCP/IP connection: maybe the solution is to use two AWK programs (processes)…↩︎
But Fortran 2018 is a minor revision of Fortran 2008, for which it holds the same about me: rusty!↩︎
Also features like
do concurrent, but I am reading here and there that those are obsolescent features… So now it is like this: writing the code so that the compiler can parallelise as many operations as possible.↩︎
Remove Java and use Go, Erlang, C++; and other languages like Ada (which can replace C++; what about Rust?), and of course dynamic languages like Python (also as embedded language; but as embedded language we could pick also Lua, or Scheme…) This diverse use of languages (and other tools) can scare and gives problems if all the cheap programmers we have are fresh from Java-centric universities. And if the management was convinced that it’s better (“safer” and more “powerful” and also cheaper…) to use just one-for-everything language and this one language for everything must be Java because, you know, there’s
Java EEJakarta EE and well known and trustworthy “enterprise support” and everything else…↩︎
A chess engine called SxRandom makes me think that it plays randomly (but only legal moves, of course)↩︎