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.

3 comments:

  1. Seems the code link has problems. At least I can't open it.
    What do you think about putting all your Citrine related code to github?

    ReplyDelete
  2. Sorry about that. I have fixed the problem. I should have logged out before testing the link. Putting my code on Github sounds like a good idea. I was meaning to get around to learning about that. My current version is the first really practical one, and then only for users who are capable of installing Python and its libraries and editing the serial port and engine path. My next job is to do some more testing.

    ReplyDelete