Keeping a memorized pro game memorized

(Written on… Uhm… No more “written on” stuffs. Too much of a hassle.)

I’ve memorized a lot of Takemiya games. However, as time passed, I gradually forgot the moves. Only general impressions like “Takemiya likes san-ren-sei opening” and “Takemiya sometimes reply a keima-gakari with kosumi” remains.

That is undesirable. Ideally, I want to remember the games forever. Therefore, periodic review is a must. Mnemosyne, anyone?

Mnemosyne is a program that helps you memorize items. It will smartly schedule reviews for you. Items that you already know well will be asked rarely, while items that isn’t memorized well will be asked more frequently. I use Mnemosyne to memorize Japanese words, among others.

We can use simple HTML tags like <b> and <i> in Mnemosyne, so I thought applets could be supported. My first idea was to create a **cough** Java applet myself and embed it inside Mnemosyne. However, following the principle of “don’t reinvent the wheel” and considering that I had to dig a lot of documentation just to get a “Hello World” applet running (almost no past experience making applets), I tried finding other people’s applet first.

So, I dug through Hiroki Mori’s “Interactive Way To Go” because I remembered there was a game replayer there. This is what I found:

<applet codebase="./../java" code="mori/go/FreeBoardApplet.class"
   width=300 height=350 align=left border=10>
	<param name=demo value=true>
	<param name=size value=13>
	<param name=init value="B[cc]W[kk]B[dj]W[kd]">
	<param name=moves value="B[fk]W[ki]B[id]W[ic]B[hc]W[jc]B[gd]W[cf]B[ch]W[dc]">
</applet>

The parameters were easy enough to decode. Give it a board size, initial moves, and navigable moves. Coordinates are in SGF style, which is <column><row> and the top left is “aa” (the letter ‘i’ is used).

I usually memorize the first 50 moves of a game. My idea is to divide the moves into 10 moves chunks. So, a Mnemosyne item will test moves 1-10, another for moves 11-20, and so on.

However, if I want to test moves 11-20, it will help if move 10 was marked. Since the applet only marks the last move played (from the “moves” parameter), move 10 shouldn’t be in “init” but in “moves”. It will be a dummy move, just to provide the mark.

Sadly, the applet wouldn’t appear inside Mnemosyne. Therefore I changed the usage scenario into the following:

  • A Menosyne item will contain a kifu review code, for example: “Kifu review: ab” which means game ‘a’ part ‘b’ (part ‘a’ is moves 1-10, part ‘b’ moves 11-20, etc)
  • Upon seeing that code, I will go to Firefox and type “k ab” (’k’ stands for “Kifu review”).
  • Firefox will be configured such that ‘k’ corresponds to a bookmark, such as “http://localhost/kifureviewer/?code=cc.
  • A page will appear with the applet mentioned before. I will replay the kifu and report the result back to Mnemosyne.

The process is quite disintegrated, going back and forth between Mnemosyne and Firefox.

For the web application, I decided to use ASP.NET. This is because I planned to load the game data from the SGF file, and I’m already comfortable with .NET’s file I/O. I used Mono 1.1.7’s XSP as the web server.

My ASP.NET’s experience was almost none, so I need to peek the documentation even to get a Hello World running. Here’s a sample:

<%@ Page Language="C#" %>
<html>
	<head>
		<title><% Response.Write(DateTime.Now); %></title>
	</head>
	<body>
	<%
		for(int i = 0; i < 10; i++)
		{
			Response.Write("<p>Hello world!</p>");
		}
	%>
	</body>
</html>

Other than that, I searched on how to import namespaces (needed e.g. System.IO and I didn’t want to type it all over). The answer is to put something like…

<%@ Import Namespace="System.IO" %>

…below the “Page Language” thing.

Next is searching where to make classes and static functions. The answer is to put it inside…

<script runat="server">
</script>

…which is put before the <html> tag.

The last info I needed was how to fetch the HTTP GET variables. This example…

Request.QueryString["code"]

…will get the value of the HTTP GET variable named “code”.

From there it wasn’t that hard, just parsing the SGF file and giving the correct parameters to the applet. Normal C# coding in which I’m already comfortable with.

I didn’t read the SGF format specification, but guessing the tag meanings wasn’t that hard. I assumed the SGF to be nonbranching and probably a lot of other simplifying assumptions. Below is shown some first characters of an SGF file:

(;DT[2006-09-01]EV[3rd Toyota Cup]RO[semi-final]
PB[Lee Sedol]BR[9p]PW[Lee Changho]WR[9p]
KM[6.5]RE[B+R]SO[Moyo Go Studio]
;B[qd];W[pp];B[dc];W[cp];B[ep];W[ce];B[dn];W[oc];

The relation from game code to SGF file names is in the file “database.txt” (location and file name cofigurable in the aspx file) which contains for example:

a	20060901_Lee-Sedol_Lee-Changho.sgf
b	20060830_Lee-Sedol_Hane-Naoki.sgf

The path of the SGF file is also configurable in the aspx file.

However, testing quickly reveals a critical problem:

Illegal Go position

It is clear that in putting stones from the “init” parameter, the applet didn’t check for captures.

There were two alternatives if I still wanted to use that applet. First is to ask for the source code of the applet and modify it. Second to do the capture checking myself before giving the parameters to the applet.

I chose the latter, utilizing the class inside my (with Fuad, Awang) Go playing program, Sai. A little hack here, a little hack there, and the board was displayed properly:

Legal Go position

Of course the prisoner count was wrong :). I don’t think there is a way to tell the applet about the initial prisoner count.

Anyway, it supports handicap:

Handicap support in KifuReviewer

However, being a Frankenstein solution, there are many things to improve:

  • The applet should be inside Mnemosyne. (at least I informed the maintainer)
  • Dummy move should be eliminated. The board should start with the last move marked.
  • User should guess by clicking on the desired coordinate, not by clicking the next button.
  • Prisoner count should be correct.

At least now I have a non-completely-manual means to memorize a game infinitely long. 1 game is already in Mnemosyne, and a lot more will certainly come…

Share and Enjoy:
  • bodytext
  • del.icio.us
  • Technorati
  • Slashdot
  • StumbleUpon
  • Sphinn
  • Facebook
  • Mixx
  • Google
  • TwitThis
  • Live

Leave a Reply