Wednesday, 22 June 2016

I have improved my Novag Citrine interface. I have added a pull-down menu to choose between playing against a PC based engine, or the on-board Citrine engine at various levels of play. The pull-down menu curently offers the strongest "Beginner" level BE1, and the eight "Average Time" levels AT1 to AT8. I have coloured the start/stop button light green when it is showing "Start Engine", and pink when it is showing "Stop Engine". This is how the window looks now:

The program now writes the options available for PC engine to the console on start-up. Here is the table for Stockfish 7:

Monday, 13 June 2016

My Novag Citrine interface now has a rudimentary Graphical User Interface (GUI). This is how it looks on Ubuntu Linux:

The default behaviour is that the user plays both sides on the Citrine board. Pressing start causes the button to change to "Stop Engine" and the engine to make a move. The engine continues to play that side until the user presses "Stop Engine", when he reverts to playing both sides. The main purpose of showing the diagram and last move is to help the user fix problems when he enters moves incorrectly. The simple Unicode board is adequate for this purpose. The user starts a new game by returning the pieces to their start position, and terminates the program by clicking the close button (which is on the right hand side when the program is run on Windows).

I found that the Unicode chess pieces were fancier in most Windows fonts, but that these pieces were wider than the other Unicode characters. This was true even for Courier and most other so called "monospaced" fonts. After much searching, and trial and error, I found that Dejavu Sans Mono worked properly on both Windows and Linux.

It is necessary to be careful with the programming here. There are two event loops, one for the GUI, and another for listening to the serial port that connects to the Citrine. The Citrine itself is, in effect, a third thread. It is important to keep all three threads synchronized. The main flow of control can be summarized using a state diagram:

The dotted "Start engine" event is enabled when the user presses "Start Engine" in the GUI, and fires when the thread listening to the serial port is next idle, at which point it is disabled, so that it fires only once. If the user takes back an engine move, and plays another move, the engine changes sides. This is the usual Citrine behaviour. If the user takes back moves while the engine is "thinking", the engine move is discarded, and the engine restarts its calculations with the new position on the board. When the program does send an engine move to the Citrine, it should always be echoed back. If this does not happen, a new game is started. The program writes a commentary to the console. This commentary includes a log of the messages received from the Citrine, and the PGN for each game. Please see later posts for the code.

One of my test scenarios gave a less than desirable result. I set the engine think time to 100 mS, entered 1.e4, and pressed "Start Engine". The engine replied with 1...e5, and I lifted the black king to force the Citrine's on-board engine to make a move. The Citrine calculated 2.Nf3, and sent this move to the PC. The PC engine replied 2...Nf6, before I was able to make the Citrine's move. The Citrine rather unhelpfully indicated 2...Nf6, but rightly would only accept 2.Nf3. The display on the PC was always correct and up to date, however. This problem appears to be unavoidable, but it should not be significant in practice.

Saturday, 28 May 2016

The main 'glue' that was needed was code to convert moves from the Universal Chess Interface (UCI) format to the Novag format and vice versa. This module makes it easy to keep track of the position from within Python, and connect to external chess engines.

As noted previously, I found it necessary to send engine moves to the Citrine twice. A 0.1 second delay after each command worked well for non-captures. In this case, the piece to be moved was clearly indicated, as was the destination square when the piece was lifted. I found that this did not work well when the engine's move was a capture. In this case, the destination square flashed very briefly, and the piece to be moved was again indicated clearly, but the destination square was not indicated at all when the piece was lifted. I added another 3 second delay after sending the first capture, which gave more time to see which piece was being captured.

I can now play against the Stockfish engine on my Novag Citrine board.