Wednesday, 22 June 2016

Improving the Novag Citrine Interface

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". Here 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:

Engine Option         Type    Default Min    Max     Var
Clear Hash            button  ''      None   None  
Contempt              spin    0       -100   100  
Hash                  spin    16      1      1048576
Minimum Thinking Time spin    20      0      5000  
Move Overhead         spin    30      0      5000  
MultiPV               spin    1       1      500  
Ponder                check   False   None   None  
Skill Level           spin    20      0      20    
Slow Mover            spin    84      10     1000  
Syzygy50MoveRule      check   True    None   None  
SyzygyPath            string   None   None    
SyzygyProbeDepth      spin    1       1      100  
SyzygyProbeLimit      spin    6       0      6    
Threads               spin    1       1      128  
UCI_Chess960          check   False   None   None  
Write Debug Log       check   False   None   None  
nodestime             spin    0       0      10000


These options can easily be changed from within Python, e.g.:

engine.setoption({'Skill Level' : 0})

This certainly works - Stockfish plays rubbish on Skill Level 0. The code can be found here. [Updated 28 June 2016.]

Monday, 13 June 2016

Adding a Graphical User Interface

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

Integrating with the Python Chess Module

My next step was to integrate my rudimentary Novag Citrine interface with python-chess:

https://python-chess.readthedocs.io/en/v0.14.0/

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.