Author Archives: Fishbreath

On tafl: timing

In a previous tafl post, I remarked on the lack of pre-defined notations and mathematical resources for tafl games. In this one, I will remark on a more fundamental deficit: namely, this is the first article I can find on the Internet which will attempt to define a standard for timed tafl games.

Surprising? Well, yes and no. Competitive tafl games are rarely played in person. The only live tournament (in the modern era, anyway) put on to date was run by the Fetlar Hnefatafl Panel, and as tournaments go, it was a fairly casual affair—the games were untimed, with a gentleman’s agreement not to take an undue amount of time per move. The other major tafl tournaments are run at Aage Nielsen’s site, and are correspondence play: timed, but not in the sense we’re looking for here.

The Fetlar panel suggests using a regular chess clock, but that seems unappealing to me. Broadly speaking, tafl games are defined by two stages: an opening, where the two sides jockey for position and control in the corners, and an endgame, where the king has left his throne and is pushing to one corner. The length of the opening doesn’t vary much for a particular board size, and generally speaking, features thoughtful, cautious play. Once the king leaves the throne to start the endgame, the flavor of play changes dramatically. The king’s side must make bold, sweeping moves, and the besieging side must split its attention between putting out fires and shoring up its leaky positions. What was a game of edging around the opponent and building one’s own structure becomes a head-on conflict.

The similarity to battle is striking, and suggests a method of timing that mirrors the structure of the game. Go players among the readership will be familiar with the concept of byo-yomi, a kind of overtime comprising a number of periods of a given length. If you don’t use all of one of your byo-yomi periods, you get it back in full. If you do use it, you move onto your next one. I suggest a tafl timing scheme using a small amount of main time, and a relatively generous overtime allocation. My thinking is this: the main time ought to be used for the opening, and once the endgame begins, the players should be nearly out and into overtime. I don’t have good information on how tafl games play out yet, but as a rough starting point, I would suggest a main time of about ten minutes, and three to five overtime periods of one minute each. More generally, I propose this mutation from a single main-time chess clock: for a given chess clock length in minutes (say, 60), divide by six to get the tafl main time (10, in this case). Divide that by ten to get the length of the overtime periods. Depending on the desired difficulty and clock sensitivity, set the number of overtimes to somewhere between two and six.

Not only does this mirror the calm-to-intense structure of tafl games, it also serves a practical purpose. Although tafl games and chess appear to have similar distributions of game lengths1, I get the feeling that the most competitive chess games are clustered around the average more than the most competitive tafl games2 are. An adaptive time control like byo-yomi frees endgames from the tyranny of the clock. Some games will end up playing out more quickly, and won’t feel clock pressure at all; I don’t feel that this is an indictment of the scheme. Some games will end up playing out at around the average length, where the clock is set perfectly: players will feel some time pressure, but have sufficient main time to lay their plans for the endgame. Some games, finally, will end up running longer. With an ordinary chess clock, a longer game would end with increasingly desperate time pressure. With byo-yomi time, the clock remains a driving force, but doesn’t get much worse with time.

Although I do propose this system for general use, I plan on different time controls for the AI-vs-AI tournament: no main time, and three ten-second overtime periods. Quick-play tournaments are known to be as effective as long-play tournaments in sorting AIs by relative skill level, and a large number of five-minute games is a much easier task for yours truly than a large number of thirty-minute games.

In final news, you can find v0.1.7.1b here, which fixes a few bugs in 0.1.7 and adds threefold repetition rules.

  1. The standard deviation for game length in number of moves for chess comes in at about 25, based on correspondence games listed here, some eyeballing of graphs, and some math based on histogram values, and 11×11 tafl games come in at 23, taken in aggregate, from Aage Nielsen’s tafl tournament history. Neither of these figures are set in stone, for reasons I’ll go into when I write up my findings.
  2. Aage Nielsen’s tournament history, above, has a large number of games between top players in the vicinity of 40 moves, and a nearly equal number at 70 to 90 moves.

OpenTafl v0.1.7b and a roadmap for the future

This evening, I plan to release OpenTafl v0.1.7b after testing on a Windows computer. The big feature is a new UI, which should be more readable and more usable, and which opens the door to several major features: a game clock (I plan to write about timing tafl games in a later post), external AI engines and network play (thanks to a rewrite of the way commands are passed from the AI and the UI to the game engine), and, further in the future, a more easily discoverable UI, where the player can use the arrow keys to navigate the board and move pieces.

Speaking of which, here’s the roadmap. Estimated release dates after v0.2.x are not to be trusted.

v0.1.7b+ – Now to April, as I have the time
The rest 0.1.x series of releases will be concerned with wrapping up a few missing rules: the game clock and draws by threefold repetition, including (for the latter) warnings about making a move that would create threefold repetition, and status messages for both.

