OpenTafl progress: v0.2.3b, and 20,000 lines of code

This is not a notification of the release of v0.2.3b: there’s quite a bit of work still to go, as far as releases go. However, since I hit the milestone in the title last night, I figured I’d offer a little preview of what I’ve been working on. (Astute readers of Many Words Main will likely remark, “Well it clearly isn’t writing!” In this, they are not correct. It’s merely the typing I’ve failed to keep up with.)

So, what’s in 0.2.3b? Quite a lot, as it turns out; I got started on a certain big feature and couldn’t help myself. We’ll get to that in a bit. Here’s a rundown of the smaller pieces:

Completed external engine support
I finally buckled down and added the last piece of external engine support: engine-raised errors. I’d previously considered a more complicated set of engine-raised errors, but it boils down to this: there are two kinds of errors an engine can encounter, recoverable and unrecoverable errors. Whenever OpenTafl receives an ‘error’ command from an external engine, it presents a dialog box with a message provided by the engine in the command. If the error is critical (determined by the error code), the game ends. If non-critical, the game continues.

A particular IntelliJ feature greatly aided me in completing this task: there’s a quick-fix item for ‘implement interface method’, which is, to say the least, extremely handy.

Some internal changes
These mostly have to do with fixing little things which could cause trouble later. One of the principles of object-oriented design is that objects should do one thing, and some behind-the-scenes functionality was creeping into UI components. I spent some time and energy on this.

Resilience and stability updates
As this series of releases deals with adding more outside inputs to OpenTafl, I spent some time making sure that failures and edge-cases are handled gracefully. For instance, 0.2.3b will properly terminate external engines when they’re no longer required, and analysis engines are handled more like regular engines for consistency. In other news, I fixed a few random crashes I came across while working on this update.

Resolve embarrassing Copenhagen rules discrepancies
It turns out I had two things wrong about Copenhagen rules: first, edge fort escapes require the edge fort to be an invincible shape, not merely an enclosing one—that is, that black cannot break the fort no matter how many unanswered moves he gets. Second, the attacking side goes first. The second one rankles a little more than the first, especially because the first one revealed an interesting heuristic for whether or not a taflman in a chain of taflmen can be captured.

It goes like this. If a taflman is part of some safe structure (that is, a structure which contains no enemy taflmen), then you can determine whether it can be captured by, in a sense, counting liberties. Get all four orthogonally-adjacent spaces, then remove any spaces which are inside the structure, and any spaces which are currently occupied by friendly pieces. If and only if you are left with three spaces can the taflman be captured. This is a nifty little way of detecting defects in chains, taflmen which are ‘sticking out’—alone on a certain rank or file. It may come in handly sometime down the line.

And now for the big feature.

Saved games and replays
Screenshot

As part of AI self-play mode, I wrote a game serializer: a way to write out game records for later viewing. Once I had done that, I was halfway to a full replay system; and once I had a full replay system, I was immediately adjacent to loading games. OpenTafl’s replay/save system has the following features:

  • Replays and saves become the same sort of object: a human-readable OpenTafl Notation game record file.
  • Replay mode can be initiated from any game record file, or from any point in a game in progress. If the other player is not also a local human, the other player can make moves while you are viewing the replay of the game in progress.
  • At any point in a replay, you can begin a new game from that position. (Note that, at this point, you can’t return to your original game except by reloading the original game. This is a limitation which will likely be around for a long time: playable variations are likely to be a huge pain.)
  • Replay mode supports annotations, and annotations following a certain format will correctly update OpenTafl’s clock display.
  • Saved games are a shortcut of sorts: they load a replay file, play it to the end, then use the ‘play-here’ function.

I have two tasks left on my plate before I’m ready to release 0.2.3b. First, I need to test the game serializer and loader against Berserk rules tafl: the potential for more than two moves per turn (in the case of berserk moves) is one I hadn’t quite considered, and need to consider. Second, I need to write help messages for all of the new functionality.

Once I’ve released 0.2.3b, it’ll be time to give the engine protocol one final once-over, and freeze it at version 1.0, where it will remain until at least this winter’s tournament. (If critical weaknesses are revealed, it’ll have to change. If no major weaknesses are revealed, it might stay at version 1.0 indefinitely.)

Finally, I want to touch on how big a milestone this is for OpenTafl, in my estimation. Before the 0.2.x series of releases, OpenTafl was essentially a toy: a novel way to play tafl games—there aren’t a lot of modern desktop clients—but little more than that. Following the completion of 0.2.x, OpenTafl will be a tool: for learning to play tafl, through the replay and annotation functions, and for studying computer tafl, through external engine mode. We’re arriving now at the purpose I had in mind for OpenTafl—to expand the base of people who are able to translate a casual interest in the game into a deep study, by building tools to make it easier to do so. Here’s hoping it works.

One thought on “OpenTafl progress: v0.2.3b, and 20,000 lines of code

  1. Pingback: OpenTafl v0.2.3b release, and a vision for 0.3.x - The Soapbox

Leave a Reply

Your email address will not be published. Required fields are marked *