Teeko by Mihailo Despotovic, March 1999

The program of my master thesis, “Učenje u strateškim igrama” (Machine Learning in Strategic Games), at the University of Belgrade. It plays Teeko, the game John Scarne invented in 1937: two players with four pawns each, on a board of five by five. First they put their pawns down, one at a time; then they move them, one field in any direction. Whoever first has four in a row, across, down or diagonally, or four in a square, wins. The program plays you or itself, and learns as it plays: after each game it remembers every position of it, with whether X or O went on to win, and in later games it prefers the moves that led to wins. It runs here as it did in a Windows console, and its files are kept in your browser, so it goes on learning from the games you play.

For each move it asks three advisers: its heuristics (make four, stop a four, make a three that can't be stopped…), a minimax search two moves deep, and its memory. Then it plays the move its evaluation function likes best. In batch mode it plays itself as many games as you ask, each side with its own memory, and that is how the experiments of the thesis were run. The memories those left are on the thesis CD, and can be loaded here; the most experienced is the one after 10,000 games.

I wrote it from 1997 to 1999 in ANSI C, as portable as I could make it: it was built with Turbo C 2.0, Borland C++ 3.1, Visual C++ 4.1 to 6.0, CodeWarrior 3.0 and the cc of Solaris and AIX, and checked with lint. Its main() was begun on 14 November 1998 in Sunnyvale, California, five months after I moved to the USA. My advisors were Đorđe Dugošija and Vladimir Srdanović, and I defended the thesis on 13 May 2002, before a commission of Đorđe Dugošija, Srđan Stanković and Vera Vujičić-Kovačević. The idea went on into TeekoTeacher.

To play:
  1. Click or tap teeko below, or type teeko in the console and press Enter.
  2. Press 2 and Enter to let the program begin, or 1 to begin yourself. (3 has it play itself; Enter shows each move.)
  3. Put your four pawns down: type a field's row and column, like 13, and Enter, or click the field on the board.
  4. Then move a pawn to a free field next to it: type both fields, like 1323, or click your pawn and then the field.
q stops a game, and q in the menu quits. t hides the program's thinking, ? shows the score, and teeko -? explains batch mode.
Run:
Keys:
The console

            
The board (click to type a field)
A field is its row, then its column: 00 is top left, 44 bottom right.
C:\TEEKO, kept in this browser
Saved memories, from the thesis

How it works

The opening, while the pawns are put down, has its own heuristics: the middle first, then the fields around it; later, four if it can make it, else stopping the opponent's four, else making three, else stopping the opponent's three. After that, for each move, the heuristics try in turn to make four, stop a four, make a three open at both ends, make a three that can't be stopped, and stop those of the opponent; failing all of those, a random move. Making or stopping four is played at once. Otherwise the search writes every move of the program to a file, level1.s, and every reply to each of them to level2.s, and takes the move whose worst reply is the best. The evaluation adds 1000 for four, 15 for a three and 6 for the middle field, 3 for each of the eight around it, less the opponent's.

The memory, memory.m, is plain text: each position is 25 digits, the board row by row, followed by how many games it was in that X won, and that O won, in four characters each. A position and the same with X and O swapped are one. When a game is won, every position of it (after the opening) is added, or its count is raised. To recall, the program looks for the positions its next move can reach, and takes the one with the most wins over losses. Drawn games teach nothing. stat.m keeps the score.

The bugs, and the fixes

Fixed does what was meant: the search plays its best move, each side reads the memory from its own side, a game you began is learned the right way round, a draw is offered only when the moves repeat, your pawns move only to a free field next to them, the patterns name the right fields and leave out the right ones, the square patterns run, the opening puts its pawn on a random free field when the four are taken, the statistics give the right number, and learning alone looks at the board it is on. The typos, such as “occured” and “positios”, are as they were.

The port was checked against the original C, compiled on a Mac with Microsoft's rand(), the clock given, and the typing read from a script. In 400 sessions of random typing and command lines, batch mode with the saved memories included, and 200 played by a program that reads the screen and answers as a person might, mistakes and all, the screens and the files left behind are the same, hangs included. Each heuristic was also run on 60,000 boards, reaching every line of them, with the same result every time. Where the C reads or writes past the end of the board, the page does what it would if the variables lay in memory in the order defs.c declares them, and the C was compiled so; the board learnplay() never fills in is empty here, as it was in that C. Visual C++ 6 rounded a percentage that ends in exactly a half up, 3.125 to 3.13, and the page does too.

The original C code

Seventeen files, which teeko.c puts together with #include.