Once the remaining features for version 0.1.7b are released, I plan to officially announce the OpenTafl Tafl Open, and provide a space for discussion and updates among AI authors. (We already have a kinda-sorta forum, over at http://conclave.manywords.press.)

v0.2.x – By the end of April
The 0.2.x series of releases will be concerned with implementing engine support. The end-of-April deadline leaves about seven months for AI authors to build in OpenTafl engine support for the OpenTafl Tafl Open, which should be sufficient for some fairly interesting designs.

v0.3.x – Summertime sometime
The 0.3.x series of releases will be concerned with allowing more player-to-player interaction, improving the single-player experience, and implementing extra game-analysis features. Planned features for the 0.3.x series include saving and loading games by means of OpenTafl Notation game records, AI improvements, correspondence play, and a simple in-game history viewer and out-of-game replay viewer.

v0.4.x – Fall/winter
The 0.4.x series of releases will be concerned with support for real-time network play. OpenTafl will be able to run in server mode, or connect to a multiplayer server in client mode.

Other features I may try to fit in include the ability to hypothesize moves and sequences as part of the history viewer and replay viewer, although this may prove to be more difficult than I expect.

Anyway, that’s what you can expect in the next year. In the nearer future, v0.1.7b should be available no later than tomorrow morning, but most likely tonight.

Fish Bowl Decision 2016: the GOP primary so far

With primary season finally kicking off in earnest, I thought I should give my thoughts on the state of the race for the GOP.

The Contenders

  • Trump: The ongoing surprise at his sticking power misses a few facts. Trump’s appeal comes from the center and the disillusioned voter, not a broad part of the conservative base. (See Cruz for a note on that.) The center and the disillusioned are generally the poorly informed, which jives with the sort of person who might support Trump—the sort which doesn’t realize that Trump holds different positions almost daily, or positions that would never actually work. Unfortunately, since most people are poorly informed, Trump’s strategy has been working so far. Fortunately, he gets enough news coverage that even the worst-informed of primary voters is starting to understand that Trump is style, not substance. May win South Carolina, but expect it to be closer than the polls show.
  • Cruz: If I were handicapping, I’d give Cruz about 40%. His ground game is superb, the best of any GOP candidate, which he parlayed into an upset win in Iowa, and a solid third place in New Hampshire, considering he spent about zero dollars. Questions about his values seem misplaced to me: stories about his Iowa operation remark on how he let his volunteers go off-script when canvassing, which fits the conservative ideal of bottom-up organization. Concerns about his likability are overblown. Not every candidate has to be an inspirational orator. Has an outside chance to win South Carolina: most polls show him well behind, but several leaked polls from candidate campaigns in the last few weeks have put him much closer than major polls would indicate.

The Possible Surprises

  • Rubio: The establishment’s golden child is underperforming expectations; his Marco Robot impression in the New Hampshire debate didn’t help anything. Light on substance in the same way that Trump is, without the populist shiny to draw in the jackdaw voters. Has the benefit of money and Washington backing, which will keep him in the race, and maybe even in a few top-3 finishes. The most Obama-like of the Republican candidates in terms of oratory. He’ll eventually peter out, and his supporters will lean Cruz: neither Trump nor Cruz is inspirational in the same way, but Cruz lines up a little better with the thoughtful conservative values Rubio purports to represent.

The Death Watch

  • Jeb!: Why anyone thought another Bush running would work is beyond me. (And I say that as someone who thinks history will be significantly kinder to W than the media of his time were.) He seems a little confused by the lack of support, but name recognition is not the same thing as preference. Jeb!’s deep pockets, and the deep pockets of his supporters, will keep him around long past his use-by date, but he probably won’t climb above 15% in any primary. The SEC primaries, with their proportional delegate awards with a minimum threshold, will probably knock him out of contention altogether.
  • Carson: It grieves me that we see this side of him. One of the first biographies I ever read was a short, middle-school-level take on him. I still think he has an amazing story of faith, a self-reliance informed by that faith, and a climb from obscurity to preeminence in his field. I don’t think he has ‘president’ in him.
  • Kasich: No matter how much a certain set of centrist Republican voters want this to happen, it isn’t happening. He’s burned too many bridges with the base, and seems to be running a general election campaign in the primary. Maddeningly, his record is solidly conservative, and I suspect he wouldn’t be all that bad a choice, but he seems set on running as the Democrat’s preferred Republican primary candidate. Unfortunately for him, most Republican primary voters are Republican, and not buying it.

The Crossbox Podcast: Episode 4

In our extremely belated Christmas edition, we visit John’s favorite decade: the 80s. Join us as we clean up the mean streets of New Orleans, work out just how bad American anti-ship missiles are, and insult a very wealthy man for fifteen minutes.


(Download)

OpenTafl v0.1.6.1b, and progress generally

I’ve released a new version of OpenTafl. Among several other changes, there are two I would like to highlight.

First off, the groundwork for OpenTafl Notation-style engines is complete: there is code in OpenTafl which can produce and read in OTN rules records, code which can produce and read in OTN position records, and code which can produce OTN move records. This is a major milestone: producing and reading position and rules records is tricky, as is producing move records. (Move records should be fairly easy to read in, compared to the others; they encode a much smaller amount of critical data.) Note that the notation spec has changed somewhat, based on lessons I’ve learned over the course of my weekend of implementation. If you’ve done any work based on it yourself, you’ll want to go over the spec again. Hopefully, it won’t change much going forward, although the specification for OpenTafl-compatible engines is likely to change as I work on implementing that in the next month or two. You can see some of the work in version 0.1.6.1b: each position should provide its OTN position record, and games against the AI will report the AI’s thinking using OTN move records.

Second, OpenTafl’s memory usage has once again been dramatically reduced, to the point where it should be comfortably playable to the maximum depth at which it’s feasibly playable (currently depth 6-7 for brandub, depending on speed, and depth 4-5 for other games, depending on size and complexity) without running into memory issues, on any reasonable computer. I intend to go into a little more depth on how I accomplished this, but for the moment, you’ll just have to take my word for it.

You can find the full change logs at the OpenTafl site.

Underhanded C Code’s 2015 winner: why I love computer science

If you’re a software person, read the post. Linus Åkesson, this year’s winner, is brilliant, and I want you to appreciate just how much.

If you aren’t, stick around, because you should appreciate Mr. Åkesson’s brilliance, too. I’m going to explain this in layman’s terms. The International Underhanded C Code Competition, or IOUCCC, is an annual competition where software engineers and computer scientists from all the world over compete to write the most innocent-looking yet fiendishly guilty C programs possible. This year’s challenge is as follows:

There are two countries, which have signed a nuclear disarmament treaty. Each wants to carry out inspections to ensure that the other side is decommissioning real bombs, and not fakes, but neither side wants to expose the actual gamma ray spectra produced by their real bombs—that’s sensitive information on their nuclear programs. So, they have need of a tool which takes an observed spectrum and compares it to a reference spectrum, returning either yes (if the observed spectrum matches the reference spectrum, and is therefore a bomb), or no (if that is not so). Here’s the underhanded bit: one country wants to cheat. They want to keep more bombs than the treaty permits, but they have to fool the inspectors—that is, they have to figure out a way to show inspectors fake decommissioned bombs, which nevertheless yield a ‘yes’ when inspected with the tool. They can’t just fake the reading, because the reading has two parts: first, the placement of the peaks in the spectrum and their relative sizes, which only come from the specific mixes of fissile materials used in bombs; and second, the overall radioactive energy level of the bomb, which only comes from having a large amount of radiation coming from the bomb. It’s easy to replicate the peaks with a small amount of fissile material, and easy to replicate the total energy with an x-ray source, but impossible to combine them to look like a bomb without being a bomb.

We need to establish some background information about how spectra appear to digital tools. The way you collect a spectrum is to point a detector at a radioactive source of some sort. Energetic particles strike the detector face. An event is recorded, and deposited into a ‘bin’ based on the energy of the event. The collection of bins composes the spectrum. So, a spectrum, to a computer, looks like this: energies between 0 and 100, 20 events; energies between 101 and 200, 40 events; energies between 201 and 300, 153 events; and so on. In C, the easiest way to represent this is an array—that is, a region of computer memory which holds a list of numbers all in a row. Since, to a computer, numbers are a fixed number of bits (binary digits), the numbers don’t need to have any space between them; number N+1 is a fixed length from the start of number N.

We also need to talk briefly about floating point numbers. Floating point numbers are how computers represent decimals (generally speaking). Since there are an infinite number of real numbers between any two real numbers, a computer obviously can’t represent them precisely. Instead, it uses scientific notation, akin to this example: 1.2 \times 10^2, or 120. (In binary, obviously, but that’s not important yet.) We call the 1.2 part the mantissa, and the 2 the exponent. (For a computer, the base of the exponent is always two, because of binary.) Moreover, they are arranged like this: sign bit, exponent bits (highest place to lowest place), mantissa bits (highest place to lowest place), and the mantissa is always assumed to be one, unless the exponent is zero. (Instead of writing 1.2, we just write .2, and remember that we usually put a one before the decimal point.)

Finally, we need to discuss how one might want to compare two spectra. First, we’ll introduce a quantity called the dot product: if you have two lists of numbers of the same length, and go number-by-number, multiplying the first by the first, the second by the second, the third by the third, and so on, then add all of those products, the number you get is called the dot product. If you take the dot product of a list of numbers with itself, then take the square root of the dot product, you get the magnitude. A list of numbers, each entry in which has been divided by the list’s magnitude, is said to be normalized. Finally, if you take the dot product of two normalized lists of numbers, you get a number between 0 and 1. If you interpret the lists of numbers as multidimensional vectors (remember your geometry?) the number you just got is the cosine of the angle between them. For our purposes, it’s a number called the spectral contrast angle. If it’s 1, the two vectors are completely identical. If it’s -1, they’re completely different. So, when we get our two spectra as lists of numbers, we want to calculate the spectral contrast angle. If it’s sufficiently similar, then the spectra match.

So, Mr. Åkesson’s program takes two lists of numbers, representing spectra. It runs some preprocessing steps: smoothing the data, taking its first-order derivative to remove any constant-slope noise1, and smoothing the derivative to obtain a spectral fingerprint: a representation which contains the locations and relative heights of the peaks. Before going any further, it checks to see whether the total energy in the spectrum is above a threshold—a decommissioned bomb will still have a small signature, because of the remains of the fissile materials inside—then hands off the data to another source code file, which handles normalizing the spectra and doing the dot product stuff.

The underhandedness comes in that handoff. The data is defined as a list of numbers of type float_t. float_t is, in turn, defined in a header file (a file which holds definitions) as a double, a 64-bit (i.e. double-precision) floating point number, of which one bit is the sign of the number, 11 bits are the exponent, and the remaining bits are the mantissa. It is important to note a few things about doubles and Mr. Åkesson’s code: first, data in a double-precision number is left-justified. In cases where a given number can be expressed with sufficient precision, the bits on the right-hand side of the double’s position in memory are set to 0, unused. Second, the values in this particular program are generally fairly small—no more than a few thousand. Third, the preprocessing has the effect of making the numbers smaller: a derivative, as a rate of change, will always be smaller than the total value, except when it changes instantly. So, after the preprocessing, you have a list of double-precision floating point numbers, whose values range from about 0 to 100. Representing these numbers is simple, and doesn’t require using very much of the 64-bit length of the number.

The list is passed to the second file as the argument to a function, still a list of numbers of type float_t. The thing is, in this file, float_t means something else. This file does not include the definitions header from the first file, because it doesn’t need it. Instead, it includes a standard math library header file, and the math library header file defines float_t as a 32-bit (i.e. single-precision) floating point number, of which one bit is a sign bit, eight bits are the exponent, and the remaining bits are the mantissa. So, instead of a list of 64-bit numbers of length n, you have a list of 32-bit numbers of length 2n—but you’ve told the code you have a list of size n, so the code only looks at n numbers. That is, the code only looks at the first half of the spectrum. This lets you evade the total energy threshold without having to have a bunch of radioactive material in the bomb: place an x-ray source in your fake bomb. The total energy goes up so that it passes the threshold, and it won’t be considered in the peak-matching code, because it’s on the right side (the second half, the high-energy side) of the spectrum.

You still have to get the peak matching right, but the underhandedness has a second, subtler component which will help. It has to do with what happens when you convert a 64-bit floating point number into a 32-bit floating point number. Remember that, when a floating-point number doesn’t need its full length to express a number, all of the significant bits are on the left side of the number. Therefore, representing numbers between 1 and 100, especially whole numbers (which the preprocessing helps to ensure) doesn’t take anywhere near 64 bits. It doesn’t even take 32 bits. So, when you turn an array of 64-bit numbers into an array of 32-bit numbers, you split each 64-bit number in half. The second half is all zero bits, and ends up being zero. Since this happens to both the reference and the observed spectra, every other number in both arrays ends up being zero, and zero is the same as zero, so we don’t need to look at them any more.

The first half is the interesting half. The sign bit works exactly the same. The exponent, though, gets shortened from 11 bits to 8 bits, and the three bits that we leave off are the highest bits. Removing the low three bits moves the high bit over three places, which is the same as dividing by eight2. The three bits which were the end of the exponent become the beginning of the mantissa. This is fine: it preserves the relative sizes of numbers. (The least significant digits of the exponent are more significant than the most significant bits of the mantissa; you’ll just have to trust me here, or do some examples in base 10 yourself, following the rules I gave for floating point numbers.)

So what we’ve done is dramatically reduced the sizes of each energy level bin in the spectrum. Furthermore, we’ve also compressed their dynamic range: the difference between the lowest peaks and the highest peaks is much smaller, and so they resemble each other much more closely. The recipe for a fake bomb, then, is to take a small amount of fissile material and a powerful x-ray source, and put them in the casing. The x-ray source takes care of the total energy level, and the dynamic range compression from the 64-bit to 32-bit switch takes care of the low-energy peaks.

Congratulations! You just convinced the other country that you’re about to decommission a real bomb, when in actuality, it’s a fake.

Congratulations also to Linus Åkesson, who wrote such a clever piece of deception into a mere 66 lines, and did so with such panache I could not resist writing on it.

1. This appears in real-world spectra, because there’s naturally a lot more low-energy noise than high-energy noise. In support of this assertion, I offer the evidence that you are not suffering from radiation sickness right now. (Probably.)
2. 1000 is 8, in binary. (From right to left, you have the 1s-place, the 2s-place, the 4s-place, and the 8s-place.) Remove three zeros, and you have a 1 in the 1s place: 1.

Stop the presses! Go AI defeats human professional!

A few days ago, Google’s DeepMind announced that they reached the most significant milestone in pure AI since the solving of checkers in 2007: a Go AI called AlphaGo that’s competitive with human professionals. (Strictly speaking, computers could play Go before yesterday, but they were ranked around midlevel amateurs at their best.) The whole paper is available here.

For those of you who aren’t as much nerds about AI as I am, here’s a quick primer on why this was thought to be a very hard problem (so hard that the people involved in the prior state of the art thought it was at least a decade away):

In the most theoretical conception, game-playing computers for perfect-information zero-sum games (most abstract board games: those with no hidden state with all players working toward the same objectives, to be not entirely accurate but more readable than perfect accuracy allows for) are as simple as exploring every possible move and every possible countermove from the current position to the end of the game. Assuming perfect play on both sides, every result will be either a win, a loss, or a draw—that is, abstract strategy games are perfectly deterministic. (Checkers isn’t completely solved, but we do know now, as a result of the work from 2007, that perfect play on both sides from the start always yields a draw.)

This is, however, a massively impractical way to actually play a game, because the number of positions to explore rapidly turns intractable. Speed-focused modern chess engines search on the order of millions of nodes (in the game tree) per second, but searching a chess position exhaustively to a depth of 7 requires a search of about 60 billion nodes. Traditional games like chess and checkers yielded to some optimizations on this process:

  • It’s easy to look at a chess or checkers board and tell how well the game is going for a certain player: in both games, it comes down primarily to the balance of pieces. (The last I read, advantages in position are worth a pawn or two in a game of chess if they’re all going your way; the queen is worth nine pawns.) So, you don’t need to explore all the way to the bottom of the game tree to get an idea of which directions are promising. You just explore as deep as you can and evaluate the position.
  • If you have a good evaluation function (that is, one that generally only evaluates a position as better when it’s closer to winning), you can do some easy pruning when you come across a game state that’s known to be worse than the worst possibility you’ve explored: in that case, you just don’t explore any further in that direction. It works even better if you can assess which moves are likely to be good and explore those first: if you try the best move first, every subsequent move is going to turn out to be worse, and you’ll save a bunch of time.

So chess computers today, working with those tools, are better than the best human players: the effective branching factor (the number of moves to explore at each state in the tree), using the pruning techniques above, goes from about 35 to between 1 and 10, depending on the exact techniques used. The reason Go didn’t fall to traditional techniques is because it’s just so much more computationally difficult. Chess’s branching factor (the number of possible moves at each state) is about 35, and games last about 80 moves; Go’s branching factor is about 250 on average, and runs about 150 moves. It also features a few difficulties that chess does not:

  • It’s a very non-local game, both in space and in time: a move made at the very start of the game halfway across the board could have implications fifty turns later on the strength of the positions played at the start. This is a horizon problem: in chess, most positions become quiescent—not likely to affect the end effect of that position on the overall evaluation—after the captures stop. Modern chess engines will play all the way through capture sequences for this reason; there’s no similar metric to use for go engines.
  • It’s very difficult to evaluate a board position on purely objective grounds, or rather, we haven’t figured out how to phrase, mathematically, what about a good go position is good. Neither present control of territory nor present number of captures bears very strongly on the eventual result.

Because of the size of the problem space for Go, traditional techniques don’t work. The branching factor remains too high. Modern Go programs use one (or sometimes both) of two approaches: either they use hand-coded expert knowledge to sort and select promising moves for tree expansion (which frequently misses oddball moves that are nevertheless good), or they randomly play out a bunch of games from the current position to the end, and sample the result to pick the best move on aggregate (which frequently misses obviously good moves). The best of the pre-AlphaGo bunch used both, combining expert knowledge to pick the best moves to sample with the oddball-finding power of random simulation.

AlphaGo does a little bit of that, but at its heart, it learned to play a lot like humans do: DeepMind’s researchers fed it a diet of 30 million sample positions and the eventual results, and built a neural network to identify what a good board looks like and what it doesn’t. (Literally—the input into the program is a 19×19 image, with pixels set to values representing empty, black stone, or white stone.) They built a second neural network to identify which states are the best ones to simulate through in a random simulation, and Bob’s your uncle: a professional-level Go program. Their paper suspects it’s about as good as a mid-level human professional—the exhibition tournament they included in the paper saw AlphaGo beat the European human champ five games to zero, four by resignation, but the Euro champ isn’t a top-tier player worldwide. February will see an exhibition tournament between the South Korean champion, a world-class player; we’ll see how it does against him. AlphaGo also won 499 out of 500 games against the prior state of the art Go computers.

The most interesting thing about this development is that it learned to play a lot like a human would—it studied past games and figured out from that study what was good play and what wasn’t, then played a lot (against itself and past versions of itself), which is roughly analogous to playing a lot and working on go problems (the way human go players are supposed to get better). The obstacle to a general game-playing AI (I could buy a copy of Arkham Horror, finally, without having to rope the wife into an eight-hour marathon of doom!) is that training neural networks is currently pretty slow. As I mentioned in the first post, AlphaGo had to study about thirty million positions and play itself many, many times to get to the level of competence it’s at now; presumably, that will improve as DeepMind hones its learning techniques and discovers new and faster ways.

That said, humans still have one thing to be proud of: efficiency. The version of AlphaGo that beat the European champ ran on about 1200 CPUs and about 200 GPUs, whereas the human brain, which is nearly as good, draws about 20 watts.

Some extra reading for you: GoGameGuru has all the game replays, which are interesting if you’re familiar with Go (it doesn’t take much—if you’ve seen a human game or five and a game-against-computer or five, you’ve probably already noticed the differences in play, if only subconsciously) AlphaGo has a style that looks very human. Apparently, Go professionals expect the Korean champ to beat AlphaGo, and another source has the game taking place in March. If I were the champ, I’d be pushing for, like, next week. I don’t know how long the million-dollar prize is gonna be good for.

Here’s a commentary on one of AlphaGo’s games against the European champ.

I originally wrote this analysis for the people over at the Quarter to Three forum, which explains the breezy, off-the-cuff style. If you’ve been following us for a while, some of the introduction will have seemed repetitive, too. Anyway, I hope it was still informative and interesting. -Fishbreath

It takes two to tango: why I like single-seat attack helos

Picture your favorite helicopter gunship. I can’t tell you much about it without knowing what it is, but I can tell you one thing: unless you’re a weirdo like me, it has two seats. I do not think this must be so. To explain why is going to take a little detour into the tactical thinking of helicopter pilots, and how that affects the way they’re employed on the battlefield.

Picture yourself as a fixed-wing pilot. You can easily fly above all but the most specialized of ground-based weapons systems. Compared to anything in the dirt, you are extremely fast, so fast that they may as well be standing still. Your bog-standard general purpose bomb is several times more explosive than the largest explosive projectiles commonly hurled by things on the ground. Your precision-guided weapons are more precise, your sensors are better, you can see further. You are as unto a god, or at least a hero of Greek or Norse myth, striking down your foes with the weight of inevitability behind you.

Got that image in your mind? Savor it for a minute. Now forget all about it, because that isn’t how flying a helicopter works at all.

Picture yourself as a helicopter pilot. If you fly high, a plane will shoot you down, or a long-range air defense system. If you fly low, things on the ground a plane would laugh at will shoot at you, and might shoot you down. You are fast, but you aren’t so fast that you can really use it to enhance your survivability. You do not generally carry especially heavy weapons, and your sensors are pretty good, but you aren’t high enough to see a long way. You are certainly not as unto a god. You’re scary, but it’s the kind of scary your adversaries can actually kill.

What does that mean for you, noble helo pilot? How does it shape your doctrine? If you’re looking for a metaphor, the right analogue for a helicopter is not an IFV or a tank. If you’re a helicopter pilot, your mindset is ‘sky infantry’. You keep out of sight, use natural cover, engage quickly before getting out of sight, and generally skulk around in the mud. Just like the infantryman has a pretty bum deal on the ground, the helo pilot has a pretty bum deal in the sky. The only difference is that the helo pilot has someone to look down on.

Why do attack helicopters generally feature two crew? Because there are three jobs in a helicopter, and one person can’t do all three at once. You need to fly the helicopter, which is a difficult task on its own; you need to use the weapons, which often requires going heads-down; you need to keep your eyes up to see threats visually, since a lot of the things that can shoot down a helicopter can only be detected by the Mark I Eyeball1. The pilot can fly and watch, if the gunner is working with the sensors or weapons systems, and the gunner can keep an eye out, if the flying gets especially hard on the pilot. Simply put, each crewman can do about one and a half things simultaneously, and each helicopter has three things you need to do. Perfect coverage.

Mathematically, it looks bad for the single-seat concept. One crewman can do one and a half things. The helicopter has three things that need to be done. Let’s work on bringing those numbers closer together.

First off: we can install an advanced autopilot. We’ll go the Ka-50, the only single-seat attack helicopter ever to see combat service, as our example2. Taking its age into consideration, the Ka-50 has one of the most advanced autopilot systems ever installed in a helicopter. It’s fully capable of flying the helicopter through a noncombat mission from just after takeoff to just before landing, and can take control in nearly every combat situation that doesn’t involve immediate evasive action, or nap of the earth flying. This reduces our list of things to do to two, but we still only have one and a half tasks doable with our single crewman.

How can we fix that? Add a second crewman, but put him in a different airframe. Your helicopters fly in pairs. How many things will we need to do at once? Fly, but the autopilot takes care of that for us. Use weapons, yes, but that’s a shared task: only one helicopter needs to be engaging at a time. That’s one thing between us. Keep an eye out, yes: ideally, both of us should be keeping an eye out, but in a pinch, one pilot can keep an eye out for the whole team. That leaves us two crewman, who together can do three things, and two or three things to do between them (that is, weapons, eyes, eyes, or weapons, eyes).

That’s really all there is to the argument. Additional automation can help reduce the workload further. A fancy threat warning system helps reduce the need for constant lookout, and helps direct pilot attention during the few, emergency situations where the autopilot is insufficient. Better weapons and datalinks allow for off-board targeting, which can be used to move the weapons employment burden around between helicopters. Autopilots with more options yield further reductions in flying workload—a terrain-following radar or lidar, for instance, would give the Ka-50 the ability to fly nap of the earth at high speeds. Better sensors help reduce the time spent heads-down for weapons employment.

I’m nearing my target word count here, so I’ll wrap up with some quick pros and cons. I’ve made a decent argument that a single-seat attack helicopter is a reasonable choice, so why might you prefer one? To start, you have reduced aircrew requirements, and reduced aircrew losses—half of two airframes is one, and half of one airframe is zero. You have a great deal of large-scale tactical flexibility. Since the two-ship element is the basic unit of maneuver, you can choose to advance in bounding overwatch, for instance, or widely separate your eyes from your weapons. Your eyes helo might be just behind solid cover on a ridge outside of enemy engagement range, able to peek and feed coordinates to your weapons helicopter, which might be advancing in concealment much nearer the enemy. In separating eyes and weapons, terrain may sometimes allow a quick attack from two angles in rapid succession, or at entirely the same time. If you have a small number of helicopter pilots, single-seat airframes let you put more into the sky at once. It’s a setup optimized for tankbusting: large targets, relatively easily spotted and shared.

Why might you choose the standard two-seater? It’s better in moderately threat-heavy COIN situations, where the front lines are poorly defined and any territory may become enemy territory. Two-seat helicopters have better small-scale tactical flexibility, and a single two-seat helicopter swing between navigation, evasion, and counterattack much more quickly than a pair of single-seat airframes. For another, two-seaters are tried and tested. Nobody operates a single-seat attack helicopter in any real number today, not because it’s not a workable theory, but because the only modern example entered service well after its technology started down the hill toward obsolescence. Today, you’d have to build your own single-seater, or buy a bunch of Kamovs and refit them, while you can buy Havocs or Cobras or, for that matter, the Ka-52, basically off-the-shelf. Two-seat helicopters have better engagement speed: for a given number of helicopters and a given number of weapons, the two-seaters will distribute their arms faster, because each airframe is a self-contained targeting and shooting unit, not depending on another helicopter for overwatch or targeting data.

That’s about all I have. One of these days, I’ll take a look at the concept, and come up with some justifications for why Luchtburg might choose a single-seat helo.

1. Or the Mark II Eyeball, also known as the missile launch warning system.
2. The Ka-50 is outmoded in today’s market, but if you look at its competitors in late 80s, when it first appeared on the scene, it’s a much closer case, and depends mainly upon some tactical considerations I’ll get into later.

On tafl: OpenTafl Notation

I mentioned in a previous post that one of the practical difficulties involved in computer implementations of tafl is the lack of a support infrastructure: anyone desiring to write a tafl AI must also write a tafl engine. Admittedly, this probably isn’t a significant obstacle to anyone with a real desire to write a tafl AI, but it does yield a great deal of duplication of effort. This is why my next step with OpenTafl is to build it into an engine into which other AIs can be plugged, and my eventual aim, hopefully at the end of this year, is to host the world’s first computer tafl tournament, where all the AIs so far written can compete against one another for bragging rights1. The timing depends mainly on how quickly I can write the features I need, but I hope to run the 1st Many Words Computer Tafl Open in late December2.

To do this, though, three sorts of notation are required. First, a method for communicating positions; second, a method for communicating rules; and third, a method for communicating moves. (A method for communicating moves already exists, thanks to tafl historian Damian Walker, but I propose some enhancements to it later.) The full version of my proposal is included at the end of this post.

First off, a method for positions: I propose something akin to chess’s Forsythe-Edwards notation, which is easily machine-readable, but also human-readable, and easy to compose by hand. Here’s an example, representing the brandub starting position:

/3t3/3t3/3T3/ttTKTtt/3T3/3t3/3t3/

Enclosed by slashes are rows. Lowercase letters represent pieces from the attacking side. Uppercase letters represent pieces from the defending side. (Besides t: taflman and k: king, my proposal also includes n: knight and c: commander, for Berserk-variant tafl.) Numbers represent that many empty spaces.

To communicate rules, there’s very little choice but to do so exhaustively. Clever use of defaults can somewhat alleviate the issue. Here is a proposed OTN rules string for Fetlar tafl:

dim:11 atkf:n start:/3ttttt3/5t5/11/t4T4t/t3TTT3t/tt1TTKTT1tt/t3TTT3t/t4T4t/11/5t5/3ttttt3/

It uses the dimension element (dim:11) and the start element (using an OTN position string) to mark the start and end of the rules; other elements come in between. The defaults suggested in the proposal, with the exception of atkf (attackers move first), are the rules of Fetlar, and other tafl games may be constructed as transformations from Fetlar. For instance, here’s brandub again:

dim:7 ks:n cenhe:n cenh: cenp:tcnkTCNK start:/3t3/3t3/3T3/ttTKTtt/3T3/3t3/3t3/

Brandub is Fetlar, except it’s played on a 7×7 board (dim:7), the king is not strong (ks:n), the center does not become hostile to the defenders when empty (cenhe:n), the center is not hostile to anybody (cenh:), and pieces of all types may pass over the center space (cenp:tcnkTCNK). Here’s Sea Battle 9×9:

dim:9 esc:e ka:n cenh: cenhe:n corh: cenp:tcnkTCNK corp:tcnkTCNK cens:tcnkTCNK cors:tcnkTCNK start:/3ttt3/4t4/4T4/t3T3t/ttTTKTTtt/t3T3t/4T4/4t4/3ttt3/

Sea Battle is Fetlar, except it’s played on a 9×9 board, escape is to the edge (esc:e), the king is not armed (ka:n), the center and corners are hostile to nobody, all pieces may move through the center and the corners, and all pieces may stop on the center and the corners.

Of tafl variants of which I am aware, the options in the rules string are sufficient to support all of them but one very esoteric alea evangelii variant3, and OpenTafl can theoretically support any variant constructed using OTN rules strings4. Other notable capabilities include the ability to define certain spaces as attacker fortresses, to support hostile attacker camps.

Finally, we move on to move notation. Building on Damian Walker’s aforementioned, excellent adaptation of algebraic chess notation to tafl rules (which, I should stress, is more than sufficient), I wanted to create a notation which requires a minimum of inference, and therefore slightly better suited to inter-computer communication. In effect, I wanted a notation sufficiently detailed such that a computer, operating with only a starting position and a list of moves, could accurately replay the game without having to know any of the rules. Since it is a notation with a lot of options, I provide a deeply contrived sample move record here, which uses almost every option:

Ne4-e6xf6 Ne6^=e8xe7/e9/cf8/d8-

The defending knight (uppercase N) on space e4 moves to e6, capturing the piece on f6 (having no special letter, it’s just an ordinary taflman). This is berserk tafl, so the move is not yet over. The knight on e6 jumps to e8 as its berserk move (^: jump, =: berserk), capturing the taflmen on e7, e9, and d8, and the enemy commander on f8 (as a special piece, it gets a prefix; as an attacking piece, it’s lowercase). This opens up a path for the king to reach the edge (-: king has a way to the edge).

You can read more, and peruse more examples, in the full proposal here: OpenTafl Notation. Feel free to leave a comment with your, well, comments.

1. And maybe a $20 Amazon gift card or something.
2. I hope to finalize the protocol in the next few months, and finish implementing it by the end of summer.
3. The one with mercenaries, pieces which start on the defending side but change sides when captured.
4. I haven’t yet written the code to parse them and generate new games, so I can’t say for sure. Thinking through some oddball variations, though, none strike me as OpenTafl-breaking.

The Crossbox Podcast: Episode 3

This time on the Crossbox Podcast, we discuss Wargame: AirLand Battle, some indefensible positions, and our arms choices for a sadly underrepresented type of competitive shooting challenge.


(Download)

Recommended reading: