<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Articles tagged game at null program</title>
  <link rel="alternate" type="text/html"
        href="https://nullprogram.com/tags/game/"/>
  <link rel="self" type="application/atom+xml"
        href="https://nullprogram.com/tags/game/feed/"/>
  <updated>2026-04-07T03:24:16Z</updated>
  <id>urn:uuid:da57a040-05d6-4aba-ae11-162617d3e9c4</id>

  <author>
    <name>Christopher Wellons</name>
    <uri>https://nullprogram.com</uri>
    <email>wellons@nullprogram.com</email>
  </author>

  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>I solved the Dandelions paper-and-pencil game</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2022/10/12/"/>
    <id>urn:uuid:14edf491-dcdd-4c2f-a75f-5e89838e6b40</id>
    <updated>2022-10-12T03:02:27Z</updated>
    <category term="c"/><category term="game"/><category term="ai"/><category term="optimization"/>
    <content type="html">
      <![CDATA[<p>I’ve been reading <a href="https://mathwithbaddrawings.com/2022/01/19/math-games-with-bad-drawings-2/"><em>Math Games with Bad Drawings</em></a>, a great book
well-aligned to my interests. It’s given me a lot of new, interesting
programming puzzles to consider. The first to truly nerd snipe me was
<a href="https://mathwithbaddrawings.com/dandelions/">Dandelions</a> (<a href="https://mathwithbaddrawings.com/wp-content/uploads/2020/06/game-5-dandelions-1.pdf">full rules</a>), an asymmetric paper-and-pencil game
invented by the book’s author, Ben Orlin. Just as with <a href="/blog/2020/10/19/">British Square two
years ago</a> — and essentially following the same technique — I wrote a
program that explores the game tree sufficiently to play either side
perfectly, “solving” the game in its standard 5-by-5 configuration.</p>

<p>The source: <strong><a href="https://github.com/skeeto/scratch/blob/master/misc/dandelions.c"><code class="language-plaintext highlighter-rouge">dandelions.c</code></a></strong></p>

<p>The game is played on a 5-by-5 grid where one player plays the dandelions,
the other plays the wind. Players alternate, dandelions placing flowers
and wind blowing in one of the eight directions, spreading seeds from all
flowers along the direction of the wind. Each side gets seven moves, and
the wind cannot blow in the same direction twice. The dandelions’ goal is
to fill the grid with seeds, and the wind’s goal is to prevent this.</p>

<p>Try playing a few rounds with a friend, and you will probably find that
dandelions is difficult, at least in your first games, as though it cannot
be won. However, my engine proves the opposite: <strong>The dandelions always
win with perfect play.</strong> In fact, it’s so lopsided that the dandelions’
first move is irrelevant. Every first move is winnable. If the dandelions
blunder, typically wind has one narrow chance to seize control, after
which wind probably wins with any (or almost any) move.</p>

<p>For reasons I’ll discuss later, I only solved the 5-by-5 game, and the
situation may be different for the 6-by-6 variant. Also, unlike British
Square, my engine does not exhaustively explore the entire game tree
because it’s far too large. Instead it does a minimax search to the bottom
of the tree and stops when it finds a branch where all leaves are wins for
the current player. Because of this, it cannot maximize the outcome —
winning as early as possible as dandelions or maximizing the number of
empty grid spaces as wind. I also can’t quantify the exact size of tree.</p>

<p>Like with British Square, my game engine only has a crude user interface
for interactively exploring the game tree. While you can “play” it in a
sense, it’s not intended to be played. It also takes a few seconds to
initially explore the game tree, so wait for the <code class="language-plaintext highlighter-rouge">&gt;&gt;</code> prompt.</p>

<h3 id="bitboard-seeding">Bitboard seeding</h3>

<p>I used <a href="https://www.chessprogramming.org/Bitboards">bitboards</a> of course: a 25-bit bitboard for flowers, a 25-bit
bitboard for seeds, and an 8-bit set to track which directions the wind
has blown. It’s especially well-suited for this game since seeds can be
spread in parallel using bitwise operations. Shift the flower bitboard in
the direction of the wind four times, ORing it into the seeds bitboard
on each shift:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int wind;
uint32_t seeds, flowers;

flowers &gt;&gt;= wind;  seeds |= flowers;
flowers &gt;&gt;= wind;  seeds |= flowers;
flowers &gt;&gt;= wind;  seeds |= flowers;
flowers &gt;&gt;= wind;  seeds |= flowers;
</code></pre></div></div>

<p>Of course it’s a little more complicated than this. The flowers must be
masked to keep them from wrapping around the grid, and wind may require
shifting in the other direction. In order to “negative shift” I actually
use a rotation (notated with <code class="language-plaintext highlighter-rouge">&gt;&gt;&gt;</code> below). Consider, to rotate an N-bit
integer <em>left</em> by R, one can <em>right</em>-rotate it by <code class="language-plaintext highlighter-rouge">N-R</code> — ex. on a 32-bit
integer, a left-rotate by 1 is the same as a right-rotate by 31. So for a
negative <code class="language-plaintext highlighter-rouge">wind</code> that goes in the other direction:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>flowers &gt;&gt;&gt; (wind &amp; 31);
</code></pre></div></div>

<p>With such a “programmable shift” I can implement the bulk of the game
rules using a couple of tables and no branches:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// clockwise, east is zero
static int8_t rot[] = {-1, -6, -5, -4, +1, +6, +5, +4};
static uint32_t mask[] = {
    0x0f7bdef, 0x007bdef, 0x00fffff, 0x00f7bde,
    0x1ef7bde, 0x1ef7bc0, 0x1ffffe0, 0x0f7bde0
};
f &amp;= mask[dir];  f &gt;&gt;&gt;= rot[i] &amp; 31;  s |= f;
f &amp;= mask[dir];  f &gt;&gt;&gt;= rot[i] &amp; 31;  s |= f;
f &amp;= mask[dir];  f &gt;&gt;&gt;= rot[i] &amp; 31;  s |= f;
f &amp;= mask[dir];  f &gt;&gt;&gt;= rot[i] &amp; 31;  s |= f;
</code></pre></div></div>

<p>The masks clear out the column/row about to be shifted “out” so that it
doesn’t wrap around. Viewed in base-2, they’re 5-bit patterns repeated 5
times.</p>

<h3 id="bitboard-packing-and-canonicalization">Bitboard packing and canonicalization</h3>

<p>The entire game state is two 25-bit bitboards and an 8-bit set. That’s 58
bits, which fits in a 64-bit integer with bits to spare. How incredibly
convenient! So I represent the game state using a 64-bit integer, using a
packing like I did with British Square. The bottom 25 bits are the seeds,
the next 25 bits are the flowers, and the next 8 is the wind set.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>000000 WWWWWWWW FFFFFFFFFFFFFFFFFFFFFFFFF SSSSSSSSSSSSSSSSSSSSSSSSS
</code></pre></div></div>

<p>Even more convenient, I could reuse my bitboard canonicalization code from
British Square, also a 5-by-5 grid packed in the same way, saving me the
trouble of working out all the bit sieves. I only had to figure out how to
transpose and flip the wind bitset. Turns out that’s pretty easy, too.
Here’s how I represent the 8 wind directions:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>567
4 0
321
</code></pre></div></div>

<p>Flipping this vertically I get:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>321
4 0
567
</code></pre></div></div>

<p>Unroll these to show how old maps onto new:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>old: 01234567
new: 07654321
</code></pre></div></div>

<p>The new is just the old rotated and reversed. Transposition is the same
story, just a different rotation. I use a small lookup table to reverse
the bits, and then an 8-bit rotation. (See <code class="language-plaintext highlighter-rouge">revrot</code>.)</p>

<p>To determine how many moves have been made, popcount the flower bitboard
and wind bitset.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int moves = POPCOUNT64(g &amp; 0x3fffffffe000000);
</code></pre></div></div>

<p>To test if dandelions have won:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int win = (g&amp;0x1ffffff) == 0x1ffffff;
</code></pre></div></div>

<p>Since the plan is to store all the game states in a big hash table — an
<a href="/blog/2022/08/08/">MSI double hash</a> in this case — I’d like to reserve the zero value
as a “null” board state. This lets me zero-initialize the hash table. To
do this, I invert the wind bitset such that a 1 indicates the direction is
still available. So the initial game state looks like this (in the real
program this is accounted for in the previously-discussed turn popcount):</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define GAME_INIT ((uint64_t)255 &lt;&lt; 50)
</span></code></pre></div></div>

<p>The remaining 6 bits can be used to cache information about the rest of
tree under this game state, namely who wins from this position, and this
serves as the “value” in the hash table. Turns out the bitboards are
already noisy enough that a <a href="/blog/2018/07/31/">single xorshift</a> makes for a great hash
function. The hash table, including hash function, is under a dozen lines
of code.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Find the hash table slot for the given game state.</span>
<span class="kt">uint64_t</span> <span class="o">*</span><span class="nf">lookup</span><span class="p">(</span><span class="kt">uint64_t</span> <span class="o">*</span><span class="n">ht</span><span class="p">,</span> <span class="kt">uint64_t</span> <span class="n">g</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">uint64_t</span> <span class="n">hash</span> <span class="o">=</span> <span class="n">g</span> <span class="o">^</span> <span class="n">g</span><span class="o">&gt;&gt;</span><span class="mi">32</span><span class="p">;</span>
    <span class="kt">size_t</span> <span class="n">mask</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1L</span> <span class="o">&lt;&lt;</span> <span class="n">HASHTAB_EXP</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">size_t</span> <span class="n">step</span> <span class="o">=</span> <span class="n">hash</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="mi">64</span> <span class="o">-</span> <span class="n">HASHTAB_EXP</span><span class="p">)</span> <span class="o">|</span> <span class="mi">1</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="n">hash</span><span class="p">;;)</span> <span class="p">{</span>
        <span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="n">step</span><span class="p">)</span><span class="o">&amp;</span><span class="n">mask</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ht</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">||</span> <span class="n">ht</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&amp;</span><span class="mh">0x3ffffffffffffff</span> <span class="o">==</span> <span class="n">g</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">ht</span> <span class="o">+</span> <span class="n">i</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>To explore a 6-by-6 grid I’d need to change my representation, which is
part of why I didn’t do it. I can’t fit two 36-bit bitboards in a 64-bit
integer, so I’d need to double my storage requirements, which are already
strained.</p>

<h3 id="computational-limitations">Computational limitations</h3>

<p>Due to the way seeds spread, game states resulting from different moves
rarely converge back to a common state later in the tree, so the hash
table isn’t doing much deduplication. Exhaustively exploring the entire
game tree, even cutting it down to an 8th using canonicalization, requires
substantial computing resources, more than I personally have available for
this project. So I had to stop at the slightly weaker form, find a winning
branch rather than maximizing a “score.”</p>

<p>I configure the program to allocate 2GiB for the hash table, but if you
run just a few dozen games off the same table (same program instance),
each exploring different parts of the game tree, you’ll exhaust this
table. A 6-by-6 doubles the memory requirements just to represent the
game, but it also slows the search and substantially increases the width
of the tree, which grows 44% faster. I’m sure it can be done, but it’s
just beyond the resources available to me.</p>

<h3 id="dandelion-puzzles">Dandelion Puzzles</h3>

<p>As a side effect, I wrote a small routine to randomly play out games in
search for “mate-in-two”-style puzzles. The dandelions have two flowers to
place and can force a win with two specific placements — and only those
two placements — regardless of how the wind blows. Here are two of the
better ones, each involving a small trick that I won’t give away here
(note: arrowheads indicate directions wind can still blow):</p>

<p><img src="/img/dandelions/puzzle1.svg" alt="" /></p>

<p><img src="/img/dandelions/puzzle2.svg" alt="" /></p>

<p>There are a variety of potential single-player puzzles of this form.</p>

<ul>
  <li>Cooperative: place a dandelion <em>and</em> pick the wind direction</li>
  <li>Avoidance: <em>don’t</em> seed a particular tile</li>
  <li>Hard ground: certain tiles can’t grow flowers (but still get seeded)</li>
  <li>Weeding: as wind, figure out which flower to remove before blowing</li>
</ul>

<p>There could be a whole “crossword book” of such dandelion puzzles.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>I Solved British Square</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2020/10/19/"/>
    <id>urn:uuid:c500b91a-046f-4320-8eff-9bc8f8443ef3</id>
    <updated>2020-10-19T19:32:52Z</updated>
    <category term="c"/><category term="game"/><category term="ai"/><category term="optimization"/>
    <content type="html">
      <![CDATA[<p><em>Update</em>: I <a href="/blog/2022/10/12/">solved another game</a> using essentially the same
technique.</p>

<p><a href="https://boardgamegeek.com/boardgame/3719/british-square">British Square</a> is a 1978 abstract strategy board game which I
recently discovered <a href="https://www.youtube.com/watch?v=PChKZbut3lM&amp;t=10m">from a YouTube video</a>. It’s well-suited to play
by pencil-and-paper, so my wife and I played a few rounds to try it out.
Curious about strategies, I searched online for analysis and found
nothing whatsoever, meaning I’d have to discover strategies for myself.
This is <em>exactly</em> the sort of problem that <a href="https://xkcd.com/356/">nerd snipes</a>, and so I
sunk a couple of evenings building an analysis engine in C — enough to
fully solve the game and play <em>perfectly</em>.</p>

<p><strong>Repository</strong>: <a href="https://github.com/skeeto/british-square"><strong>British Square Analysis Engine</strong></a>
(and <a href="https://github.com/skeeto/british-square/releases">prebuilt binaries</a>)</p>

<p><a href="/img/british-square/british-square.jpg"><img src="/img/british-square/british-square-thumb.jpg" alt="" /></a>
<!-- Photo credit: Kelsey Wellons --></p>

<!--more-->

<p>The game is played on a 5-by-5 grid with two players taking turns
placing pieces of their color. Pieces may not be placed on tiles
4-adjacent to an opposing piece, and as a special rule, the first player
may not play the center tile on the first turn. Players pass when they
have no legal moves, and the game ends when both players pass. The score
is the difference between the piece counts for each player.</p>

<p>In the default configuration, my engine takes a few seconds to explore
the full game tree, then presents the <a href="https://en.wikipedia.org/wiki/Minimax">minimax</a> values for the
current game state along with the list of perfect moves. The UI allows
manually exploring down the game tree. It’s intended for analysis, but
there’s enough UI present to “play” against the AI should you so wish.
For some of my analysis I made small modifications to the program to
print or count game states matching certain conditions.</p>

<h3 id="game-analysis">Game analysis</h3>

<p>Not accounting for symmetries, there are 4,233,789,642,926,592 possible
playouts. In these playouts, the first player wins 2,179,847,574,830,592
(~51%), the second player wins 1,174,071,341,606,400 (~28%), and the
remaining 879,870,726,489,600 (~21%) are ties. It’s immediately obvious
the first player has a huge advantage.</p>

<p>Accounting for symmetries, there are 8,659,987 total game states. Of
these, 6,955 are terminal states, of which the first player wins 3,599
(~52%) and the second player wins 2,506 (~36%). This small number of
states is what allows the engine to fully explore the game tree in a few
seconds.</p>

<p>Most importantly: <strong>The first player can always win by two points.</strong> In
other words, it’s <em>not</em> like Tic-Tac-Toe where perfect play by both
players results in a tie. Due to the two-point margin, the first player
also has more room for mistakes and usually wins even without perfect
play. There are fewer opportunities to blunder, and a single blunder
usually results in a lower win score. The second player has a narrow
lane of perfect play, making it easy to blunder.</p>

<p>Below is the minimax analysis for the first player’s options. The number
is the first player’s score given perfect play from that point — i.e.
perfect play starts on the tiles marked “2”, and the tiles marked “0”
are blunders that lead to ties.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>11111
12021
10-01
12021
11111
</code></pre></div></div>

<p>The special center rule probably exists to reduce the first player’s
obvious advantage, but in practice it makes little difference. Without
the rule, the first player has an additional (fifth) branch for a win by
two points:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>11111
12021
10201
12021
11111
</code></pre></div></div>

<p>Improved alternative special rule: <strong>Bias the score by two in favor of
the second player.</strong> This fully eliminates the first player’s advantage,
perfect play by both sides results in a tie, and both players have a
narrow lane of perfect play.</p>

<p>The four tie openers are interesting because the reasoning does not
require computer assistance. If the first player opens on any of those
tiles, the second player can mirror each of the first player’s moves,
guaranteeing a tie. Note: The first player can still make mistakes that
results in a second player win <em>if</em> the second player knows when to stop
mirroring.</p>

<p>One of my goals was to develop a heuristic so that even human players
can play perfectly from memory, as in Tic-Tac-Toe. Unfortunately I was
not able to develop any such heuristic, though I <em>was</em> able to prove
that <strong>a greedy heuristic — always claim as much territory as possible —
is often incorrect</strong> and, in some cases, leads to blunders.</p>

<h3 id="engine-implementation">Engine implementation</h3>

<p>As <a href="/blog/2017/04/27/">I’ve done before</a>, my engine represents the game using
<a href="https://www.chessprogramming.org/Bitboards">bitboards</a>. Each player has a 25-bit bitboard representing their
pieces. To make move validation more efficient, it also sometimes tracks
a “mask” bitboard where invalid moves have been masked. Updating all
bitboards is cheap (<code class="language-plaintext highlighter-rouge">place()</code>, <code class="language-plaintext highlighter-rouge">mask()</code>), as is validating moves
against the mask (<code class="language-plaintext highlighter-rouge">valid()</code>).</p>

<p>The longest possible game is 32 moves. This would <em>just</em> fit in 5 bits,
except that I needed a special “invalid” turn, making it a total of 33
bits. So I use 6 bits to store the turn counter.</p>

<p>Besides generally being unnecessary, the validation masks can be derived
from the main bitboards, so I don’t need to store them in the game tree.
That means I need 25 bits per player, and 6 bits for the counter: <strong>56
bits total</strong>. I pack these into a 64-bit integer. The first player’s
bitboard goes in the bottom 25 bits, the second player in the next 25
bits, and the turn counter in the topmost 6 bits. The turn counter
starts at 1, so an all zero state is invalid. I exploit this in the hash
table so that zeroed slots are empty (more on this later).</p>

<p>In other words, the <em>empty</em> state is <code class="language-plaintext highlighter-rouge">0x4000000000000</code> (<code class="language-plaintext highlighter-rouge">INIT</code>) and zero
is the null (invalid) state.</p>

<p>Since the state is so small, rather than passing a pointer to a state to
be acted upon, bitboard functions return a new bitboard with the
requested changes… functional style.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="c1">// Compute bitboard+mask where first play is tile 6</span>
    <span class="c1">// -----</span>
    <span class="c1">// -X---</span>
    <span class="c1">// -----</span>
    <span class="c1">// -----</span>
    <span class="c1">// -----</span>
    <span class="kt">uint64_t</span> <span class="n">b</span> <span class="o">=</span> <span class="n">INIT</span><span class="p">;</span>
    <span class="kt">uint64_t</span> <span class="n">m</span> <span class="o">=</span> <span class="n">INIT</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">place</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
    <span class="n">m</span> <span class="o">=</span> <span class="n">mask</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
</code></pre></div></div>

<h4 id="minimax-costs">Minimax costs</h4>

<p>The engine uses minimax to propagate information up the tree. Since the
search extends to the very bottom of the tree, the minimax “heuristic”
evaluation function is the actual score, not an approximation, which is
why it’s able to play perfectly.</p>

<p>When <a href="/blog/2010/10/17/">I’ve used minimax before</a>, I built an actual tree data
structure in memory, linking states by pointer / reference. In this
engine there is no such linkage, and instead the links are computed
dynamically via the validation masks. Storing the pointers is more
expensive than computing their equivalents on the fly, <em>so I don’t store
them</em>. Therefore my game tree only requires 56 bits per node — or 64
bits in practice since I’m using a 64-bit integer. With only 8,659,987
nodes to store, that’s a mere 66MiB of memory! This analysis could have
easily been done on commodity hardware two decades ago.</p>

<p>What about the minimax values? Game scores range from -10 to 11: 22
distinct values. (That the first player can score up to 11 and the
second player at most 10 is another advantage to going first.) That’s 5
bits of information. However, I didn’t have this information up front,
and so I assumed a range from -25 to 25, which requires 6 bits.</p>

<p>There are still 8 spare bits left in the 64-bit integer, so I use 6 of
them for the minimax score. Rather than worry about two’s complement, I
bias the score to eliminate negative values before storing it. So the
minimax score rides along for free above the state bits.</p>

<h4 id="hash-table-memoization">Hash table (memoization)</h4>

<p>The vast majority of game tree branches are redundant. Even without
taking symmetries into account, nearly all states are reachable from
multiple branches. Exploring all these redundant branches would take
centuries. If I run into a state I’ve seen before, I don’t want to
recompute it.</p>

<p>Once I’ve computed a result, I store it in a hash table so that I can
find it later. Since the state is just a 64-bit integer, I use <a href="/blog/2018/07/31/">an
integer hash function</a> to compute a starting index from which to
linearly probe an open addressing hash table. The <em>entire</em> hash table
implementation is literally a dozen lines of code:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">uint64_t</span> <span class="o">*</span>
<span class="nf">lookup</span><span class="p">(</span><span class="kt">uint64_t</span> <span class="n">bitboard</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="kt">uint64_t</span> <span class="n">table</span><span class="p">[</span><span class="n">N</span><span class="p">];</span>
    <span class="kt">uint64_t</span> <span class="n">mask</span> <span class="o">=</span> <span class="mh">0xffffffffffffff</span><span class="p">;</span> <span class="c1">// sans minimax</span>
    <span class="kt">uint64_t</span> <span class="n">hash</span> <span class="o">=</span> <span class="n">bitboard</span><span class="p">;</span>
    <span class="n">hash</span> <span class="o">*=</span> <span class="mh">0xcca1cee435c5048f</span><span class="p">;</span>
    <span class="n">hash</span> <span class="o">^=</span> <span class="n">hash</span> <span class="o">&gt;&gt;</span> <span class="mi">32</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="n">hash</span> <span class="o">%</span> <span class="n">N</span><span class="p">;</span> <span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">N</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">table</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">||</span> <span class="n">table</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&amp;</span><span class="n">mask</span> <span class="o">==</span> <span class="n">bitboard</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="o">&amp;</span><span class="n">table</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If the bitboard is not found, it returns a pointer to the (zero-valued)
slot where it should go so that the caller can fill it in.</p>

<h4 id="canonicalization">Canonicalization</h4>

<p>Memoization eliminates nearly all redundancy, but there’s still a major
optimization left. Many states are equivalent by symmetry or reflection.
Taking that into account, about 7/8th of the remaining work can still be
eliminated.</p>

<p>Multiple different states that are identical by symmetry must to be
somehow “folded” into a single, <em>canonical</em> state to represent them all.
I do this by visiting all 8 rotations and reflections and choosing the
one with the smallest 64-bit integer representation.</p>

<p>I only need two operations to visit all 8 symmetries, and I chose
transpose (flip around the diagonal) and vertical flip. Alternating
between these operations visits each symmetry. Since they’re bitboards,
transforms can be implemented using <a href="https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating">fancy bit-twiddling hacks</a>.
Chess boards, with their power-of-two dimensions, have useful properties
which these British Square boards lack, so this is the best I could come
up with:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Transpose a board or mask (flip along the diagonal).</span>
<span class="kt">uint64_t</span>
<span class="nf">transpose</span><span class="p">(</span><span class="kt">uint64_t</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00000020000010</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="mi">12</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00000410000208</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span>  <span class="mi">8</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00008208004104</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span>  <span class="mi">4</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00104104082082</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span>  <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xfe082083041041</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span>  <span class="mi">4</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01041040820820</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span>  <span class="mi">8</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00820800410400</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00410000208000</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x00200000100000</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// Flip a board or mask vertically.</span>
<span class="kt">uint64_t</span>
<span class="nf">flipv</span><span class="p">(</span><span class="kt">uint64_t</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="mi">20</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x0000003e00001f</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span> <span class="mi">10</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x000007c00003e0</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&gt;&gt;</span>  <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xfc00f800007c00</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x001f00000f8000</span><span class="p">)</span> <span class="o">|</span>
           <span class="p">((</span><span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="mi">20</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x03e00001f00000</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>These transform both players’ bitboards in parallel while leaving the
turn counter intact. The logic here is quite simple: Shift the bitboard
a little bit at a time while using a mask to deposit bits in their new
home once they’re lined up. It’s like a coin sorter. Vertical flip is
analogous to byte-swapping, though with 5-bit “bytes”.</p>

<p>Canonicalizing a bitboard now looks like this:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">uint64_t</span>
<span class="nf">canonicalize</span><span class="p">(</span><span class="kt">uint64_t</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">uint64_t</span> <span class="n">c</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">transpose</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">flipv</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>     <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">transpose</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">flipv</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>     <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">transpose</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">flipv</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>     <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="n">b</span> <span class="o">=</span> <span class="n">transpose</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">b</span> <span class="o">?</span> <span class="n">c</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">c</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Callers need only use <code class="language-plaintext highlighter-rouge">canonicalize()</code> on values they pass to <code class="language-plaintext highlighter-rouge">lookup()</code>
or store in the table (via the returned pointer).</p>

<h3 id="developing-a-heuristic">Developing a heuristic</h3>

<p>If you can come up with a perfect play heuristic, especially one that
can be reasonably performed by humans, I’d like to hear it. My engine
has a built-in heuristic tester, so I can test it against perfect play
at all possible game positions to check that it actually works. It’s
currently programmed to test the greedy heuristic and print out the
millions of cases where it fails. Even a heuristic that fails in only a
small number of cases would be pretty reasonable.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Two Games with Monte Carlo Tree Search</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2017/04/27/"/>
    <id>urn:uuid:b6f77cb1-01df-3714-4ba0-1859614364da</id>
    <updated>2017-04-27T21:27:50Z</updated>
    <category term="c"/><category term="ai"/><category term="game"/>
    <content type="html">
      <![CDATA[<p><em>Update 2020: A DOS build of Connect Four <a href="https://www.youtube.com/watch?v=K00BylbOQUo">was featured on GET OFF MY
LAWN</a>.</em></p>

<p><a href="https://jeffbradberry.com/posts/2015/09/intro-to-monte-carlo-tree-search/">Monte Carlo tree search</a> (MCTS) is the most impressive game
artificial intelligence I’ve ever used. At its core it simulates a
large number of games (<em>playouts</em>), starting from the current game
state, using random moves for each player. Then it simply picks the
move where it won most often. This description is sufficient to spot
one of its most valuable features: <strong>MCTS requires no knowledge of
strategy or effective play</strong>. The game’s rules — enough to simulate
the game — are all that’s needed to allow the AI to make decent moves.
Expert knowledge still makes for a stronger AI, but, more many games,
it’s unnecessary to construct a decent opponent.</p>

<p>A second valuable feature is that it’s easy to parallelize. Unlike
<a href="/blog/2011/08/24/">alpha-beta pruning</a>, which doesn’t mix well with parallel
searches of a Minimax tree, Monte Carlo simulations are practically
independent and can be run in parallel.</p>

<p>Finally, the third valuable feature is that the search can be stopped
at any time. The completion of any single simulation is as good a
stopping point as any. It could be due to a time limit, a memory
limit, or both. In general, the algorithm <em>converges</em> to a best move
rather than suddenly discovering it. The good moves are identified
quickly, and further simulations work to choose among them. More
simulations make for better moves, with exponentially diminishing
returns. Contrasted with Minimax, stopping early has the risk that the
good moves were never explored at all.</p>

<p>To try out MCTS myself, I wrote two games employing it:</p>

<ul>
  <li><a href="https://github.com/skeeto/connect4"><strong>Connect Four</strong></a> [<a href="https://github.com/skeeto/connect4/releases/download/1.0/connect4.exe">.exe x64</a>, 173kB]</li>
  <li><a href="https://github.com/skeeto/yavalath"><strong>Yavalath</strong></a>      [<a href="https://github.com/skeeto/yavalath/releases/download/1.0/yavalath.exe">.exe x64</a>, 174kB]</li>
</ul>

<p>They’re both written in C, for both unix-like and Windows, and should
be <a href="/blog/2017/03/30/">easy to build</a>. <strong>I challenge you to beat them both.</strong> The
Yavalath AI is easier to beat due to having blind spots, which I’ll
discuss below. The Connect Four AI is more difficult and will likely
take a number of tries.</p>

<h3 id="connect-four">Connect Four</h3>

<p><a href="/img/mcts/connect4.png"><img src="/img/mcts/connect4-thumb.png" alt="" /></a></p>

<p>MCTS works very well with Connect Four, and only requires modest
resources: 32MB of memory to store the results of random playouts, and
500,000 game simulations. With a few tweaks, it can even be run in
DOSBox. It stops when it hits either of those limits. In theory,
increasing both would make for stronger moves, but in practice I can’t
detect any difference. It’s like <a href="https://curiosity-driven.org/pi-approximation">computing pi with Monte Carlo</a>,
where eventually it just runs out of precision to make any more
progress.</p>

<p>Based on my simplified description above, you might wonder why it needs
all that memory. Not only does MCTS need to track its win/loss ratio for
each available move from the current state, it tracks the win/loss ratio
for moves in the states behind those moves. A large chunk of the game
tree is kept in memory to track all of the playout results. This is why
MCTS needs a lot more memory than Minimax, which can discard branches
that have been searched.</p>

<p><img src="/img/mcts/tree.svg" alt="" /></p>

<p>A convenient property of this tree is that the branch taken in the
actual game can be re-used in a future search. The root of the tree
becomes the node representing the taken game state, which has already
seen a number of playouts. Even better, MCTS is weighted towards
exploring good moves over bad moves, and good moves are more likely to
be taken in the real game. In general, a significant portion of the tree
gets to be reused in a future search.</p>

<p>I’m going to skip most of the details of the algorithm itself and focus
on my implementation. Other articles do a better job at detailing the
algorithm than I could.</p>

<p>My Connect Four engine doesn’t use dynamic allocation for this tree (or
at all). Instead it manages a static buffer — an array of tree nodes,
each representing a game state. All nodes are initially chained together
into a linked list of free nodes. As the tree is built, nodes are pulled
off the free list and linked together into a tree. When the game
advances to the next state, nodes on unreachable branches are added back
to the free list.</p>

<p>If at any point the free list is empty when a new node is needed, the
current search aborts. This is the out-of-memory condition, and no more
searching can be performed.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* Connect Four is normally a 7 by 6 grid. */</span>
<span class="cp">#define CONNECT4_WIDTH  7
#define CONNECT4_HEIGHT 6
</span>
<span class="k">struct</span> <span class="n">connect4_node</span> <span class="p">{</span>
    <span class="kt">uint32_t</span> <span class="n">next</span><span class="p">[</span><span class="n">CONNECT4_WIDTH</span><span class="p">];</span>      <span class="c1">// "pointer" to next node</span>
    <span class="kt">uint32_t</span> <span class="n">playouts</span><span class="p">[</span><span class="n">CONNECT4_WIDTH</span><span class="p">];</span>  <span class="c1">// number of playouts</span>
    <span class="kt">float</span>    <span class="n">score</span><span class="p">[</span><span class="n">CONNECT4_WIDTH</span><span class="p">];</span>     <span class="c1">// pseudo win/loss ratio</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Rather than native C pointers, the structure uses 32-bit indexes into
the master array. This saves a lot of memory on 64-bit systems, and the
structure is the same size no matter the pointer size of the host. The
<code class="language-plaintext highlighter-rouge">next</code> field points to the next state for the nth move. Since 0 is a
valid index, -1 represents null (<code class="language-plaintext highlighter-rouge">CONNECT4_NULL</code>).</p>

<p>Each column is a potential move, so there are <code class="language-plaintext highlighter-rouge">CONNECT4_WIDTH</code>
possible moves at any given state. Each move has a floating point
score and a total number of playouts through that move. In my
implementation, <strong>the search can also halt due to an overflow in a
playout counter</strong>. The search can no longer be tracked in this
representation, so it has to stop. This generally only happens when
the game is nearly over and it’s grinding away on a small number of
possibilities.</p>

<p>Note that the actual game state (piece positions) is not tracked in the
node structure. That’s because it’s implicit. We know the state of the
game at the root, and simulating the moves while descending the tree
will keep track of the board state at the current node. That’s more
memory savings.</p>

<p>The state itself is a pair of bitboards, one for each player. Each
position on the grid gets a bit on each bitboard. The bitboard is very
fast to manipulate, and win states are checked with just a handful of
bit operations. My intention was to make playouts as fast as possible.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">connect4_ai</span> <span class="p">{</span>
    <span class="kt">uint64_t</span> <span class="n">state</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>         <span class="c1">// game state at root (bitboard)</span>
    <span class="kt">uint64_t</span> <span class="n">rng</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>           <span class="c1">// random number generator state</span>
    <span class="kt">uint32_t</span> <span class="n">nodes_available</span><span class="p">;</span>  <span class="c1">// total number of nodes available</span>
    <span class="kt">uint32_t</span> <span class="n">nodes_allocated</span><span class="p">;</span>  <span class="c1">// number of nodes in the tree</span>
    <span class="kt">uint32_t</span> <span class="n">root</span><span class="p">;</span>             <span class="c1">// "pointer" to root node</span>
    <span class="kt">uint32_t</span> <span class="n">free</span><span class="p">;</span>             <span class="c1">// "pointer" to free list</span>
    <span class="kt">int</span> <span class="n">turn</span><span class="p">;</span>                  <span class="c1">// whose turn (0 or 1) at the root?</span>
<span class="p">};</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">nodes_available</code> and <code class="language-plaintext highlighter-rouge">nodes_allocated</code> are not necessary for
correctness nor speed. They’re useful for diagnostics and debugging.</p>

<p>All the functions that operate on these two structures are
straightforward, except for <code class="language-plaintext highlighter-rouge">connect4_playout</code>, a recursive function
which implements the bulk of MCTS. Depending on the state of the node
it’s at, it does one of two things:</p>

<ul>
  <li>
    <p>If there are unexplored moves (<code class="language-plaintext highlighter-rouge">playouts == 0</code>), it randomly chooses
an unplayed move, allocates exactly one node for the state behind that
move, and simulates the rest of the game in a loop, without recursion
or allocating any more nodes.</p>
  </li>
  <li>
    <p>If all moves have been explored at least once, it uses an upper
confidence bound (UCB1) to randomly choose a move, weighed towards
both moves that are under-explored and moves which are strongest.
Striking that balance is one of the challenges. It recurses into that
next state, then updates the node with the result as it propagates
back to the root.</p>
  </li>
</ul>

<p>That’s pretty much all there is to it.</p>

<h3 id="yavalath">Yavalath</h3>

<p><a href="/img/mcts/yavalath.png"><img src="/img/mcts/yavalath-thumb.png" alt="" /></a></p>

<p><a href="http://cambolbro.com/games/yavalath/">Yavalath</a> is a <a href="http://www.genetic-programming.org/hc2012/Browne-Paper-3-Yavalath-07.pdf">board game invented by a computer
program</a>. It’s a pretty fascinating story. The depth and strategy
are disproportionately deep relative to its dead simple rules: Get four
in a row without first getting three in a row. The game revolves around
forced moves.</p>

<p>The engine is structured almost identically to the Connect Four engine.
It uses 32-bit indexes instead of pointers. The game state is a pair of
bitboards, with end-game masks <a href="/blog/2016/11/15/">computed at compile time via
metaprogramming</a>. The AI allocates the tree from a single, massive
buffer — multiple GBs in this case, dynamically scaled to the available
physical memory. And the core MCTS function is nearly identical.</p>

<p>One important difference is that identical game states — states where
the pieces on the board are the same, but the node was reached through
a different series of moves — are coalesced into a single state in the
tree. This state deduplication is done through a hash table. This
saves on memory and allows multiple different paths through the game
tree to share playouts. It comes at a cost of including the game state
in the node (so it can be identified in the hash table) and reference
counting the nodes (since they might have more than one parent).</p>

<p>Unfortunately the AI has blind spots, and once you learn to spot them it
becomes easy to beat consistently. It can’t spot certain kinds of forced
moves, so it always falls for the same tricks. The <em>official</em> Yavalath
AI is slightly stronger than mine, but has a similar blindness. I think
MCTS just isn’t quite a good fit for Yavalath.</p>

<p><strong>The AI’s blindness is caused by <em>shallow traps</em></strong>, a common problem
for MCTS. It’s what makes MCTS a poor fit for Chess. A shallow trap is
a branch in the game tree where the game will abruptly end in a small
number of turns. If the random tree search doesn’t luckily stumble
upon a trap during its random traversal, it can’t take it into account
in its final decision. A skilled player will lead the game towards one
of these traps, and the AI will blunder along, not realizing what’s
happened until its too late.</p>

<p>I almost feel bad for it when this happens. If you watch the memory
usage and number of playouts, once it falls into a trap, you’ll see it
using almost no memory while performing a ton of playouts. It’s
desperately, frantically searching for a way out of the trap. But it’s
too late, little AI.</p>

<h3 id="another-tool-in-the-toolbelt">Another Tool in the Toolbelt</h3>

<p>I’m really happy to have sunk a couple weekends into playing with MCTS.
It’s not always a great fit, as seen with Yavalath, but it’s a really
neat algorithm. Now that I’ve wrapped my head around it, I’ll be ready
to use it should I run into an appropriate problem in the future.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Goblin-COM 7DRL 2015</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2015/03/15/"/>
    <id>urn:uuid:362ccedf-9538-358f-9474-5befd8bce4de</id>
    <updated>2015-03-15T21:56:12Z</updated>
    <category term="game"/><category term="media"/><category term="win32"/><category term="c"/>
    <content type="html">
      <![CDATA[<p>Yesterday I completed my third entry to the annual Seven Day Roguelike
(7DRL) challenge (previously: <a href="/blog/2013/03/17/">2013</a> and <a href="/blog/2014/03/31/">2014</a>). This
year’s entry is called <strong>Goblin-COM</strong>.</p>

<p><a href="/img/screenshot/gcom.png"><img src="/img/screenshot/gcom-thumb.png" alt="" /></a></p>

<ul>
  <li>Download/Source: <a href="https://github.com/skeeto/goblin-com">Goblin-COM</a></li>
  <li>Telnet play (no saves): <code class="language-plaintext highlighter-rouge">telnet gcom.nullprogram.com</code></li>
  <li><a href="https://www.youtube.com/watch?v=QW3Uul7-Iss">Video review</a> by Akhier Dragonheart</li>
</ul>

<p>As with previous years, the ideas behind the game are not all that
original. The goal was to be a fantasy version of <a href="http://en.wikipedia.org/wiki/UFO:_Enemy_Unknown">classic
X-COM</a> with an ANSI terminal interface. You are the ruler of a
fledgling human nation that is under attack by invading goblins. You
hire heroes, operate squads, construct buildings, and manage resource
income.</p>

<p>The inspiration this year came from watching <a href="https://www.youtube.com/playlist?list=PL2xITSnTC0YkB2-B8fs-02YVT81AE0WtP">BattleBunny</a> play
<a href="http://openxcom.org/">OpenXCOM</a>, an open source clone of the original X-COM. It
had its major 1.0 release last year. Like the early days of
<a href="https://www.openttd.org/en/">OpenTTD</a>, it currently depends on the original game assets.
But also like OpenTTD, it surpasses the original game in every way, so
there’s no reason to bother running the original anymore. I’ve also
recently been watching <a href="https://youtu.be/bwPLKud0rP4">One F Jef play Silent Storm</a>, which is
another turn-based squad game with a similar combat simulation.</p>

<p>As in X-COM, the game is broken into two modes of play: the geoscape
(strategic) and the battlescape (tactical). Unfortunately I ran out of
time and didn’t get to the battlescape part, though I’d like to add it
in the future. What’s left is a sort-of city-builder with some squad
management. You can hire heroes and send them out in squads to
eliminate goblins, but rather than dropping to the battlescape,
battles always auto-resolve in your favor. Despite this, the game
still has a story, a win state, and a lose state. I won’t say what
they are, so you have to play it for yourself!</p>

<h3 id="terminal-emulator-layer">Terminal Emulator Layer</h3>

<p>My previous entries were HTML5 games, but this entry is a plain old
standalone application. C has been my preferred language for the past
few months, so that’s what I used. Both UTF-8-capable ANSI terminals
and the Windows console are supported, so it should be perfectly
playable on any modern machine. Note, though, that some of the
poorer-quality terminal emulators that you’ll find in your Linux
distribution’s repositories (rxvt and its derivatives) are not
Unicode-capable, which means they won’t work with G-COM.</p>

<p>I <strong>didn’t make use of ncurses</strong>, instead opting to write my own
terminal graphics engine. That’s because I wanted a <a href="/blog/2014/12/09/">single, small
binary</a> that was easy to build, and I didn’t want to mess around
with <a href="http://pdcurses.sourceforge.net/">PDCurses</a>. I’ve also been studying the Win32 API lately, so
writing my own terminal platform layer would rather easy to do anyway.</p>

<p>I experimented with a number of terminal emulators — LXTerminal,
Konsole, GNOME/MATE terminal, PuTTY, xterm, mintty, Terminator — but
the least capable “terminal” <em>by far</em> is the Windows console, so it
was the one to dictate the capabilities of the graphics engine. Some
ANSI terminals are capable of 256 colors, bold, underline, and
strikethrough fonts, but a highly portable API is basically <strong>limited
to 16 colors</strong> (RGBCMYKW with two levels of intensity) for each of the
foreground and background, and no other special text properties.</p>

<p>ANSI terminals also have a concept of a default foreground color and a
default background color. Most applications that output color (git,
grep, ls) leave the background color alone and are careful to choose
neutral foreground colors. G-COM always sets the background color, so
that the game looks the same no matter what the default colors are.
Also, the Windows console doesn’t really have default colors anyway,
even if I wanted to use them.</p>

<p>I put in partial support for Unicode because I wanted to use
interesting characters in the game (≈, ♣, ∩, ▲). Windows has supported
Unicode for a long time now, but since they added it <em>too</em> early,
they’re locked into the <a href="http://utf8everywhere.org/">outdated UTF-16</a>. For me this wasn’t
too bad, because few computers, Linux included, are equipped to render
characters outside of the <a href="http://en.wikipedia.org/wiki/Plane_(Unicode)">Basic Multilingual Plane</a> anyway, so
there’s no need to deal with surrogate pairs. This is especially true
for the Windows console, which can only render a <em>very</em> small set of
characters: another limit on my graphics engine. Internally individual
codepoints are handled as <code class="language-plaintext highlighter-rouge">uint16_t</code> and strings are handled as UTF-8.</p>

<p>I said <em>partial</em> support because, in addition to the above, it has no
support for combining characters, or any other situation where a
codepoint takes up something other than one space in the terminal.
This requires lookup tables and dealing with <a href="/blog/2014/06/13/">pitfalls</a>, but
since I get to control exactly which characters were going to be used
I didn’t need any of that.</p>

<p>In spite of the limitations, I’m <em>really</em> happy with the graphical
results. The waves are animated continuously, even while the game is
paused, and it looks great. Here’s GNOME Terminal’s rendering, which I
think looked the best by default.</p>

<video width="480" height="400" controls="" loop="" autoplay="">
  <source src="/vid/gcom.webm" type="video/webm" />
  <source src="/vid/gcom.mp4" type="video/mp4" />
</video>

<p>I’ll talk about how G-COM actually communicates with the terminal in
another article. The interface between the game and the graphics
engine is really clean (<code class="language-plaintext highlighter-rouge">device.h</code>), so it would be an interesting
project to write a back end that renders the game to a regular window,
no terminal needed.</p>

<h4 id="color-directive">Color Directive</h4>

<p>I came up with a format directive to help me colorize everything. It
runs in addition to the standard <code class="language-plaintext highlighter-rouge">printf</code> directives. Here’s an example,</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">panel_printf</span><span class="p">(</span><span class="o">&amp;</span><span class="n">panel</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s">"Really save and quit? (Rk{y}/Rk{n})"</span><span class="p">);</span>
</code></pre></div></div>

<p>The color is specified by two characters, and the text it applies to
is wrapped in curly brackets. There are eight colors to pick from:
RGBCMYKW. That covers all the binary values for red, green, and blue.
To specify an “intense” (bright) color, capitalize it. That means the
<code class="language-plaintext highlighter-rouge">Rk{...}</code> above makes the wrapped text bright red.</p>

<p><img src="/img/screenshot/gcom-yn.png" alt="" /></p>

<p>Nested directives are also supported. (And, yes, that <code class="language-plaintext highlighter-rouge">K</code> means “high
intense black,” a.k.a. dark gray. A <code class="language-plaintext highlighter-rouge">w</code> means “low intensity white,”
a.k.a. light gray.)</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">panel_printf</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="o">++</span><span class="p">,</span> <span class="s">"Kk{♦}    wk{Rk{B}uild}     Kk{♦}"</span><span class="p">);</span>
</code></pre></div></div>

<p>And it mixes with the normal <code class="language-plaintext highlighter-rouge">printf</code> directives:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">panel_printf</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">y</span><span class="o">++</span><span class="p">,</span> <span class="s">"(Rk{m}) Yk{Mine} [%s]"</span><span class="p">,</span> <span class="n">cost</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="single-binary">Single Binary</h3>

<p>The GNU linker has a really nice feature for linking arbitrary binary
data into your application. I used this to embed my assets into a
single binary so that the user doesn’t need to worry about any sort of
data directory or anything like that. Here’s what the <code class="language-plaintext highlighter-rouge">make</code> rule
would look like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$(LD) -r -b binary -o $@ $^
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">-r</code> specifies that output should be relocatable — i.e. it can be
fed back into the linker later when linking the final binary. The <code class="language-plaintext highlighter-rouge">-b
binary</code> says that the input is just an opaque binary file (“plain”
text included). The linker will create three symbols for each input
file:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">_binary_filename_start</code></li>
  <li><code class="language-plaintext highlighter-rouge">_binary_filename_end</code></li>
  <li><code class="language-plaintext highlighter-rouge">_binary_filename_size</code></li>
</ul>

<p>When then you can access from your C program like so:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">extern</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">_binary_filename_txt_start</span><span class="p">[];</span>
</code></pre></div></div>

<p>I used this to embed the story texts, and I’ve used it in the past to
embed images and textures. If you were to link zlib, you could easily
compress these assets, too. I’m surprised this sort of thing isn’t
done more often!</p>

<h3 id="dumb-game-saves">Dumb Game Saves</h3>

<p>To save time, and because it doesn’t really matter, saves are just
memory dumps. I took another page from <a href="http://handmadehero.org/">Handmade Hero</a> and
allocate everything in a single, contiguous block of memory. With one
exception, there are no pointers, so the entire block is relocatable.
When references are needed, it’s done via integers into the embedded
arrays. This allows it to be cleanly reloaded in another process
later. As a side effect, it also means there are no dynamic
allocations (<code class="language-plaintext highlighter-rouge">malloc()</code>) while the game is running. Here’s roughly
what it looks like.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="k">struct</span> <span class="n">game</span> <span class="p">{</span>
    <span class="kt">uint64_t</span> <span class="n">map_seed</span><span class="p">;</span>
    <span class="n">map_t</span> <span class="o">*</span><span class="n">map</span><span class="p">;</span>
    <span class="kt">long</span> <span class="n">time</span><span class="p">;</span>
    <span class="kt">float</span> <span class="n">wood</span><span class="p">,</span> <span class="n">gold</span><span class="p">,</span> <span class="n">food</span><span class="p">;</span>
    <span class="kt">long</span> <span class="n">population</span><span class="p">;</span>
    <span class="kt">float</span> <span class="n">goblin_spawn_rate</span><span class="p">;</span>
    <span class="n">invader_t</span> <span class="n">invaders</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
    <span class="n">squad_t</span> <span class="n">squads</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
    <span class="n">hero_t</span> <span class="n">heroes</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
    <span class="n">game_event_t</span> <span class="n">events</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
<span class="p">}</span> <span class="n">game_t</span><span class="p">;</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">map</code> pointer is that one exception, but that’s because it’s
generated fresh after loading from the <code class="language-plaintext highlighter-rouge">map_seed</code>. Saving and loading
is trivial (error checking omitted) and <em>very</em> fast.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span>
<span class="nf">game_save</span><span class="p">(</span><span class="n">game_t</span> <span class="o">*</span><span class="n">game</span><span class="p">,</span> <span class="kt">FILE</span> <span class="o">*</span><span class="n">out</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">fwrite</span><span class="p">(</span><span class="n">game</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">game</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="n">out</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">game_t</span> <span class="o">*</span>
<span class="nf">game_load</span><span class="p">(</span><span class="kt">FILE</span> <span class="o">*</span><span class="n">in</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">game_t</span> <span class="o">*</span><span class="n">game</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">game</span><span class="p">));</span>
    <span class="n">fread</span><span class="p">(</span><span class="n">game</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">game</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="n">in</span><span class="p">);</span>
    <span class="n">game</span><span class="o">-&gt;</span><span class="n">map</span> <span class="o">=</span> <span class="n">map_generate</span><span class="p">(</span><span class="n">game</span><span class="o">-&gt;</span><span class="n">map_seed</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">game</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The data isn’t important enough to bother with <a href="http://lwn.net/Articles/322823/">rename+fsync</a>
durability. I’ll risk the data if it makes savescumming that much
harder!</p>

<p>The downside to this technique is that saves are generally not
portable across architectures (particularly where endianness differs),
and may not even portable between different platforms on the same
architecture. I only needed to persist a single game state on the same
machine, so this wouldn’t be a problem.</p>

<h3 id="final-results">Final Results</h3>

<p>I’m definitely going to be reusing some of this code in future
projects. The G-COM terminal graphics layer is nifty, and I already
like it better than ncurses, whose API I’ve always thought was kind of
ugly and old-fashioned. I like writing terminal applications.</p>

<p>Just like the last couple of years, the final game is a lot simpler
than I had planned at the beginning of the week. Most things take
longer to code than I initially expect. I’m still enjoying playing it,
which is a really good sign. When I play, I’m having enough fun to
deliberately delay the end of the game so that I can sprawl my nation
out over the island and generate crazy income.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  <entry>
    <title>How to build DOS COM files with GCC</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2014/12/09/"/>
    <id>urn:uuid:cff7d942-a91d-38b8-46fd-d05bbce0e212</id>
    <updated>2014-12-09T23:50:10Z</updated>
    <category term="c"/><category term="debian"/><category term="tutorial"/><category term="game"/>
    <content type="html">
      <![CDATA[<p><em>Update 2018: RenéRebe builds upon this article in an <a href="https://www.youtube.com/watch?v=Y7vU5T6rKHE">interesting
follow-up video</a> (<a href="https://www.youtube.com/watch?v=EXiF7g8Hmt4">part 2</a>).</em></p>

<p><em>Update 2020: DOS Defender <a href="https://www.youtube.com/watch?v=6UjuFnZYkG4">was featured on GET OFF MY LAWN</a>.</em></p>

<p>This past weekend I participated in <a href="http://ludumdare.com/compo/2014/12/03/welcome-to-ludum-dare-31/">Ludum Dare #31</a>. Before the
theme was even announced, due to <a href="/blog/2014/11/22/">recent fascination</a> I wanted
to make an old school DOS game. DOSBox would be the target platform
since it’s the most practical way to run DOS applications anymore,
despite modern x86 CPUs still being fully backwards compatible all the
way back to the 16-bit 8086.</p>

<p>I successfully created and submitted a DOS game called <a href="http://ludumdare.com/compo/ludum-dare-31/?uid=8472">DOS
Defender</a>. It’s a 32-bit 80386 real mode DOS COM program. All
assets are embedded in the executable and there are no external
dependencies, so the entire game is packed into that 10kB binary.</p>

<ul>
  <li><a href="https://github.com/skeeto/dosdefender-ld31">https://github.com/skeeto/dosdefender-ld31</a></li>
  <li><a href="https://github.com/skeeto/dosdefender-ld31/releases/download/1.1.0/DOSDEF.COM">DOSDEF.COM</a> (10kB, v1.1.0, run in DOSBox)</li>
</ul>

<p><img src="/img/screenshot/dosdefender.gif" alt="" /></p>

<p>You’ll need a joystick/gamepad in order to play. I included mouse
support in the Ludum Dare release in order to make it easier to
review, but this was removed because it doesn’t work well.</p>

<p>The most technically interesting part is that <strong>I didn’t need <em>any</em>
DOS development tools to create this</strong>! I only used my every day Linux
C compiler (<code class="language-plaintext highlighter-rouge">gcc</code>). It’s not actually possible to build DOS Defender
in DOS. Instead, I’m treating DOS as an embedded platform, which is
the only form in which <a href="http://www.freedos.org/">DOS still exists today</a>. Along with
DOSBox and <a href="http://www.dosemu.org/">DOSEMU</a>, this is a pretty comfortable toolchain.</p>

<p>If all you care about is how to do this yourself, skip to the
“Tricking GCC” section, where we’ll write a “Hello, World” DOS COM
program with Linux’s GCC.</p>

<h3 id="finding-the-right-tools">Finding the right tools</h3>

<p>I didn’t have GCC in mind when I started this project. What really
triggered all of this was that I had noticed Debian’s <a href="http://linux.die.net/man/1/bcc">bcc</a>
package, Bruce’s C Compiler, that builds 16-bit 8086 binaries. It’s
kept around for compiling x86 bootloaders and such, but it can also be
used to compile DOS COM files, which was the part that interested me.</p>

<p>For some background: the Intel 8086 was a 16-bit microprocessor
released in 1978. It had none of the fancy features of today’s CPU: no
memory protection, no floating point instructions, and only up to 1MB
of RAM addressable. All modern x86 desktops and laptops can still
pretend to be a 40-year-old 16-bit 8086 microprocessor, with the same
limited addressing and all. That’s some serious backwards
compatibility. This feature is called <em>real mode</em>. It’s the mode in
which all x86 computers boot. Modern operating systems switch to
<em>protected mode</em> as soon as possible, which provides virtual
addressing and safe multi-tasking. DOS is not one of these operating
systems.</p>

<p>Unfortunately, bcc is not an ANSI C compiler. It supports a subset of
K&amp;R C, along with inline x86 assembly. Unlike other 8086 C compilers,
it has no notion of “far” or “long” pointers, so inline assembly is
required to access <a href="http://en.wikipedia.org/wiki/X86_memory_segmentation">other memory segments</a> (VGA, clock, etc.).
Side note: the remnants of these 8086 “long pointers” still exists
today in the Win32 API: <code class="language-plaintext highlighter-rouge">LPSTR</code>, <code class="language-plaintext highlighter-rouge">LPWORD</code>, <code class="language-plaintext highlighter-rouge">LPDWORD</code>, etc. The inline
assembly isn’t anywhere near as nice as GCC’s inline assembly. The
assembly code has to manually load variables from the stack so, since
bcc supports two different calling conventions, the assembly ends up
being hard-coded to one calling convention or the other.</p>

<p>Given all its limitations, I went looking for alternatives.</p>

<h3 id="djgpp">DJGPP</h3>

<p><a href="http://www.delorie.com/djgpp/">DJGPP</a> is the DOS port of GCC. It’s a very impressive project,
bringing almost all of POSIX to DOS. The DOS ports of many programs
are built with DJGPP. In order to achieve this, it only produces
32-bit protected mode programs. If a protected mode program needs to
manipulate hardware (i.e. VGA), it must make requests to a <a href="http://en.wikipedia.org/wiki/DOS_Protected_Mode_Interface">DOS
Protected Mode Interface</a> (DPMI) service. If I used DJGPP, I
couldn’t make a single, standalone binary as I had wanted, since I’d
need to include a DPMI server. There’s also a performance penalty for
making DPMI requests.</p>

<p>Getting a DJGPP toolchain working can be difficult, to put it kindly.
Fortunately I found a useful project, <a href="https://github.com/andrewwutw/build-djgpp">build-djgpp</a>, that makes
it easy, at least on Linux.</p>

<p>Either there’s a serious bug or the official DJGPP binaries <a href="http://www.delorie.com/djgpp/v2faq/faq6_7.html">have
become infected again</a>, because in my testing I kept getting
the “Not COFF: check for viruses” error message when running my
programs in DOSBox. To double check that it’s not an infection on my
own machine, I set up a DJGPP toolchain on my Raspberry Pi, to act as
a clean room. It’s impossible for this ARM-based device to get
infected with an x86 virus. It still had the same problem, and all the
binary hashes matched up between the machines, so it’s not my fault.</p>

<p>So given the DPMI issue and the above, I moved on.</p>

<h3 id="tricking-gcc">Tricking GCC</h3>

<p>What I finally settled on is a neat hack that involves “tricking” GCC
into producing real mode DOS COM files, so long as it can target 80386
(as is usually the case). The 80386 was released in 1985 and was the
first 32-bit x86 microprocessor. GCC still targets this instruction
set today, even in the x86-64 toolchain. Unfortunately, GCC cannot
actually produce 16-bit code, so my main goal of targeting 8086 would
not be achievable. This doesn’t matter, though, since DOSBox, my
intended platform, is an 80386 emulator.</p>

<p>In theory this should even work unchanged with MinGW, but there’s a
long-standing MinGW bug that prevents it from working right (“cannot
perform PE operations on non PE output file”). It’s still do-able, and
I did it myself, but you’ll need to drop the <code class="language-plaintext highlighter-rouge">OUTPUT_FORMAT</code> directive
and add an extra <code class="language-plaintext highlighter-rouge">objcopy</code> step (<code class="language-plaintext highlighter-rouge">objcopy -O binary</code>).</p>

<h4 id="hello-world-in-dos">Hello World in DOS</h4>

<p>To demonstrate how to do all this, let’s make a DOS “Hello, World” COM
program using GCC on Linux.</p>

<p>There’s a significant burden with this technique: <strong>there will be no
standard library</strong>. It’s basically like writing an operating system
from scratch, except for the few services DOS provides. This means no
<code class="language-plaintext highlighter-rouge">printf()</code> or anything of the sort. Instead we’ll ask DOS to print a
string to the terminal. Making a request to DOS means firing an
interrupt, which means inline assembly!</p>

<p>DOS has nine interrupts: 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x2F. The big one, and the one we’re interested in, is 0x21,
function 0x09 (print string). Between DOS and BIOS, there are
<a href="http://www.o3one.org/hwdocs/bios_doc/dosref22.html">thousands of functions called this way</a>. I’m not going to try
to explain x86 assembly, but in short the function number is stuffed
into register <code class="language-plaintext highlighter-rouge">ah</code> and interrupt 0x21 is fired. Function 0x09 also
takes an argument, the pointer to the string to be printed, which is
passed in registers <code class="language-plaintext highlighter-rouge">dx</code> and <code class="language-plaintext highlighter-rouge">ds</code>.</p>

<p>Here’s the GCC inline assembly <code class="language-plaintext highlighter-rouge">print()</code> function. Strings passed to
this function must be terminated with a <code class="language-plaintext highlighter-rouge">$</code>. Why? Because DOS.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">void</span> <span class="nf">print</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">string</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">asm</span> <span class="k">volatile</span> <span class="p">(</span><span class="s">"mov   $0x09, %%ah</span><span class="se">\n</span><span class="s">"</span>
                  <span class="s">"int   $0x21</span><span class="se">\n</span><span class="s">"</span>
                  <span class="o">:</span> <span class="cm">/* no output */</span>
                  <span class="o">:</span> <span class="s">"d"</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
                  <span class="o">:</span> <span class="s">"ah"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The assembly is declared <code class="language-plaintext highlighter-rouge">volatile</code> because it has a side effect
(printing the string). To GCC, the assembly is an opaque hunk, and the
optimizer relies in the output/input/clobber constraints (the last
three lines). For DOS programs like this, all inline assembly will
have side effects. This is because it’s not being written for
optimization but to access hardware and DOS, things not accessible to
plain C.</p>

<p>Care must also be taken by the caller, because GCC doesn’t know that
the memory pointed to by <code class="language-plaintext highlighter-rouge">string</code> is ever read. It’s likely the array
that backs the string needs to be declared <code class="language-plaintext highlighter-rouge">volatile</code> too. This is all
foreshadowing into what’s to come: doing anything in this environment
is an endless struggle against the optimizer. Not all of these battles
can be won.</p>

<p>Now for the main function. The name of this function shouldn’t matter,
but I’m avoiding calling it <code class="language-plaintext highlighter-rouge">main()</code> since MinGW has a funny ideas
about mangling this particular symbol, even when it’s asked not to.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">dosmain</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">print</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">$"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>COM files are limited to 65,279 bytes in size. This is because an x86
memory segment is 64kB and COM files are simply loaded by DOS to
0x0100 in the segment and executed. There are no headers, it’s just a
raw binary. Since a COM program can never be of any significant size,
and no real linking needs to occur (freestanding), the entire thing
will be compiled as one translation unit. It will be one call to GCC
with a bunch of options.</p>

<h4 id="compiler-options">Compiler Options</h4>

<p>Here are the essential compiler options.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-std=gnu99 -Os -nostdlib -m32 -march=i386 -ffreestanding
</code></pre></div></div>

<p>Since no standard libraries are in use, the only difference between
gnu99 and c99 is that trigraphs are disabled (as they should be) and
inline assembly can be written as <code class="language-plaintext highlighter-rouge">asm</code> instead of <code class="language-plaintext highlighter-rouge">__asm__</code>. It’s a
no brainer. This project will be so closely tied to GCC that I don’t
care about using GCC extensions anyway.</p>

<p>I’m using <code class="language-plaintext highlighter-rouge">-Os</code> to keep the compiled output as small as possible. It
will also make the program run faster. This is important when
targeting DOSBox because, by default, it will deliberately run as slow
as a machine from the 1980’s. I want to be able to fit in that
constraint. If the optimizer is causing problems, you may need to
temporarily make this <code class="language-plaintext highlighter-rouge">-O0</code> to determine if the problem is your fault
or the optimizer’s fault.</p>

<p>You see, the optimizer doesn’t understand that the program will be
running in real mode, and under its addressing constraints. <strong>It will
perform all sorts of invalid optimizations that break your perfectly
valid programs.</strong> It’s not a GCC bug since we’re doing crazy stuff
here. I had to rework my code a number of times to stop the optimizer
from breaking my program. For example, I had to avoid returning
complex structs from functions because they’d sometimes be filled with
garbage. The real danger here is that a future version of GCC will be
more clever and will break more stuff. In this battle, <code class="language-plaintext highlighter-rouge">volatile</code> is
your friend.</p>

<p>Th next option is <code class="language-plaintext highlighter-rouge">-nostdlib</code>, since there are no valid libraries for
us to link against, even statically.</p>

<p>The options <code class="language-plaintext highlighter-rouge">-m32 -march=i386</code> set the compiler to produce 80386 code.
If I was writing a bootloader for a modern computer, targeting 80686
would be fine, too, but DOSBox is 80386.</p>

<p>The <code class="language-plaintext highlighter-rouge">-ffreestanding</code> argument requires that GCC not emit code that
calls built-in standard library helper functions. Sometimes instead of
emitting code to do something, it emits code that calls a built-in
function to do it, especially with math operators. This was one of the
main problems I had with bcc, where this behavior couldn’t be
disabled. This is most commonly used in writing bootloaders and
kernels. And now DOS COM files.</p>

<h4 id="linker-options">Linker Options</h4>

<p>The <code class="language-plaintext highlighter-rouge">-Wl</code> option is used to pass arguments to the linker (<code class="language-plaintext highlighter-rouge">ld</code>). We
need it since we’re doing all this in one call to GCC.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-Wl,--nmagic,--script=com.ld
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">--nmagic</code> turns off page alignment of sections. One, we don’t
need this. Two, that would waste precious space. In my tests it
doesn’t appear to be necessary, but I’m including it just in case.</p>

<p>The <code class="language-plaintext highlighter-rouge">--script</code> option tells the linker that we want to use a custom
<a href="http://wiki.osdev.org/Linker_Scripts">linker script</a>. This allows us to precisely lay out the sections
(<code class="language-plaintext highlighter-rouge">text</code>, <code class="language-plaintext highlighter-rouge">data</code>, <code class="language-plaintext highlighter-rouge">bss</code>, <code class="language-plaintext highlighter-rouge">rodata</code>) of our program. Here’s the <code class="language-plaintext highlighter-rouge">com.ld</code>
script.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0100;
    .text :
    {
        *(.text);
    }
    .data :
    {
        *(.data);
        *(.bss);
        *(.rodata);
    }
    _heap = ALIGN(4);
}
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">OUTPUT_FORMAT(binary)</code> says not to put this into an ELF (or PE,
etc.) file. The linker should just dump the raw code. A COM file is
just raw code, so this means the linker will produce a COM file!</p>

<p>I had said that COM files are loaded to <code class="language-plaintext highlighter-rouge">0x0100</code>. The fourth line
offsets the binary to this location. The first byte of the COM file
will still be the first byte of code, but it will be designed to run
from that offset in memory.</p>

<p>What follows is all the sections, <code class="language-plaintext highlighter-rouge">text</code> (program), <code class="language-plaintext highlighter-rouge">data</code> (static
data), <code class="language-plaintext highlighter-rouge">bss</code> (zero-initialized data), <code class="language-plaintext highlighter-rouge">rodata</code> (strings). Finally I
mark the end of the binary with the symbol <code class="language-plaintext highlighter-rouge">_heap</code>. This will come in
handy later for writing <code class="language-plaintext highlighter-rouge">sbrk()</code>, after we’re done with “Hello,
World.” I’ve asked for the <code class="language-plaintext highlighter-rouge">_heap</code> position to be 4-byte aligned.</p>

<p>We’re almost there.</p>

<h4 id="program-startup">Program Startup</h4>

<p>The linker is usually aware of our entry point (<code class="language-plaintext highlighter-rouge">main</code>) and sets that
up for us. But since we asked for “binary” output, we’re on our own.
If the <code class="language-plaintext highlighter-rouge">print()</code> function is emitted first, our program’s execution
will begin with executing that function, which is invalid. Our program
needs a little header stanza to get things started.</p>

<p>The linker script has a <code class="language-plaintext highlighter-rouge">STARTUP</code> option for handling this, but to
keep it simple we’ll put that right in the program. This is usually
called <code class="language-plaintext highlighter-rouge">crt0.o</code> or <code class="language-plaintext highlighter-rouge">Boot.o</code>, in case those names every come up in your
own reading. This inline assembly <em>must</em> be the very first thing in
our code, before any includes and such. DOS will do most of the setup
for us, we really just have to jump to the entry point.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">asm</span> <span class="p">(</span><span class="s">".code16gcc</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"call  dosmain</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"mov   $0x4C, %ah</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"int   $0x21</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">.code16gcc</code> tells the assembler that we’re going to be running in
real mode, so that it makes the proper adjustment. Despite the name,
this will <em>not</em> make it produce 16-bit code! First it calls <code class="language-plaintext highlighter-rouge">dosmain</code>,
the function we wrote above. Then it informs DOS, using function
<code class="language-plaintext highlighter-rouge">0x4C</code> (terminate with return code), that we’re done, passing the exit
code along in the 1-byte register <code class="language-plaintext highlighter-rouge">al</code> (already set by <code class="language-plaintext highlighter-rouge">dosmain</code>).
This inline assembly is automatically <code class="language-plaintext highlighter-rouge">volatile</code> because it has no
inputs or outputs.</p>

<h4 id="everything-at-once">Everything at Once</h4>

<p>Here’s the entire C program.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">asm</span> <span class="p">(</span><span class="s">".code16gcc</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"call  dosmain</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"mov   $0x4C,%ah</span><span class="se">\n</span><span class="s">"</span>
     <span class="s">"int   $0x21</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>

<span class="k">static</span> <span class="kt">void</span> <span class="nf">print</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">string</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">asm</span> <span class="k">volatile</span> <span class="p">(</span><span class="s">"mov   $0x09, %%ah</span><span class="se">\n</span><span class="s">"</span>
                  <span class="s">"int   $0x21</span><span class="se">\n</span><span class="s">"</span>
                  <span class="o">:</span> <span class="cm">/* no output */</span>
                  <span class="o">:</span> <span class="s">"d"</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
                  <span class="o">:</span> <span class="s">"ah"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">dosmain</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">print</span><span class="p">(</span><span class="s">"Hello, World!</span><span class="se">\n</span><span class="s">$"</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I won’t repeat <code class="language-plaintext highlighter-rouge">com.ld</code>. Here’s the call to GCC.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gcc -std=gnu99 -Os -nostdlib -m32 -march=i386 -ffreestanding \
    -o hello.com -Wl,--nmagic,--script=com.ld hello.c
</code></pre></div></div>

<p>And testing it in DOSBox:</p>

<p><img src="/img/screenshot/dosbox-hello.png" alt="" /></p>

<p>From here if you want fancy graphics, it’s just a matter of making an
interrupt and <a href="http://www.brackeen.com/vga/index.html">writing to VGA memory</a>. If you want sound you can
perform an interrupt for the PC speaker. I haven’t sorted out how to
call Sound Blaster yet. It was from this point that I grew DOS
Defender.</p>

<h3 id="memory-allocation">Memory Allocation</h3>

<p>To cover one more thing, remember that <code class="language-plaintext highlighter-rouge">_heap</code> symbol? We can use it
to implement <code class="language-plaintext highlighter-rouge">sbrk()</code> for dynamic memory allocation within the main
program segment. This is real mode, and there’s no virtual memory, so
we’re free to write to any memory we can address at any time. Some of
this is reserved (i.e. low and high memory) for hardware. So using
<code class="language-plaintext highlighter-rouge">sbrk()</code> specifically isn’t <em>really</em> necessary, but it’s interesting
to implement ourselves.</p>

<p>As is normal on x86, your text and segments are at a low address
(0x0100 in this case) and the stack is at a high address (around
0xffff in this case). On Unix-like systems, the memory returned by
<code class="language-plaintext highlighter-rouge">malloc()</code> comes from two places: <code class="language-plaintext highlighter-rouge">sbrk()</code> and <code class="language-plaintext highlighter-rouge">mmap()</code>. What <code class="language-plaintext highlighter-rouge">sbrk()</code>
does is allocates memory just above the text/data segments, growing
“up” towards the stack. Each call to <code class="language-plaintext highlighter-rouge">sbrk()</code> will grow this space (or
leave it exactly the same). That memory would then managed by
<code class="language-plaintext highlighter-rouge">malloc()</code> and friends.</p>

<p>Here’s how we can get <code class="language-plaintext highlighter-rouge">sbrk()</code> in a COM program. Notice I have to
define my own <code class="language-plaintext highlighter-rouge">size_t</code>, since we don’t have a standard library.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="kt">unsigned</span> <span class="kt">short</span>  <span class="kt">size_t</span><span class="p">;</span>

<span class="k">extern</span> <span class="kt">char</span> <span class="n">_heap</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">char</span> <span class="o">*</span><span class="n">hbreak</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">_heap</span><span class="p">;</span>

<span class="k">static</span> <span class="kt">void</span> <span class="o">*</span><span class="nf">sbrk</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">char</span> <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="n">hbreak</span><span class="p">;</span>
    <span class="n">hbreak</span> <span class="o">+=</span> <span class="n">size</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">ptr</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It just sets a pointer to <code class="language-plaintext highlighter-rouge">_heap</code> and grows it as needed. A slightly
smarter <code class="language-plaintext highlighter-rouge">sbrk()</code> would be careful about alignment as well.</p>

<p>In the making of DOS Defender an interesting thing happened. I was
(incorrectly) counting on the memory return by my <code class="language-plaintext highlighter-rouge">sbrk()</code> being
zeroed. This was the case the first time the game ran. However, DOS
doesn’t zero this memory between programs. When I would run my game
again, <em>it would pick right up where it left off</em>, because the same
data structures with the same contents were loaded back into place. A
pretty cool accident! It’s part of what makes this a fun embedded
platform.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Northbound 7DRL 2014</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2014/03/31/"/>
    <id>urn:uuid:f0804d6b-83fd-38f4-654f-242dd73dce88</id>
    <updated>2014-03-31T17:37:08Z</updated>
    <category term="game"/><category term="media"/>
    <content type="html">
      <![CDATA[<p>Last year <a href="/blog/2013/03/17/">I participated in 7DRL 2013</a> and submitted a game
called <a href="/disc-rl/"><em>Disc RL</em></a>. 7DRL stands for <a href="http://7drl.org/"><em>Seven Day
Roguelike</em></a> — a challenge to write a roguelike game inside of
one week. I participated again this year in 7DRL 2014, with the help
of <a href="http://www.50ply.com/">Brian</a>. My submission was called <em>Northbound</em>. To play, all
you need is a modern web browser.</p>

<ul>
  <li><a href="/northbound/">Northbound</a> (<a href="http://youtu.be/J4jOxma4uhE">video</a>, <a href="https://github.com/skeeto/northbound">source</a>)</li>
</ul>

<p>It only takes about 10-15 minutes to complete.</p>

<p><a href="/img/screenshot/northbound.png"><img src="/img/screenshot/northbound-thumb.png" alt="" /></a></p>

<p>It’s a story-driven survival game about escaping northward away from a
mysterious, spreading corruption. (“Corruption” seems to be a common
theme in my games.) There’s no combat and, instead, the game is a
series of events with a number of possible responses by the player.
For better or worse, other characters may join you in your journey. I
coded the core game basically from scratch — no rot.js this year —
and Brian focused on writing story events and expanding the story
system.</p>

<p>Just as Disc RL was inspired primarily by NetHack and DCSS, this
year’s submission was heavily, to an embarrassing extent, inspired by
two other games: <a href="http://stoicstudio.com/"><em>The Banner Saga</em></a> (<a href="http://www.youtube.com/playlist?list=PLvjoxMr-LwkIBxL4XedpI72XcYgZIzK-S">LP</a>) and
<a href="http://playism-games.com/games/onewayheroics/"><em>One Way Heroics</em></a> (<a href="http://www.youtube.com/playlist?list=PLp3KcQ0xncPrVPZQT5xCrRhk19I2pNszI">LP</a>).</p>

<p>Writing events was taking a lot longer than expected, and time ran
short at the end of the week, so there aren’t quite as many events as
I had hoped. This leaves the story incomplete, so don’t keep playing
over and over trying to reveal it all!</p>

<p>My ultimate goal was to create a game with an interesting atmosphere,
and I think I was mostly successful. There’s somber music, sounds
effects, and ambient winds. The climate changes as you head north,
with varying terrain. There’s day and night cycles. I intentionally
designed the main menu to show off most of this.</p>

<h3 id="the-event-system">The Event System</h3>

<p>Events are stored in a handful of YAML files. YAML is a very
human-friendly data format that, unlike JSON, is very well suited for
writing prose. Here’s an example of an event that may occur if you
walk on a frozen lake with too many people.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">title</span><span class="pi">:</span> <span class="s">Treacherous ice!</span>
  <span class="na">filter</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">inCold</span><span class="pi">,</span> <span class="nv">inWater</span><span class="pi">,</span> <span class="pi">[</span><span class="nv">minParty</span><span class="pi">,</span> <span class="nv">2</span><span class="pi">]]</span>
  <span class="na">description</span><span class="pi">:</span> <span class="pi">&gt;-</span>
    <span class="s">As everyone steps out onto the frozen lake, the quiet, chilled air</span>
    <span class="s">is disrupted by loud cracks of splits forming through the ice.</span>
    <span class="s">Frozen in place, {{game.player.party.[0]}} looks at you as if</span>
    <span class="s">asking you what should be done.</span>

    <span class="s">{{game.player.party.[1]}} says, "Perhaps we should leave some of</span>
    <span class="s">this stuff behind to lighten load on the ice."</span>
  <span class="na">options</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="na">answer</span><span class="pi">:</span> <span class="s">Leave behind some supplies before moving further. (-10 supplies)</span>
      <span class="na">scripts</span><span class="pi">:</span> <span class="pi">[[</span><span class="nv">supplies</span><span class="pi">,</span> <span class="nv">-10</span><span class="pi">]]</span>
      <span class="na">result</span><span class="pi">:</span> <span class="s">Dropping off excess weight keeps the the ice from cracking.</span>
    <span class="pi">-</span> <span class="na">answer</span><span class="pi">:</span> <span class="s">Ignore the issue and carry on.</span>
      <span class="na">scripts</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">dierandom</span><span class="pi">,</span> <span class="pi">[</span><span class="nv">karma</span><span class="pi">,</span> <span class="nv">-3</span><span class="pi">]]</span>
      <span class="na">result</span><span class="pi">:</span> <span class="pi">&gt;-</span>
        <span class="s">Throwing caution to the wind you move on. Unfortunately the</span>
        <span class="s">ice worsens and cracks. Someone is going in.</span>
</code></pre></div></div>

<p>Those paragraphs would be difficult to edit and format while within
quotes in JSON.</p>

<p>Events can manipulate game state, with other events depending on the
state change, effectively advancing story events in order. The longest
event chain in the game reveals some of the nature of the corruption.
This gets complicated fast, which really slows down event development.</p>

<p>If this is interesting for you to play with, you should easily be able
to add your own story events to the game just by appending to the
event YAML files.</p>

<h3 id="the-map">The Map</h3>

<p>I put off map generation for awhile to work on the story system. For
the first few days it was just randomly placed trees on an endless
grassy field.</p>

<p>When I finally moved on to map generated it was far easier than I
expected. It’s just a few layers of the same 3D Perlin noise, capable
of providing a virtually infinite, seamless expanse of terrain.
Water-dirt-grass is one layer. Trees-mountains-highgrass is another
layer. The cold/snow is a third layer, which, in addition to Perlin
noise, is a function of altitude (more snow appears as you go north).</p>

<p>One obvious early problem was blockage. Occasionally forests would
generate that prohibited movement forward, ending the game. Rather
than deal with the complexities of checking connectedness, I went with
an idea suggested by Brian: add a road that carves its way up the map,
guaranteeing correctness. It plows through forests, mountains, and
lakes alike all the way to the end of the game. Its curvature is
determined by yet another sample into the same 3D Perlin set.</p>

<p>The snow and corruption effects are all dynamically generated from the
base tiles. In short, I write the tile onto a hidden canvas, add a
white gradient for snow, and desaturate for corruption. This was
faster than manually creating three versions of everything.</p>

<h3 id="in-reflection">In Reflection</h3>

<p>While I really like the look and sound of Northbound, it’s ultimately
less fun for me than Disc RL. With the fixed story and lack of
procedually-genertaed content, it has little replayability. This would
still be the case even if the story was fully fleshed out.</p>

<p>Even now I still play Disc RL on occasion, about a couple of times per
month, just for enjoyment. Despite this, I’ve still never beaten it,
which is an indication that I made it much too hard. On the other
hand, Northbound is <em>way</em> too easy. The main problem is that running
out of the supplies almost immediately ends the game in a not-fun way,
so I never really want that to happen. The only way to lose is through
intention.</p>

<p>Next year I need to make a game that looks and feels like Northbound
but plays like Disc RL.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Disc RL in the Media</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2013/05/01/"/>
    <id>urn:uuid:1c073e89-be86-36ee-bd3d-c9ead44383fb</id>
    <updated>2013-05-01T00:00:00Z</updated>
    <category term="game"/><category term="media"/>
    <content type="html">
      <![CDATA[<p>My Seven Day Roguelike (7DRL) game, <a href="/blog/2013/03/17/">Disc RL</a>, was
mentioned in a podcast and demonstrated in a YouTube video. Note that
the UberHunter, the one who made the YouTube video, is one of the
members of the podcast.</p>

<ul>
  <li><a href="http://www.roguelikeradio.com/2013/04/episode-67-7drls-2013-overview.html">Roguelike Radio</a> (starting at 53:15)</li>
  <li><a href="http://youtu.be/0d94WcOo4jU">7DRL 2013 - Disc RL</a> by TheUberHunter</li>
</ul>

<p>An important complaint I discovered about a week after the contest
ended, and mentioned <a href="http://7drl.org/author/jo/">very vocally</a> in both the video and the
podcast, was my exclusive use of the classic roguelike controls: <code class="language-plaintext highlighter-rouge">hjkl
yubn</code> (vi keys). Apparently users <em>really</em> dislike these controls,
even the hardcore roguelike players. This was a complete surprise to
me! These are only controls I’ve ever used and I didn’t realize other
players were using anything different, except for perhaps the numpad.
Most of my experience with roguelikes has been on laptops, so the
numpad simply wasn’t an option.</p>

<p>Fortunately, as a couple of them had found, these fine-movement
controls weren’t that important thanks to the auto-movement features.
That was the second surprise: autoexplore sounded like a foreign idea
to the podcast. I stole that from <a href="http://crawl.develz.org/">Dungeon Crawl Stone Soup</a>, a
roguelike I consider second <a href="/blog/2008/09/17/">only to NetHack</a>.
Dungeon navigation tedious, so I think of autoexplore as a standard
feature these days. What sorts of roguelikes these guys playing if
autoexplore is a fairly new concept?</p>

<p>Eben Howard made an really interesting suggestion to take
auto-movement further. If there had been a key to automatically
retreat to safe corridor, manual movement would have been almost
unnecessary. That will definitely be a feature in my next 7DRL.</p>

<p>Oddly, UberHunter didn’t make much use of auto-movement in his video.
When I play Disc RL, the early game is dominated by the autoexplore
(o) and ranged attack (f) keys. Until I come across the first ranged
unit (viruses, V), there’s no reason to use anything else.</p>

<p>That’s where the YouTube video is kind of disappointing. He didn’t get
far enough to see tactical combat, the real meat of the game. That
doesn’t kick in until you’re dealing with ranged units. Eben in the
podcast <em>did</em> get this far, fortunately, so it was at least discussed.
This issue suggests that I should have made tactical combat show up
earlier in the game. My original concern was giving the player enough
time to get accustomed to Disc RL before throwing harder (i.e. ranged)
monsters at them. I didn’t want to scare potential players off right
away.</p>

<p>Also surprising in the YouTube video, UberHunter seemed to be confused
about using hyperlinks in the help system, worried that clicking them
would break something. He kept trying to open the links in new tabs,
which wouldn’t work because they’re JavaScript “hyperlinks.” Disc RL
is a single-page application and that’s how single-page applications
work. I don’t know if there would be any way to fix this to be more
friendly. Single-page applications are still fairly new and I think
web users, especially longer-experienced web users, are still getting
accustomed to them.</p>

<p>Even though only one of these reviewers thought my game was
interesting, getting this rich feedback was still really exciting for
me. When you’re doing something that truly isn’t interesting or
important, no one says anything at all.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>JavaScript Fantasy Name Generator</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2013/03/27/"/>
    <id>urn:uuid:8c5e22c4-f826-3b81-3f55-4ea60882620e</id>
    <updated>2013-03-27T00:00:00Z</updated>
    <category term="javascript"/><category term="game"/><category term="interactive"/>
    <content type="html">
      <![CDATA[<p>Also in preparation for <a href="/blog/2013/03/17/">my 7-day roguelike</a> I
rewrote the <a href="/blog/2009/01/04/">RingWorks fantasy name generator</a>
<a href="https://github.com/skeeto/fantasyname">in JavaScript</a>. It’s my third implementation of this generator
and this one is also the most mature <em>by far</em>.</p>

<p>Try it out by <a href="/fantasyname/">playing with the demo</a> (<a href="https://github.com/skeeto/fantasyname">GitHub</a>).</p>

<p>The first implementation was written in Perl. It worked by
interpreting the template string each time a name was to be generated.
This was incredibly slow, partly because of the needless re-parsing,
but mostly because the parser library I used had really poor
performance. It’s literally <em>millions</em> of times slower than this new
JavaScript implementation.</p>

<p>The <a href="/blog/2009/07/03/">second implementation</a> I did in Emacs Lisp. I didn’t
actually write a parser. Instead, an s-expression is walked and
interpreted for each name generation. Much faster, but I missed having
the template syntax.</p>

<p>The JavaScript implementation has a template <em>compiler</em>. There are
five primitive name generator prototypes — including strings
themselves, because anything with a toString() method can be a name
generator — which the compiler composes into a composite generator
following the template. The neatest part is that it’s an optimizing
compiler, using the smallest composition of generators possible. If a
template can only emit one possible pattern, the compiler will try to
return a string of exactly the one possible output.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typeof</span> <span class="nx">NameGen</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="dl">'</span><span class="s1">(foo) (bar)</span><span class="dl">'</span><span class="p">);</span>
<span class="c1">// =&gt; "string"</span>
</code></pre></div></div>

<p>Here’s the example usage I have in the documentation. On my junk
laptop it can generate a million names for this template in just under
a second.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">generator</span> <span class="o">=</span> <span class="nx">NameGen</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="dl">"</span><span class="s2">sV'i</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">generator</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>  <span class="c1">// =&gt; "entheu'loaf"</span>
<span class="nx">generator</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>  <span class="c1">// =&gt; "honi'munch"</span>
</code></pre></div></div>

<p>However, in this case there aren’t actually that many possible
outputs. How do I know? You can ask the generator about what it can
generate. Generators know quite a bit about themselves!</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">generator</span><span class="p">.</span><span class="nx">combinations</span><span class="p">();</span>
<span class="c1">// =&gt; 118910</span>

<span class="kd">var</span> <span class="nx">foobar</span> <span class="o">=</span> <span class="nx">NameGen</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="dl">'</span><span class="s1">(foo|bar)</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">foobar</span><span class="p">.</span><span class="nx">combinations</span><span class="p">();</span>
<span class="c1">// =&gt; 2</span>
<span class="nx">foobar</span><span class="p">.</span><span class="nx">enumerate</span><span class="p">();</span> <span class="c1">// List all possible outputs.</span>
<span class="c1">// =&gt; ["foo", "bar"]</span>
</code></pre></div></div>

<p>After some experience using it in Disc RL I found that it would be
<em>really</em> useful to be mark parts of the output to the capitalized.
Without this, capitalization is awkwardly separate metadata. So I
extended the original syntax to do this. Prefix anything with an
exclamation point and it gets capitalized in the output.</p>

<p>For example, here’s a template I find amusing. There are 5,113,130
possible output names.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!BsV (the) !i
</code></pre></div></div>

<p>Here are some of the interesting output names.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Quisey the Dork
Cunda the Snark
Strisia the Numb
Pustie the Dolt
Blhatau the Clown
</code></pre></div></div>

<p>Mostly as an exercise, I also added tilde syntax, which reverses the
component that follows it. So <code class="language-plaintext highlighter-rouge">~(foobar)</code> will always emit <code class="language-plaintext highlighter-rouge">raboof</code>. I
don’t think this is particularly useful but having it opens the door
for other similar syntax extensions.</p>

<p>If you’re making a procedurally generated game in JavaScript, consider
using this library for name generation!</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  <entry>
    <title>7DRL 2013 Complete</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2013/03/17/"/>
    <id>urn:uuid:bb22fefb-c0c9-3a83-88fe-70179a7975f8</id>
    <updated>2013-03-17T00:00:00Z</updated>
    <category term="javascript"/><category term="interactive"/><category term="game"/>
    <content type="html">
      <![CDATA[<p>As I mentioned previously, I participated in this year’s Seven Day
Roguelike. It was my first time doing so. I managed to complete my
roguelike within the allotted time period, though lacking many
features I had originally planned. It’s an HTML5 game run entirely
within the browser. You can play the final version here,</p>

<ul>
  <li><a href="/disc-rl/">Disc RL</a></li>
</ul>

<p><a href="/img/screenshot/disc-rl.png"><img src="/img/screenshot/disc-rl-thumb.png" alt="" /></a></p>

<h3 id="what-went-right">What Went Right</h3>

<h4 id="display">Display</h4>

<p>The first thing I did was create a functioning graphical display. The
goal was to get it into a playable state as soon as possible so that I
could try ideas out as I implemented them. This was especially true
because I was doing <a href="/blog/2012/10/31/">live development</a>, adding
features to the game as it was running.</p>

<p>The display is made up of 225 (15x15) absolutely positioned <code class="language-plaintext highlighter-rouge">div</code>
elements. The content of each div is determined by its dynamically-set
CSS classes. Generally, the type of map tile is one class (background)
and the type of monster in that tile is another class (foreground). If
the game had items, these would also be displayed using classes.</p>

<p>While I could use <code class="language-plaintext highlighter-rouge">background-image</code> to fill these <code class="language-plaintext highlighter-rouge">div</code>s with images,
I decided when I started I would use no images whatsoever. Everything
in the game would be drawn using CSS.</p>

<p>After the display was working, I was able spend the rest of the time
working entirely in game coordinates, completely forgetting all about
screen coordinates. This made everything else so much simpler.</p>

<h4 id="saving">Saving</h4>

<p>Early in the week I got <a href="/blog/2013/03/11/">my save system working</a>.
After ditching a library that wasn’t working, it only took me about 45
minutes to do this from scratch. Plugging my main data structure into
it <em>just worked</em>. I did end up accidentally violating my assumption
about non-circularity. When adding multiple dungeon levels, these
levels would refer to each other, leading to circularity. I got around
that with a small hack of referring to other dungeons by name, an
indirect reference.</p>

<p>From what I’ve seen of other HTML5 roguelikes, saving state seems to
be a unique feature of my roguelike. I don’t see anyone else doing it.</p>

<h4 id="combat">Combat</h4>

<p>I think the final combat mechanics are fairly interesting. It’s all
based on <em>identity discs</em> and <em>corruption</em> (see the help in the game
for more information). There are two kinds of attacks that any
creature in the game can do: melee (bash with your disc) and ranged
(throw your disc). I created three different AIs to make use of these,
bringing in four different monster classes. Note, I consider these
game spoilers.</p>

<ul>
  <li>
    <p><strong>Simple</strong>: Middle-of-the-road on abilities, these guys run up
and try to hit you. No ranged attacks. The strategy is to attack
them with ranged as they close in, then melee them down. They’re
easy and these are the monsters you see in the beginning of the
game.</p>
  </li>
  <li>
    <p><strong>Brute</strong>: These guys have high health and damage (high
strength), but are slow moving (low dexterity). They try to run up
to you and bash you (same AI as “simple” monsters). The strategy
for them is to “kite” them, keeping your distance and hitting them
with ranged attacks, especially when they’re standing on
corruption.</p>
  </li>
  <li>
    <p><strong>Archer</strong>: Archers are the opposite of brutes: low health, high
ranged damage, and high speed. They chase you down and perform
ranged attacks no matter what. The strategy for dealing with them
is to break line-of-sight and wait. They’ll run up and around the
corner where you can melee attack them. Since they’ll continue to
use ranged attacks this leaves them wide open for melee
attacks. This is due to a mechanic that monsters, including the
player, can’t block attacks with their disc for one turn after they
throw it.</p>
  </li>
  <li>
    <p><strong>Skirmisher</strong>: This is a hybrid of brutes and archers and are
the most difficult. They have high dexterity, sometimes also high
strength, and use the appropriate attack for the situation. At
range they use ranged attacks, they’ll try to run away from you if
you get close, and if you do manage to get up close they’ll switch
to melee. Dealing with these guys depends a lot on the terrain
around you. Remember to take advantage of corruption when dealing
with them.</p>
  </li>
</ul>

<p>The eight final, identical bosses of the game have a slightly custom
AI, making them sort of like another class on their own. They’re the
“T” monsters in the screenshot above. I won’t describe it here because
I still want there to be some sort of secret. :-)</p>

<h4 id="corruption">Corruption</h4>

<p>Corruption was actually something I came up with late in the week, and
I’m happy with out it turned out. It makes for more interesting combat
tactics (see above) and I think it really adds some flavor.
Occasionally when you move over corrupted (green) tiles, you will
notice the game’s interface being scrambled for a turn.</p>

<h4 id="rotjs">rot.js</h4>

<p>I ended up using <a href="http://ondras.github.com/rot.js/hp/">rot.js</a> to handle field-of-view calculations,
path finding, and dungeon generation. These are all time consuming to
write and there really is no reason to implement your own for the
first two. I would have liked to do my own dungeon generation, but
rot.js was just so convenient for this that I decided to skip it. The
downside is that my dungeons will look like the dungeons from other
games.</p>

<p>Path finding was critical not only for monsters but also automatic
exploration. Even though it’s quirky, I’m really happy with how it
turned out. Personally, one of the most tiring parts of some
roguelikes is just manually navigating around empty complex
corridors. Good gameplay is all about a long series of interesting
decisions. Choosing right or left when exploring a map is generally
not an interesting decision, because there’s really no differentiating
them. Auto-exploration is a useful way to quickly get the player to
the next interesting decision. In my game, you generally only need to
press a directional navigation key when you’re engaged in combat.</p>

<h4 id="help-screen">Help Screen</h4>

<p>I’m really happy with how my overlay screens turned out, especially
the keyboard styling. I’m talking about the help screen, control
screen, and end-game screen. Since this is the <em>very</em> first thing
presented to the user, I felt it was important to invest time into
it. First impressions are everything.</p>

<h3 id="what-went-wrong">What Went Wrong</h3>

<p>The game is smaller than I originally planned. Monsters have unused
stats and slots on them not displayed by the interface. A look at the
code will reveal a lot of openings I left for functionality not
actually present. I originally intended for 10 dungeon levels, but
lacking a variety of monster AIs, which are time consuming to write, I
ended up with 6 dungeon levels.</p>

<h4 id="user-interfaces">User Interfaces</h4>

<p>My original healing mechanic was going to be health potions (under a
different, thematic name), with no heal-over-time. As I was nearing
the end of the week I still hadn’t implemented items, so this got
scrapped for a heal-on-level mechanic and an easing of the leveling
curve. Everything was in place for implementing items, and therefore
healing potions, except for the user interface. This was a common
situation: the UI being the hardest part of any new feature. Writing
an inventory management interface was going to take too much time, so
I dropped it.</p>

<p>Also dumped due to the lack of time to implement an interface for it
was some kind of spell mechanic. Towards the end I did squeeze in
ranged attacks, but this was out of necessity of real combat
mechanics.</p>

<p>There’s no race (Program, User, etc) and class (melee, ranged, etc.)
selection, not even character name selection. This is really just
another user interface thing.</p>

<p>There are no stores/merchants because these are probably the hardest
to implement interfaces of all!</p>

<h4 id="game-balance">Game Balance</h4>

<p>I’m also not entirely satisfied with the balance. The early game is
too easy and the late game is probably too hard. The difficulty ramps
up quickly in the middle. Fortunately this is probably better than the
reverse: the early game is too hard and the end game is too
easy. Early difficulty won’t be what’s scaring off anyone trying out
the game — instead, that would be boredom! Generally if you find a
level too difficult, you need to retreat to the previous level and
grind out a few more levels. This turns out to be not very
interesting, so there needs to be less of it.</p>

<p>Fixing this would take a lot more play-testing — also very
time-consuming. At the end of the week I probably spent around six
hours just playing legitimately (i.e. not cheating), and having fun
doing so, but that still wasn’t enough. The very end of the game with
the final bosses is quite challenging, so to test that part in a
reasonable time-frame I had to cheat a bit.</p>

<h4 id="code-namespacing">Code Namespacing</h4>

<p>My namespaces are messy. This was the largest freestanding (i.e. not
AngularJS) JavaScript application I’ve done so far, and it’s the first
one where I could really start to appreciate tighter namespace
management. This lead to more coupling between different systems than
was strictly necessary.</p>

<p>I still want to avoid the classical module pattern of wrapping
everything in a big closure. That’s incompatible with Skewer for one,
and it would have also been incompatible with my prototype-preserving
storage system. I just need to be more disciplined in containing
sprawl.</p>

<p>However, in the end none of this really mattered one bit. No one is
maintaining this code and no one will ever read it except me. At the
end of the week it’s <em>much</em> better to have sloppy code and a working
game than a clean codebase and only half of a game.</p>

<h4 id="css-animations">CSS Animations</h4>

<p>Along with my no-images philosophy, I was intending to exploit CSS
animations to make the map look really interesting. I wanted the
glowing walls to pulsate with energy. Unfortunately adding a removing
classes causes these animations to reset if reflow is allowed to occur
— sometimes. The exact behavior is browser-dependent. All the
individual tile animations would get out of sync and everything would
look terrible. There is intentionally little control over this
behavior, for optimization purposes, so I couldn’t fix it.</p>

<h3 id="next-year">Next Year?</h3>

<p>Will I participate again next year? Maybe. I’m really happy with the
outcome this year, but I’m afraid doing the same thing again next year
will feel tedious. But maybe I’ll change my mind after taking a year
off from this! I wasn’t intending on participating this year, until
<a href="http://50ply.com/">Brian</a> twisted my arm into it. See, peer pressure isn’t always
a bad thing!</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>October Chess Engine Updates</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2011/08/24/"/>
    <id>urn:uuid:438369c7-5406-3133-f427-237674b1e53e</id>
    <updated>2011-08-24T00:00:00Z</updated>
    <category term="java"/><category term="game"/>
    <content type="html">
      <![CDATA[<p>When I wrote a <a href="/blog/2010/10/17/">chess engine</a> a year ago, I left it
in a slightly incomplete state. The original intention was to try out
an old <a href="/blog/2007/10/24/">genetic algorithm idea</a> of mine, and
creating a chess engine was just a side effect of that. Well, that
didn’t work out so well since the vast majority of my engine’s games
against itself would end in ties, leaving me with very little data to
work with.</p>

<p>I was left with a working chess engine with some rough edges. Mainly,
there was an “undo move” option that didn’t work right, the graphics
could use a little work, and the only way to set the engine’s strength
was by editing a text file and injecting it into the classpath.</p>

<p>Six months later it got
<a href="/blog/2011/04/09/">some attention on a chess enthusiast forum</a>. I
gave some advice on how to tweak the engine a bit and it made me
realize how hard that is for many people to do. “Hey, there are some
people actually interested in using my unnamed chess engine. Cool! I
should probably fix some of those rough edges.” So I did.</p>

<p>First I gave it a name, since no one on that forum seemed to know what
to call it. Most of the work was done in October of 2010, so I went
with that: <strong>October</strong>. The October Chess Engine. It’s also now in the
public domain, no copyrights attached.</p>

<p>Next, since I’ve learned so much about Java 2D graphics in the last
year, I reworked the graphics. The graphics code is shorter and
simpler, the GUI looks nicer, and it now permits user resizing of the
window. It’s also a little larger by default.</p>

<p>I fixed the engine so that it can search an odd number of plies. All
it needed was a a sign change in one place. The hard part was figuring
out where exactly it needed to be done. With that fixed, I modified
the GUI so that the user can select the difficulty setting.</p>

<p><img src="/img/chess/difficulty.png" alt="" /></p>

<p>I’ve also advanced my knowledge of Java threading, cleaning up thread
management in the engine. There’s no difference from a user
perspective, except that it no longer triggers thread-related JVM bugs
— which I’ve seen occur when rapidly instantiating and tearing down
many threads.</p>

<p>As a side-effect of tidying threading, I made an experimental branch
(<a href="https://github.com/skeeto/october-chess-engine/tree/distributed"><code class="language-plaintext highlighter-rouge">distributed</code></a>)
that allows the AI to make use of other computers in the network. The
entire board state is serialized, along with a single unevaluated
move, and sent off to other machines. They analyze the move and report
back with the move’s score.</p>

<p>While investigating a move can be done independently, it misses out on
a serious optimization. Scores from previous moves can be used to
constrain the current search, allowing the AI to skip over entire
branches of the search tree
(<a href="http://en.wikipedia.org/wiki/Alpha-beta_pruning">alpha-beta pruning</a>).
When all 30-some possible moves are evaluated in parallel, that
optimization is completely lost. As a result, going from one machine
to two equal machines tends to have no real speedups, because
cumulatively they have to work harder than a single machine. It’s not
until several machines are added that the optimization loss is
overcome.</p>

<p>Also with the threading change, I added an AI time estimate, so the
user knows how long the AI will take. This is important with the new
difficulty settings, since high difficulties can take awhile to
compute. Sometimes it’s wildly off, particularly when the AI only
takes a few seconds, but, to my own surprise, it can be quite accurate
when the AI is taking several minutes to complete its turn. Because of
the previously-mentioned optimization, the AI speeds up as it
progresses, so newer timings are weighted more than older timings.</p>

<p>And finally, one of the most visible changes to the user, I created an
<a href="http://nsis.sourceforge.net/">NSIS installer</a> for the Windows users
(available in the downloads section of
<a href="https://github.com/skeeto/october-chess-engine">October’s website</a>). They
can click their way through a familiar install wizard, making the
chess engine a neatly-packaged product. I got the idea from
<a href="http://crawl.develz.org/wordpress/">DCSS</a>, which has a very well
organized build system and makes good use of NSIS.</p>

<p>In the future I’d like to tidy up the experimental distributed AI
stuff, possibly rebuild it on top of Java RMI. I’d also like to add
support for the Universal Chess Interface (UCI). That would allow me
to determine an accurate rating for October, and it would give me an
excellent excuse to not do any more GUI work because another GUI could
easily be used in its place.</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>October's Chess Engine Gets Some Attention</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2011/04/09/"/>
    <id>urn:uuid:bf181782-accb-396e-2855-b7e49b23f2db</id>
    <updated>2011-04-09T00:00:00Z</updated>
    <category term="java"/><category term="game"/>
    <content type="html">
      <![CDATA[<p>Looking at my server logs the other I noticed that the unnamed <a href="/blog/2010/10/17/">Chess
engine I wrote this past October</a> recently got <a href="http://immortalchess.net/forum/showthread.php?t=8845">some attention on
the Immortal Chess forum</a>. As far as I know this is the first
time anyone who’s good at Chess has played it. They were analyzing its
behavior a bit too.</p>

<p>As I expected, in its default setting (the <em>only</em> setting without
editing text configuration files) it’s a pretty weak engine. I did this
to keep is fast, so its turns would take only seconds even on older
hardware. In this state it searches four plies (good engines get as high
as 12). They were able to defeat it easily.</p>

<p><img src="/img/chess/chess-defeat.png" alt="" /></p>

<p>I posted some information on how they can tweak the engine without
having to edit source code or download any new files. Specifically, it’s
easy to increase the search depth to six plies, or more. This
information may be useful in general for anyone wanting to tweak my
Chess engine.</p>

<blockquote>
  <p>You can increase the AI’s strength with some trickery, without having
to go to the source code. Open the .jar file with your favorite
archive manager (looks like 7-Zip is popular around here), and locate
the file <code class="language-plaintext highlighter-rouge">com/nullprogram/chess/ai/default.properties</code>. Open it up in
a text editor and you can see some configuration for the AI (and
remember to save your changes back into the .jar file).</p>

  <p>The most important setting is “depth”, which is a default of 4 plies
right now. You can set this to any <strong>even</strong> number. If you’re on
modern hardware, 6 plies is still reasonably fast. 8 if you’re
patient. It’s multithreaded, so more cores means faster AI. Each
increase in ply is probably a strength increase of about 200-250, so 4
to 6 is about a 450 point increase.</p>

  <p>You can also adjust piece values and situational weights (“safety” is
king safety), which could possibly yield a more powerful AI. Changing
these will not cause any more CPU use, but the payoff will probably be
little.</p>
</blockquote>

<p>The next step to making it stronger would be running a Java profiler,
finding the bottlenecks, and getting the engine sped up enough to search
more plies in the same amount of time. This would certainly involve
tightening up memory use, because the tree search currently creates lots
and lots of garbage. Another option is using opening books, but that’s
not something I’m interested in doing — I like that it currently doesn’t
really rely on any domain knowledge.</p>

<p>Even though it’s a below-average engine, it looks like it still made it
into some personal Chess engine collections. Perhaps I should have put
some credits in there so that, in the future, they could have found
their way back here. I should have also stuck the source code in the
.jar so they’d have it around too.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Flip Foolflim the Dragon Traitor</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2011/01/10/"/>
    <id>urn:uuid:f36fc6c4-7a77-31a9-6fd2-5b4bfd7d095b</id>
    <updated>2011-01-10T00:00:00Z</updated>
    <category term="story"/><category term="game"/>
    <content type="html">
      <![CDATA[<p>So <a href="/blog/2010/07/19/">I’ve been playing a bit of tabletop role-playing games
lately</a>, so here’s another game story like my
previous <a href="/blog/2008/12/22/">Fire Gem tale</a>. I didn’t think it was
<em>that</em> interesting, but I found out that some of my friends were sharing
it with each other when I wasn’t around.</p>

<p>A recent character was named Flip Foolflim, a chaotic evil halfling
rogue. I had selected his secondary language by the roll of the dice,
Draconic, and by coincidence we happened to be fighting a lot of
dragonborn. Flip could always understand them when they spoke to each
other. I was asked why my halfling would know Draconic, so here’s his
story.</p>

<p><img src="/img/rpg/dragon-slay-small.jpg" alt="" class="right" /></p>

<p>Flip had made friends with a dragon — not a typical friendship,
obviously. During their initial encounter this dragon realized a use for
the little halfling. Flip would regularly head out from the dragon’s
lair to one of the local towns where he would round up a group of naïve
adventurers who volunteered slay a “treacherous dragon.” Once at the
lair, he would turn on them and join his dragon friend in killing the
adventurers and keeping the spoils. It was an arrangement both of them
enjoyed.</p>

<p>This little scheme went well for some years until Flip, blinded by his
greed, greatly underestimated one particular group. Fortunately for
Flip, he discovered his mistake before attempting to backstab the
adventurers, and instead joined them in slaying his dragon friend.</p>

<p>Without his home in the dragon lair, he wandered for some time before
joining a party of adventurers (the PCs of the recent adventure). He
worked with them for some time, though not making any close friends.
None of his companions appreciated his thumb collection, cut from the
right hands of everyone his party struck down — for those who had hands.</p>

<p>One particular fight wasn’t going so well for his side, a situation that
he had experienced before back in the dragon lair. In the middle of the
fight Flip kneeled before the opponent, swearing his allegiance, and
attacked his own party members (other PCs, including my wife’s
character). Neither side liked this change, so he found himself with no
friends, meeting his end in that battle.</p>

<p>However, when my friends were discussing this I think it wasn’t so much
about the story being interesting but something like, “Hey, did you hear
Chris had his character attack the other PCs last week?!”</p>

<p>No hard feelings, guys!</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  <entry>
    <title>Sudoku Applet</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2010/10/20/"/>
    <id>urn:uuid:8451de1d-f0c4-3001-2e5a-5720aaa17ed4</id>
    <updated>2010-10-20T00:00:00Z</updated>
    <category term="java"/><category term="interactive"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 20 October 2010 -->
<p>
<img src="/img/sudoku/small.png" alt="" class="right"/>

Over the last two evenings I created this, a Sudoku Java applet.
</p>
<pre>
git clone <a href="https://github.com/skeeto/Sudoku">git://github.com/skeeto/Sudoku.git</a>
</pre>
<p>

The hardest part was creating and implementing the algorithm for
generating new Sudokus. The first step to writing any Sudoku generator
is to <a href="/blog/2008/07/20/">write a Sudoku solver</a>. Use it to
solve an empty board in a random order, then back off while
maintaining a single solution. For a proper Sudoku, this has to be
done symmetrically leaving no more than 32 givens.
</p>
<p>
I didn't work out a great way to determine the difficulty of a
particular puzzle. The proper way would probably be to solve it a few
different ways and measure the number of steps taken. Right now I'm
controlling difficulty by adjusting the number of givens: 24 (hard),
28 (medium), and 32 (easy). Harder puzzles take longer to generate
because the search-space is less dense, due to the strict constraints.
</p>
]]>
    </content>
  </entry>
    
  
    
  <entry>
    <title>Java Applets Demo Page</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2010/10/18/"/>
    <id>urn:uuid:0caa6106-7605-3b67-59c2-215e415f062f</id>
    <updated>2010-10-18T00:00:00Z</updated>
    <category term="java"/><category term="interactive"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 18 October 2010 -->
<p class="abstract">
  Update February 2013: Java Applets are a dead technology and using a
  Java web browser plugin is simply much too insecure. I strongly
  recommend against it. This applet page has since been moved to a
  more generally-named URL.
</p>

<p>
Because the two projects I announced over the weekend can be used as
Java applets, I went back and upgraded <a href="/blog/2007/10/08/">
two older</a> <a href="/blog/2009/12/13/">projects</a> so that they
could also behave as interactive applets. Now that I have several
applets to show off I've collected them together onto a "Java Applet
Demos" page.
</p>
<p class="center">
  <a href="/toys/">
    <b>Java Applet Demos</b><br/>
    <img src="/img/applets/applets.png" alt=""/>
  </a>
</p>
<p>
I intend on expanding this in the near future with improvements
(Michael is unhappy with my integration function on the water wheel,
for one) and new applets <a href="/blog/2010/10/15/">while I'm on a
roll</a>. Swing is my oyster.
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Pen and Paper RPG Wishlist</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2010/07/20/"/>
    <id>urn:uuid:23d2d154-1ba3-3df3-0ba5-84d76159b5ff</id>
    <updated>2010-07-20T00:00:00Z</updated>
    <category term="rant"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 20 July 2010 -->
<p>
As I get more involved with tabletop RPGs, specifically Dungeons and
Dragons, I find there are some related attributes that I wish these
game systems had. While I'm sure there are systems do have some of
these, I wish whatever I happen to be using had all of them.
</p>
<p>
<b>Print friendly</b>. The source material tends to be very colorful
and graphical. While this can be a good thing, especially when
illustrating monsters (Show, not tell!), it's bad if you want to print
out your own materials. I want the crucial information available in a
crisp, clean monochrome form of some sort. Not only could I reproduce
material for use in notes and handouts, but I could create my own
condensed sets of information by composing these crisp forms.
</p>
<p>
For example, in the D&amp;D monster manual each monster has a nice
concise block containing all the information — defenses, health,
abilities, etc. — needed to use that monster. This is great, but it's
on a brownish background, in a red-ish box. So close to being what I
want. But even then, do I have legal permission to reproduce this
information? And so ...
</p>
<p>
<b>Licensing</b>. The closest thing tabletop gaming has to a Free
Software license would be
the <a href="http://en.wikipedia.org/wiki/Open_Game_License"> Open
Game License</a> (OGL), which is still pretty restrictive. I would
love for the source materials to be licensed at least loosely enough
that I could print out my own copies for cheap (assuming they are
print friendly, per above). Have some new players sitting down at the
table? To get them started, give them that stapled-together player
handbook you printed out. There's RPG evangelism for you.
</p>
<p>
The <a href="http://www.fudgerpg.com/fudge.html">Fudge role-playing
game system</a> has both these attributes down pretty well. The Fudge
manual is very print friendly PDF with explicit permission to share it
with your friends. However, just
as <a href="http://en.wikipedia.org/wiki/Yacc"> yacc</a> is a compiler
compiler, Fudge is really a game system <i>system</i>, a system for
creating game systems, so it's only part of what is needed to play a
game.
</p>
<p>
<b>Useful software tools</b>. One specific example is character
creation software. Creating a new character can be burdensome,
especially for a new player. Software that allows a player to select
some basic options from a menu and produce a printable, error-free
character sheet can save a lot of time.
</p>
<p>
Fourth edition Dungeons and Dragons has a character builder, but it is
a humongous piece of junk. It's proprietary, Windows-only, bulky, and
slow. For a program that merely generates printouts based on a few
user selections from some simple menus, it has some <i>extremely</i>
excessive system requirements (much higher than the ones they
claim). And it requires a reboot to install too. A human can produce
the same results by hand inside of a half hour, so for a computer
there is virtually no computation involved. So what is it doing? Worse
of all, the fourth edition license expressly forbids competing
character creation software, so no one can legally produce a
reasonable one. All this thing should be is a database of available
character abilities, some character sheet logic, and a postscript
printer.
</p>
<p>
Fortunately there are some decent, generic world generation tools for
GMs out there, such
as <a href="http://www.inkwellideas.com/roleplaying_tools/random_inn/">
random inn
generators</a>, <a href="http://inkwellideas.com/roleplaying_tools/random_dungeon/">
random
dungeon</a> <a href="http://www.velvet-edge.com/RisusMonkeyMap.html">
generators</a>, and so
on. And <a href="http://www.dizzydragon.net/adventuregenerator/home">
another one</a>. <a href="/blog/2010/05/13/">I've mentioned this
before</a>.
</p>
<p>
If you know any systems that fit the above descriptions well, go ahead
and link them in the comments!
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Neat Random Inn Generator</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2010/05/13/"/>
    <id>urn:uuid:e06b2833-b206-3749-e71e-e44c0a090b12</id>
    <updated>2010-05-13T00:00:00Z</updated>
    <category term="game"/><category term="link"/>
    <content type="html">
      <![CDATA[<!-- 13 May 2010 -->
<p>
<img src="/img/rpg/inn.png" class="left" alt="">

Joe Wetzel over at Inkwell Ideas put together a
neat <a href="http://www.inkwellideas.com/roleplaying_tools/random_inn/">
Random Inn/Tavern Generator</a> for use in tabletop RPGs. He's still
working on it so it's gradually building up more features. It's just
JavaScript and HTML, so no special plugins are needed for it to
work. Right now it appears to be the only generator that makes
floorplans.
</p>
<p>
It creates a random floorplan using image segments, so you'll have to
screenshot the website if you plan on saving a particular layout as a
single image. It also generates a menu, including prices, which I
think adds a lot of personality to the otherwise bare floorplan.
</p>
<p>
There are controls to fix certain properties of the generator in
place, making it less random, so you can control things such as secret
doors, inn size, and second floors. In the future there are plans for
adding generated NPC staff and patrons, and even plot hooks.
</p>
<p>
Ameron over at Dungeon's Master just wrote a
post <a href="http://dungeonsmaster.com/2010/05/tavern-trappings/">
Tavern Trappings</a> as a guide for how to fill a tavern with
everything else. It compliments the random inn generator well.
</p>
<p>
If <a href="/blog/2008/12/22/">I ever GM a game someday</a> I think
this would come in handy.
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>SumoBots Programming Game</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2009/09/02/"/>
    <id>urn:uuid:dcd695f6-8c7f-3fdd-5368-cbec6965764f</id>
    <updated>2009-09-02T00:00:00Z</updated>
    <category term="game"/><category term="video"/>
    <content type="html">
      <![CDATA[<!-- 2 September 2009 -->
<p>
In the summer of 2007 my friend, Michael Abraham, and I wrote a robot
programming game in Matlab. The idea came out of a little demo he
wrote where one circle was chasing another circle. Eventually the
circles could be run by their own functions, then they were shooting
at each other, then dropping mines, and so on. It was dubbed
"Matbots".
</p>
<p>
It turned into a little programming competition among several of us at
work. Someone would invent a new feature, like cooperative bots or
bullet dodging, that would allow it to dominate for awhile. Then
someone else would build on that and come up with some other killer
feature. At one point we even hooked up a joystick so we could control
our own bot live against our creations.
</p>
<p>
I never shared that here. Someday I will.
</p>
<p>
Anyway, Mike took a little bit of the Matbots code and design and came
up with a new, similar game called SumoBots. Programmable bots are in
a frictionless circular playing area with the ability to accelerate in
any direction. Collisions between bots are governed by a spring force
dynamics. Bots are out of the game when they leave the circular
area. The goal is to knock out all the other bots. Here's a video,
</p>
<p class="center">
  <video src="/vid/sumobots/sumobot-party.ogv" controls
         poster="/vid/sumobots/sumobot-party.png">
    <i>You don't have an Ogg Theora capable HTML5 browser. Click this to
    download the video:</i><br/>
    <a href="/vid/sumobots/sumobot-party.ogv">
      <img src="/vid/sumobots/sumobot-party.png" alt=""/>
    </a>
  </video>
</p>
<p>
I like how smooth and natural that looks.
</p>
<p>
He got a number of people at his lab to code up some bots to
compete. I threw the code up over at <a href="http://bitbucket.org/">
bitbucket</a>, a <a href="http://mercurial.selenic.com/wiki/">
Mercurial</a> host, which you can checkout with,
</p>
<pre>
hg clone <a href="http://bitbucket.org/skeeto/sumobots/">http://bitbucket.org/skeeto/sumobots/</a>
</pre>
<p>
(I haven't convinced anyone else over there to use a version control
repository, let alone this one, but here's hoping!)
</p>
<p>
You can use either Matlab or Octave to program your bot. It works in
both, with Octave being on the slow side. For Octave, you'll need to
define a <code>cla</code> function as a call to <code>clf</code> (they
don't define it for some reason). To start coding a bot, just look at
the <code>samplebot</code> bot for information on programming a
bot. Edit the players in <code>player_list.txt</code>, then launch it
by running <code>engine</code> (<code>engine.m</code>).
</p>
<p>
I wrote one bot so far called bully. It charges at the nearest bot,
being careful to cancel out its own velocity. In the video above this
bot is red.
</p>
<p>
The other bots so far is kyleBot, blue in the video, which passively
runs circles around the outside of the surface hoping to trick
aggressive bots, like mine, into running out. The bot2fun bot, black
in the video, is like bully, but tries to keep safely near the center
of the playing area. The brick bot, green in the video, is a dummy,
practice bot that just gets knocked around.
</p>
<p>
The tricky part in writing a bot is managing the frictionless
surface. Acceleration can't just be in the direction you want to
travel, but also against the current velocity. You might want to set
up some kind of <a
href="http://en.wikipedia.org/wiki/Process_control"> process
control</a> for this.
</p>
<p>
Right now I think there is a balance issue. Passive bots have an
advantage, but the game won't progress if everyone takes this
advantage and writes passive bots. It's like camping in a first-person
shooter. As a partial solution to these stalemates, Mike has proposed
that the playing surface should shrink over time.
</p>
<p>
If you want to join in, grab the code and start coding.
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Lisp Fantasy Name Generator</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2009/07/03/"/>
    <id>urn:uuid:492b2b80-c4ba-3655-9811-1b183558d806</id>
    <updated>2009-07-03T00:00:00Z</updated>
    <category term="elisp"/><category term="lisp"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 3 July 2009 -->
<p>
Earlier this year <a href="/blog/2009/01/04">I implemented the
RinkWorks fantasy name generator in Perl</a>. I think lisp lends
itself even better for that, and so I have a partial elisp
implementation for you.
</p>
<p>
What stands out for me is that the patterns can easily be represented
as a S-expression. We represent substitutions with symbols, literals
with strings, and groups with lists. For example, this pattern,
</p>
<pre>
s(ith|&lt;'C&gt;)V
</pre>
<p>
can be represented in code as,
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nv">s</span> <span class="p">(</span><span class="s">"ith"</span> <span class="p">(</span><span class="s">"'"</span> <span class="nv">C</span><span class="p">))</span> <span class="nv">V</span><span class="p">)</span></code></pre></figure>
<p>
I want a function I can apply to this to generate a name. First, I set
up an association list with symbols and its replacements,
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nb">defvar</span> <span class="nv">namegen-subs</span>
  <span class="o">'</span><span class="p">((</span><span class="nv">s</span> <span class="nv">ach</span> <span class="nv">ack</span> <span class="nv">ad</span> <span class="nv">age</span> <span class="nv">ald</span> <span class="nv">ale</span> <span class="nv">an</span> <span class="nv">ang</span> <span class="nv">ar</span> <span class="nv">ard</span> <span class="nv">as</span> <span class="nb">ash</span> <span class="nv">at</span> <span class="nv">ath</span> <span class="nv">augh</span>
       <span class="nv">aw</span> <span class="nv">ban</span> <span class="nv">bel</span> <span class="nv">bur</span> <span class="nv">cer</span> <span class="nv">cha</span> <span class="nv">che</span> <span class="nv">dan</span> <span class="nv">dar</span> <span class="nv">del</span> <span class="nv">den</span> <span class="nv">dra</span> <span class="nv">dyn</span>
       <span class="nv">ech</span> <span class="nv">eld</span> <span class="nv">elm</span> <span class="nv">em</span> <span class="nv">en</span> <span class="nv">end</span> <span class="nv">eng</span> <span class="nv">enth</span> <span class="nv">er</span> <span class="nv">ess</span> <span class="nv">est</span> <span class="nv">et</span> <span class="nv">gar</span> <span class="nv">gha</span>
       <span class="nv">hat</span> <span class="nv">hin</span> <span class="nv">hon</span> <span class="nv">ia</span> <span class="nv">ight</span> <span class="nv">ild</span> <span class="nv">im</span> <span class="nv">ina</span> <span class="nv">ine</span> <span class="nv">ing</span> <span class="nv">ir</span> <span class="nv">is</span> <span class="nv">iss</span> <span class="nv">it</span>
       <span class="nv">kal</span> <span class="nv">kel</span> <span class="nv">kim</span> <span class="nv">kin</span> <span class="nv">ler</span> <span class="nv">lor</span> <span class="nv">lye</span> <span class="nv">mor</span> <span class="nv">mos</span> <span class="nv">nal</span> <span class="nv">ny</span> <span class="nv">nys</span> <span class="nv">old</span> <span class="nv">om</span>
       <span class="nv">on</span> <span class="nb">or</span> <span class="nv">orm</span> <span class="nv">os</span> <span class="nv">ough</span> <span class="nv">per</span> <span class="nv">pol</span> <span class="nv">qua</span> <span class="nv">que</span> <span class="nv">rad</span> <span class="nv">rak</span> <span class="nv">ran</span> <span class="nv">ray</span> <span class="nv">ril</span>
       <span class="nv">ris</span> <span class="nv">rod</span> <span class="nv">roth</span> <span class="nv">ryn</span> <span class="nv">sam</span> <span class="nv">say</span> <span class="nv">ser</span> <span class="nv">shy</span> <span class="nv">skel</span> <span class="nv">sul</span> <span class="nv">tai</span> <span class="nb">tan</span> <span class="nv">tas</span>
       <span class="nv">ther</span> <span class="nv">tia</span> <span class="nv">tin</span> <span class="nv">ton</span> <span class="nv">tor</span> <span class="nv">tur</span> <span class="nv">um</span> <span class="nv">und</span> <span class="nv">unt</span> <span class="nv">urn</span> <span class="nv">usk</span> <span class="nv">ust</span> <span class="nv">ver</span>
       <span class="nv">ves</span> <span class="nv">vor</span> <span class="nv">war</span> <span class="nv">wor</span> <span class="nv">yer</span><span class="p">)</span>
    <span class="p">(</span><span class="nv">v</span> <span class="nv">a</span> <span class="nv">e</span> <span class="nv">i</span> <span class="nv">o</span> <span class="nv">u</span> <span class="nv">y</span><span class="p">)</span>
    <span class="o">...</span>
    <span class="p">(</span><span class="nv">d</span> <span class="nv">elch</span> <span class="nv">idiot</span> <span class="nv">ob</span> <span class="nv">og</span> <span class="nv">ok</span> <span class="nv">olph</span> <span class="nv">olt</span> <span class="nv">omph</span> <span class="nv">ong</span> <span class="nv">onk</span> <span class="nv">oo</span> <span class="nv">oob</span> <span class="nv">oof</span> <span class="nv">oog</span>
       <span class="nv">ook</span> <span class="nv">ooz</span> <span class="nv">org</span> <span class="nv">ork</span> <span class="nv">orm</span> <span class="nv">oron</span> <span class="nv">ub</span> <span class="nv">uck</span> <span class="nv">ug</span> <span class="nv">ulf</span> <span class="nv">ult</span> <span class="nv">um</span> <span class="nv">umb</span> <span class="nv">ump</span> <span class="nv">umph</span>
       <span class="nv">un</span> <span class="nv">unb</span> <span class="nv">ung</span> <span class="nv">unk</span> <span class="nv">unph</span> <span class="nv">unt</span> <span class="nv">uzz</span><span class="p">))</span>
  <span class="s">"Substitutions for the name generator."</span><span class="p">)</span></code></pre></figure>
<p>
Since we will need this in a couple places, make a function to
randomly select an element from a list,
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">randth</span> <span class="p">(</span><span class="nv">lst</span><span class="p">)</span>
  <span class="s">"Select random element from the given list."</span>
  <span class="p">(</span><span class="nb">nth</span> <span class="p">(</span><span class="nb">random</span> <span class="p">(</span><span class="nb">length</span> <span class="nv">lst</span><span class="p">))</span> <span class="nv">lst</span><span class="p">))</span></code></pre></figure>
<p>
A function for replacing a symbol,
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">namegen-select</span> <span class="p">(</span><span class="nv">sym</span><span class="p">)</span>
  <span class="s">"Select a replacement for the given symbol."</span>
  <span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nb">null</span> <span class="p">(</span><span class="nb">assoc</span> <span class="nv">sym</span> <span class="nv">namegen-subs</span><span class="p">))</span>
      <span class="p">(</span><span class="k">throw</span> <span class="ss">'bad-symbol</span>
             <span class="p">(</span><span class="nv">concat</span> <span class="s">"Invalid substitution symbol: "</span> <span class="p">(</span><span class="nb">format</span> <span class="s">"%s"</span> <span class="nv">sym</span><span class="p">)))</span>
    <span class="p">(</span><span class="nb">symbol-name</span> <span class="p">(</span><span class="nv">randth</span> <span class="p">(</span><span class="nb">cdr</span> <span class="p">(</span><span class="nb">assoc</span> <span class="nv">sym</span> <span class="nv">namegen-subs</span><span class="p">))))))</span></code></pre></figure>
<p>
And finally, the generator. Find a string, pass it through, find a
symbol, substitute it, find a list, pick one element and recurse on
it.
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">namegen</span> <span class="p">(</span><span class="nv">sexp</span><span class="p">)</span>
  <span class="s">"Generate a name from the given sexp generator."</span>
  <span class="p">(</span><span class="nb">cond</span>
   <span class="p">((</span><span class="nb">null</span> <span class="nv">sexp</span><span class="p">)</span> <span class="s">""</span><span class="p">)</span>
   <span class="p">((</span><span class="nb">stringp</span> <span class="nv">sexp</span><span class="p">)</span> <span class="nv">sexp</span><span class="p">)</span>
   <span class="p">((</span><span class="nb">symbolp</span> <span class="nv">sexp</span><span class="p">)</span> <span class="p">(</span><span class="nv">namegen-select</span> <span class="nv">sexp</span><span class="p">))</span>
   <span class="p">((</span><span class="nb">listp</span> <span class="nv">sexp</span><span class="p">)</span>
    <span class="p">(</span><span class="nv">concat</span> <span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nb">listp</span> <span class="p">(</span><span class="nb">car</span> <span class="nv">sexp</span><span class="p">))</span> <span class="p">(</span><span class="nv">namegen</span> <span class="p">(</span><span class="nv">randth</span> <span class="p">(</span><span class="nb">car</span> <span class="nv">sexp</span><span class="p">)))</span>
              <span class="p">(</span><span class="nv">namegen</span> <span class="p">(</span><span class="nb">car</span> <span class="nv">sexp</span><span class="p">)))</span>
            <span class="p">(</span><span class="nv">namegen</span> <span class="p">(</span><span class="nb">cdr</span> <span class="nv">sexp</span><span class="p">))))))</span></code></pre></figure>
<p>
That's it! We can apply it to the expression above,
</p>
<figure class="highlight"><pre><code class="language-cl" data-lang="cl"><span class="p">(</span><span class="nv">namegen</span> <span class="o">'</span><span class="p">(</span><span class="nv">s</span> <span class="p">(</span><span class="s">"ith"</span> <span class="p">(</span><span class="s">"'"</span> <span class="nv">C</span><span class="p">))</span> <span class="nv">V</span><span class="p">))</span>
<span class="nv">-&gt;</span> <span class="s">"rynithi"</span></code></pre></figure>
<p>
But that's really the easy part. The hard part would be converting the
original pattern into the S-expression, which I don't plan on doing
right now.
</p>
<p>
Something else to note: this is thousands of times faster than the
Perl version I wrote earlier.
</p>
<p>
I threw the code in with the rest of my name generation code
(namegen.el),
</p>
<pre>
git clone <a href="https://github.com/skeeto/fantasyname">git://github.com/skeeto/fantasyname.git</a>
</pre>
<p>
S-expressions are handy anywhere.
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Fantasy Name Generator: Request for Patterns</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2009/01/04/"/>
    <id>urn:uuid:a5777be4-102b-3359-a083-36a8a9578ae6</id>
    <updated>2009-01-04T00:00:00Z</updated>
    <category term="game"/><category term="perl"/>
    <content type="html">
      <![CDATA[<!-- 4 January 2009 -->
<p>
  <img src="/img/misc/name-generation.jpg" alt="" class="right"/>

Whether choosing a name for my character in a fantasy game or
populating a world which I pretend to myself that I will one day DM, I
have always gone to the <a href="http://www.rinkworks.com/namegen/">
RinkWorks Fantasy Name Generator</a>. The author of this tool, Samuel
Stoddard, gives <a
href="http://www.rinkworks.com/namegen/history.shtml"> some
history</a> on how he came to design and develop it.
</p>
<p>
It works by using pattern to select sets of letters to put together
into a name. There is a thorough, <a
href="http://www.rinkworks.com/namegen/instr.shtml">long
description</a> on the website. Unfortunately, he didn't share his
source code and so we can see how he did it.
</p>
<p>
Therefore, I used his description to duplicate his generator.
</p>
<p>
You can grab a copy here with <a href="http://git.or.cz/">git</a>,
</p>
<pre>
git clone <a href="https://github.com/skeeto/fantasyname">git://github.com/skeeto/fantasyname.git</a>
</pre>
<p>
It includes a command line interface as well as a web interface, which
I am running and linked to at the beginning of this post for you to
use. The code is available under the same license as Perl itself.
</p>
<p>
I used Perl and the <a
href="http://search.cpan.org/dist/Parse-RecDescent/lib/Parse/RecDescent.pm">
Parse::RecDescent</a> parser generator. Thanks to this module, it
essentially comes down to about 40 lines of code. The name pattern is
executed, just like a computer program, to generate a name. Here is
the BNF grammar I came up with,
</p>
<pre>
LITERAL ::= /[^|()&lt;&gt;]+/

TEMPLATE ::= /[-svVcBCimMDd']/

literal_set ::= LITERAL | group

template_set ::= TEMPLATE | group

literal_exp ::= literal_set literal_exp | literal_set

template_exp ::= template_set template_exp | template_set

literal_list ::= literal_exp "|" literal_list | literal_exp "|" | literal_exp

template_list ::= template_exp "|" template_list | template_exp "|" | template_exp

group ::= "&lt;" template_list "&gt;" | "(" literal_list ")"

name ::= template_list | group
</pre>
<p>
The program is just that, decorated with some bits of Perl. Since I
came up with it, I have found that it is slightly different than
Mr. Stoddard's generator, in that his allows empty sets anywhere.
Mine only allows them at the end of lists. For example, this is valid
for his generator,
</p>
<pre>
&lt;|B|C&gt;(ikk)
</pre>
<p>
But to work in mine, the empty item must be moved to the end,
</p>
<pre>
&lt;B|C|&gt;(ikk)
</pre>
<p>
This can be adjusted my making the proper changes to the grammar,
which I haven't figured out yet.
</p>
<p>
Another problem with mine is that Parse::RecDescent is
<i>slooooowwwww</i>. Ridiculously slow. Maybe I designed the grammar
poorly? This is probably the biggest problem. Even simple patterns can
take several seconds to generate names, specifically with deeply
nested patterns. For example, this can take minutes,
</p>
<pre>
&lt;&lt;&lt;&lt;&lt;&lt;&lt;s&gt;&gt;&gt;&gt;&gt;&gt;&gt;
</pre>
<p>
Before you go thinking you are going to tank my server, I have written
the web interface so that it limits the running time of the
generator. If you want to do something fancy, use your own hardware. ;-)
</p>
<p>
There is also a problem that it will silently drop invalid pattern
characters at the end of the pattern. This has to do with me not quite
understanding how to apply Parse::RecDescent yet.
</p>
<p>
And this is where I need your help. I have had some trouble coming up
with good patterns. I don't even have a good default, generic fantasy
name pattern. Here are some of mine,
</p>
<pre>
&lt;s|B|Bv|v&gt;&lt;V|s|'|V&gt;&lt;s|V|C&gt; # default
&lt;i|Cd&gt;D&lt;d|i&gt; # idiot
&lt;V|B&gt;&lt;V|vs|Vs&gt; # short
</pre>
<p>
None of which I am very satisfied.
</p>
<p>
You can design patterns for Nordic names, Gallic names,
Tolkienesque Middle Earth names, orc names, idiot names, dragon names,
dwarf names, elf names, Wheel of Time names, and so on. There is so
much potential available with this tool.
</p>
<p>
To suggest one to me, e-mail me some patterns, or even better, clone
my git repository and add one to it yourself (then ask me to pull from
you). This way your credit will stay directly attached to it with a
commit.
</p>
<p>
Good luck!
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  <entry>
    <title>The Fire Gem</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2008/12/22/"/>
    <id>urn:uuid:54ba3933-0a03-3701-530c-9616a64bec9d</id>
    <updated>2008-12-22T00:00:00Z</updated>
    <category term="story"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 22 December 2008 -->
<p>
  <img src="/img/rpg/fire-gem.jpg" alt="" class="right"/>

If you are at all familiar with <a
href="http://www.wizards.com/default.asp?x=dnd/whatisdnd"> Dungeons
and Dragons</a>, you may have already heard of the stories of <a
href="http://www.netfunny.com/rhf/jokes/98/Jul/gazebo.html"><i>The
Tale of Eric and the Dread Gazebo</i></a> by Richard Aronson and <a
href="http://www.blindpanic.com/humor/vecna.htm">The Head of
Vecna</a>. These are real classics. Read them now, if you haven't
already, before you go on. If you are unfamiliar with <a
href="http://en.wikipedia.org/wiki/Role_playing_game"> tabletop
role-playing games</a> you should go learn a little about them first.
</p>
<p>
I would like to share one of my Dungeons and Dragons stories. It won't
be anywhere as interesting as the two stories I mentioned, but I have
gotten some laughs out of people I tell it to.
</p>
<p>
Back in my college days, a friend was running a 3.5 campaign and asked
me to join in. The other players had rolled up their characters and
done a couple practice sessions before I joined, so I was jumping into
a group that had already had their start.
</p>
<p>
It was an evil campaign. Everyone in the group was either evil or
neutral. We were serving some kind of evil sorcerer. I felt that being
evil allowed much more variety of play and usually gave us more
freedom in the game world than being good. If things started to get
dry, someone would do something stupid like burn down the nearest town
inn. The lawful evil characters weren't so happy about this, though.
</p>
<p>
I rolled up a chaotic evil half-orc barbarian named Gnohkk. I was
lucky on my rolls and had some wonderful stats, so he was very big and
strong. Gnohkk started with a two-handed axe that contained a magic
fire gem in its head. After some training he was able to cause a fiery
explosion at will centered at the location of the fire gem. If an
untrained character wielded the axe, upon striking anything he would
have to make a saving throw to prevent an explosion.
</p>
<p>
Because Gnohkk would also suffer from the explosion, this wasn't
terribly useful at first, except against targets particularly
vulnerable to fire, like trolls and magic trees. The training was
mainly to make the axe usable.
</p>
<p>
At some point during the campaign the party got a hold of a ring of
fire resistance, which was then used by Gnohkk. With this ring he was
invulnerable to his own explosions, making the axe very powerful. The
ring also provided a handful of simple fire spells that made combat
more interesting.
</p>
<p>
Sadly, not long after the ring was found the fire gem axe chipped
broke. Before discarding the broken axe, Gnohkk carefully removed the
fire gem for safe keeping.
</p>
<p>
After an intense battle against some type of monsters with big horns,
Gnohkk found himself a nice metal helmet. He also managed to scrounge
up 10 horns from the monster corpses, which gave him a great
idea. When the party got to the next town, Gnohkk visited the
blacksmith, and requested to have him affix the 10 horns around the
outside of the helmet. In the front of the helmet he wanted to have a
socket created and the fire gem embedded inside it. The blacksmith
said it would take a couple of days.
</p>
<p>
I was hoping this giant helmet would make Gnohkk more intimidating. So
far in the campaign, every time he had attempted to intimidate an NPC
he failed his rolls and came off looking stupid instead.
</p>
<p>
So, this was pretty cool: a giant horned helmet with a gem in the
front. With the helmet on, Gnohkk could explode into a ball of flames
at will and without warning. What a wonderful toy for a chaotic evil!
</p>
<p>
When Gnohkk returned to the blacksmith a couple days later he found
the shop was destroyed. Some of the walls remained, the roof was gone,
and weapons and tools were thrown all over the area. The blacksmith's
charred body had been dead for some time. However, the helmet
<i>was</i> completed and basically intact. Gnohkk shrugged, grabbed
the helmet and left, all without having to pay a single copper to the
now dead blacksmith.
</p>
<p>
We figured out later what happened (the GM probably just told
us). Gnohkk failed to tell the blacksmith about the properties of the
gem. When the blacksmith tapped the gem into the socket, the fire gem
activated and exploded, killing him and destroying his shop.
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  <entry>
    <title>Play NetHack</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2008/09/17/"/>
    <id>urn:uuid:ee6c7f53-f8e1-3636-8e34-1b3f1b70e5c7</id>
    <updated>2008-09-17T00:00:00Z</updated>
    <category term="game"/>
    <content type="html">
      <![CDATA[<!-- 17 September 2008 -->
<p>
  <img src="/img/misc/nethack-cat.jpg" alt=""
       class="right" width="250"/>

Patience. NetHack is all about patience. Never be too hasty, as the
game is extremely unforgiving. If you let your guard down for just a
few turns, you can easily lose everything. Death is permanent
(with <a href="http://nethackwiki.com/wiki/Amulet_of_life_saving">
some exceptions</a>), so dying means starting it all over with a new
character.
</p>
<p>
I got into <a href="http://www.nethack.org/">NetHack</a> a couple of
years ago. I play it in cycles, playing heavily for a couple of months
at a time, then take a break for a couple months after I tire of
getting stuck at the same point each game. I generally return a better
player. The game is very complex, taking probably a hundred hours of
play just to nail down the basic gameplay and techniques.
</p>
<p>
This is what my typical session looks like. I like it almost as simple
as it comes. By default, color is off, but I like to have it on (a lot
more information is available with color). The graphics may seem
crappy, but
<a href="http://www.battlereports.com/users/johnny_vegas2/artius1/Report/report.html">
it is said</a>,
</p>
<blockquote>
  <p>
    While the graphics may seem primitive by today's standards,
    today's gameplay seems primitive by NetHack standards.
  </p>
</blockquote>
<pre style="background-color: #000000; color: #FFFFFF;">
The dingo is blinded by the flash!  The dingo turns to flee!

                                                                       -------
                                                                       |<span style="color: #0000FF;">+</span><span style="color: #00FF00;">+</span>...|
       --------------                               ----------         |.+...|
       |............|              --------         |&gt;........#        ---|---
       |............|              |......|         |........|#           #
       |.........&lt;...#            #.......|         |........|#         ###
       |...<span style="color: #0000FF;">^</span>........|           ###|......|         --.-------#         #
       --.----.------           #  ------.-#          #       ###       #
         #######              ###        ###          ###       #       #
            ####              #           #             #       ###     #
               ###          ###           ####          ###       #     #
                 #          #               #  #          #       ###---.----
                 ##       ###               #########     #         #.......|
                 -.----   #                      # -.-----<span style="color: #AA5500;">|</span>--        |@.....|
                 |.`...####                      ##<span style="color: #AA5500;">-</span>........|        |...<span style="color: #0000FF;">[</span>..|
                 |....|                            |........|        |......|
                 |<span style="color: #0000FF;">{</span>...|         0##################<span style="color: #AA5500;">-</span>........|########-......|
                 ------                            |........|#       --------
                                                   ----------#

wellons the Sightseer       St:12 Dx:12 Co:18 In:12 Wi:8 Ch:16  Neutral S:1967
Dlvl:6  $:1329 HP:48(48) Pw:17(17) AC:7  Xp:5/185 T:3717
</pre>
<p>
Like most rogue-like games, playing NetHack is a rewarding experience,
so if you never tried it out before, I suggest taking a look at
the <a href="http://www.nethack.org/v343/Guidebook.html">NetHack
Guidebook</a> and firing it up for yourself! If you don't want to
install it, but you have a telnet client available, you can connect to
the <a href="http://www.alt.org/nethack/">nethack.alt.org</a> server
to play and watch others play, which is a good way to learn
more. Building it from source can be a little tricky (took me a little
while to figure it out the first time), so using your package manager
is advised if you do choose to install it to try it out.
</p>
<p>
Another good resource is the NetHack
wiki <a href="http://nethackwiki.com/">NetHackWiki</a>. However, if you
don't want to "spoil" yourself, don't go there. Learning things about
the game outside of the game is not considered cheating, but rather
spoiling. I don't mind spoiling myself. I will run into plenty of
things I have not yet spoiled myself on. The game is hard enough as it
is!
</p>
<p>
There is a theory that if someone ever completely beats NetHack under
the hardest conditions, the source code will be thrown out and
replaced with something even harder and more unforgiving. There is
another theory which states that this has already happened.
</p>
<p>
When play for the first time, start with a Valkyrie or a Barbarian as
these classes are pretty tough against baddies, simpler to play, and
more foolproof than some of the squishier classes, like wizards.
</p>
<p>
<b>WARNING: SPOILERS FOLLOW</b>
</p>
<p>
To give an idea of some of the interesting gameplay, I have a couple
examples.
</p>
<pre style="background-color: #000000; color: #FFFFFF;">
               #
          -----.--
          |....<span style="color: #FFFF00;">y</span>.|     ##
          |......|     #
          |.<span style="color: #0000FF;">n</span>....@f######
          |......|
          |....<span style="color: #00FF00;">n</span>.|
          --------
</pre>
<p>
I am the <code>@</code> symbol, which is how NetHack represents the
player. I am entering the room with two
awakened <a href="http://nethackwiki.com/wiki/Nymph">nymphs</a>
(<code>n</code>) and a
<a href="http://nethackwiki.com/wiki/Yellow_light">yellow light</a>
(<code>y</code>). Behind me is my cat who fights alongside me and
assists me. Nymphs do not do damage, but rather steal your
equipment. They approach you, charm you into giving them something
from your inventory, which includes weapons and armor, and teleport
away. This means that you generally want to kill them before they
close in.
</p>
<p>
Yellow lights also do no damage. They run up to you and explode,
causing you to be blind for a number of turns. Normally, this can be a
really bad situation if you do not have the right tools available to
you, which is typical for early in the game. In the worst case, which
also happens to be the most likely, while I work on the nymphs the
yellow light will run up to be blinding me. Now, since I cannot see
the nymphs, I cannot attack them at range and they run up to me each
stealing one item. If I remain blind for long enough, they may find me
again and steal something else while I am helpless. They would rob me
blind! It would be up to my cat to dispatch them.
</p>
<p>
However, I did have some good tools available. I happened to get
extremely lucky
(the <a href="http://nethackwiki.com/wiki/RNG">Random Number God</a>
was nice to me that day) and find both
a <a href="http://nethackwiki.com/wiki/Cloak_of_displacement">cloak
of displacement</a> and
<a href="http://nethackwiki.com/wiki/Jumping_boots">jumping
boots</a> at a store at dungeon level 1. The cloak makes me appear to
be in a different place than I really am while the jumping boots let
me travel several squares in a single turn. I was also playing a
rogue, so my main attack was already a ranged one: throwing daggers.
</p>
<p>
The yellow light ran up to my displaced image and exploded, causing no
blindness to me. One down. Next, I threw my plentiful supply of
daggers at the nymphs, keeping my distance by jumping around the
room. I managed to prevent a deadly situation, being stuck naked with
no weapon, by applying my resources well. With NetHack, I had plenty
of time to plan out each move I made. There is no timer. NetHack moves
at <i>my</i> pace.
</p>
<p>
There was a another situation a couple months ago (which I will not
bother drawing) where I was attacked in the middle of a room by a
<a href="http://nethackwiki.com/wiki/Canine">werewolf</a>. The
werewolf summoned help immediately and I was surrounded by winter
wolves and coyotes and such. Winter wolves can be dangerous because
they shoot deadly frost bolts, and I had not yet have the
<a href="http://nethackwiki.com/wiki/Cold_resistance">cold
resistance</a> intrinsic.
</p>
<p>
I cut a hole through the canines towards the hallway where I could
fight them one at a time, and I lost most of my health in the
process. Then
I <a href="http://nethackwiki.com/wiki/Prayer">prayed</a> to recover
my health. Then I starting hacking away at the canines. Again, I was
low on health and running out of options. The winter wolves were
firing bolts down the hallway at
me. Engraving <a href="http://nethackwiki.com/wiki/Elbereth">Elbereth</a>
on the floor was not going to save me from the ranged frost
bolts. Things were looking quite grim for me. The end seemed near.
</p>
<p>
I did the only thing I could think to do at this point: I reached down
and took a bite into one of the dead frost wolves that was resting on
the floor beneath me.
</p>
<p>
Take a moment and picture this. Frost bolts are zipping down a dark
cold hallway at a nearly dead Valkyrie. There are shattered potions
and frozen liquids all over the floor. The winter wolves have caused
the temperature to plummet. Her breath hangs visibly in the air. She
quickly crouches down and shoves her face into a dead wolf, taking a
nasty bite right into its furry, bloodied side. Between her clenched
teeth she tears off a piece dripping with blood. Desperately, she
stuffs her face with the fresh kill, trying to eat as much as fast as
she can as she dodges more frost bolts.
</p>
<p>
At this moment, the Random Number God blessed me with good fortune,
and I was granted the cold resistance intrinsic just before the next
frost bolt was going to kill me, allowing me to harmlessly absorb it
and continue hacking away the remaining canines. Her reward for
victory was a canine feast!
</p>
<p>
So, yes, the simple looking NetHack can be quite exciting. :-)
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  <entry>
    <title>Sudoku Solver</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2008/07/20/"/>
    <id>urn:uuid:11f2985b-375e-39d4-7510-1daf1b97cfea</id>
    <updated>2008-07-20T00:00:00Z</updated>
    <category term="c"/><category term="game"/>
    <content type="html">
      <![CDATA[<!-- 20 July 2008 -->
<p>
I was at my fiancee's parent's house over Fourth of July weekend. Her
family likes to leave plenty of reading material right by the toilet,
which is something fairly new to me. They take their time on the john
quite seriously.
</p>
<p>
While I was in there I saw a large book
of <a href="http://en.wikipedia.org/wiki/Sudoku"> Sudoku</a>
puzzles. Since the toilet is a good spot to think (I like to call it
my
"<a href="http://everything-more.blogspot.com/2008/04/that-t-shirt-is-wrong-color.html">
thinking chair</a>"), I thought out an algorithm for solving
Sudokus. I then left the bathroom and implemented it in order to
verify that it worked.
</p>
<p>
The method is trial-and-error, which it does recursively: fill in the
next available spot with a valid number as defined by the rules
(cannot have the same number in a column, row, or partition), and
recurse. The function reports success (true) when a solution was
found, or failure (false), which means we try the next available
number. If no more valid numbers are available for testing at the
current position, then the puzzle is not solvable (we made an error at
a previous position), so we stop recursing and return failure.
</p>
<p>
More formally,
</p>
<ul>
  <li>Find an open position.</li>
  <li>Look at that position's row, column, and partition to find valid
  numbers to fill in.</li>
  <li>Fill the position with one of the valid choices.</li>
  <li>Recurse using the new change.</li>
  <li>If the recursion reports a problem (returns false), try the next
  valid number and repeat.</li>
  <li>If recursion reports success (true), stop guessing and return
  success.</li>
  <li>If the list of valid numbers is exhausted, return failure (false).</li>
</ul>
<p>
Note that the recursion depth does not exceed 81, as it only recurses
once per blank square. The "game tree" is broad rather than deep. It
doesn't have to duplicate the puzzle matrix in memory either because
all operations can be done in place.
</p>
<p>
Here is the implementation in C I typed up just after I left the
bathroom,
</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">int</span> <span class="nf">solve</span><span class="p">(</span><span class="kt">char</span> <span class="n">matrix</span><span class="p">[</span><span class="mi">9</span><span class="p">][</span><span class="mi">9</span><span class="p">])</span>
<span class="p">{</span>
    <span class="cm">/* Find an empty spot. */</span>
    <span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">9</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">s</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">9</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">s</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">x</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="n">y</span> <span class="o">=</span> <span class="n">j</span><span class="p">;</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
            <span class="p">}</span>

    <span class="cm">/* No empty spots, we found a solution! */</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">s</span><span class="p">)</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>

    <span class="cm">/* Determine legal numbers for this spot. */</span>
    <span class="kt">char</span> <span class="n">nums</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">};</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">9</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
        <span class="n">nums</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span> <span class="n">matrix</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>   <span class="cm">/* Vertically */</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">9</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
        <span class="n">nums</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span> <span class="n">matrix</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>   <span class="cm">/* Horizontally */</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
            <span class="n">nums</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span> <span class="n">matrix</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="p">((</span><span class="kt">int</span><span class="p">)</span> <span class="p">(</span><span class="n">x</span> <span class="o">/</span> <span class="mi">3</span><span class="p">))</span> <span class="o">*</span> <span class="mi">3</span><span class="p">]</span>
                             <span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="p">((</span><span class="kt">int</span><span class="p">)</span> <span class="p">(</span><span class="n">y</span> <span class="o">/</span> <span class="mi">3</span><span class="p">))</span> <span class="o">*</span> <span class="mi">3</span><span class="p">]</span>
                <span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>          <span class="cm">/* Within the partition */</span>

    <span class="cm">/* Try each possible number and recurse for each. */</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">matrix</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">solve</span><span class="p">(</span><span class="n">matrix</span><span class="p">))</span>
                <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
        <span class="p">}</span>

    <span class="cm">/* Each attempt failed: reset this position and report failure. */</span>
    <span class="n">matrix</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>
I assumed that it would be slow solving the puzzles, having to search
a wide tree, but it turns out to be very fast. It solves normal
human-solvable puzzles in a couple of milliseconds. Wikipedia has a
near-worst case Sudoku that is designed to make algorithms like mine
perform their worst.
</p>
<p>
  <img src="/img/sudoku/worst-case.png" alt="Worst-case Sudoku"/>
</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">char</span> <span class="n">worst_case</span><span class="p">[</span><span class="mi">9</span><span class="p">][</span><span class="mi">9</span><span class="p">]</span> <span class="o">=</span>
  <span class="p">{</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">5</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>

    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>

    <span class="p">{</span><span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span>
    <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span>   <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">}</span>
  <span class="p">};</span></code></pre></figure>
<p>
On my laptop, my program solves this in 15 seconds, which means that
it should take no more than 15 seconds to solve any given Sudoku
puzzle. This provides me a nice upper limit.
</p>
<p>
There is a way to "defeat" this particular puzzle. For example, say an
attacker was trying to perform a
<a href="http://en.wikipedia.org/wiki/Denial-of-service_attack">
denial-of-service</a> (DoS) attack on your Sudoku solver by giving it
puzzles like this one (making your server spend lots of time solving
only a few puzzles). However, these puzzles assume a certain guessing
order. By simply randomizing the order of guessing, both in choosing
positions and the order that numbers are guessed, the attacker will
have a much harder time creating a difficult puzzle. The worst case
could very well be the best case. This is very similar to how
Perl <a href="http://www.ayni.com/perldoc/perlsec.html#Algorithmic-Complexity-Attacks">
randomizes its hash array hash functions</a>.
</p>
<p>
Now suppose we kept our guess order random then "solved" an empty
Sudoku puzzle. What we have is a solution to a randomly generated
Sudoku. To turn it into a puzzle, we just back it off a bit. A Sudoku
is only supposed to have a single unambiguous solution, so we can only
back off until just before the point where two solutions becomes
possible. If you imagine a solution tree, this would be backing up a
branch until you hit a fork.
</p>
<p>
Normally, Sudokus are symmetric (in the matrix sense), but completely
randomizing the position guessing order won't achieve this. To make
this work, the randomizing process can be adjusted to only select
random points on the upper triangle (including the diagonal). For each
point it selects <i>not</i> on the diagonal, the mirror point is
automatically selected next. This will preserve symmetry when
generating puzzles.
</p>
<p>
One issue remains: there seems to be no way to control the difficulty
of the puzzles it generates. Maybe a number of open spaces left behind
is a good metric? This will require some further study (and another
post!).
</p>
]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  <entry>
    <title>Chess AI Idea</title>
    <link rel="alternate" type="text/html" href="https://nullprogram.com/blog/2007/10/24/"/>
    <id>urn:uuid:2e66347a-fe5d-3b70-58ea-9a9e9bd6248a</id>
    <updated>2007-10-24T00:00:00Z</updated>
    <category term="ai"/><category term="game"/>
    <content type="html">
      <![CDATA[<p>So, I had this idea using a genetic algorithm to optimize the
parameters of a program that plays chess. Now, the genetic algorithm
wouldn’t be used at all during a game, but rather to optimize the
board evaluation parameters beforehand. I don’t know much about
writing board game AI programs, as I have only written a few of them
for fun (tic-tac-toe, connect 4, Pente). For this chess program, I am
taking a simple approach because I am more interested in seeing the
genetic algorithm at work than seeing the chess playing AI do well
against other chess AI or people.</p>

<p>The program would search the game tree using the <a href="http://en.wikipedia.org/wiki/Minimax">minimax</a>
algorithm, with some <a href="http://en.wikipedia.org/wiki/Alpha-beta_pruning">possible optimizations</a> added
afterward. Tree searching is just a matter of generating all possible
moves and looking at them. The hard part is the board evaluation
function, which evaluates the a particular board’s score based on the
arrangement of the pieces. Parameters to this evaluation function
would be, for example, the piece values. The pawn would be locked in
at a value of 1, which anchors the other values and provides a base
unit to work from.</p>

<p>Again, the parameters would not change during a game. We use the
genetic algorithm ahead of time to determine the parameters.</p>

<p>For the genetic algorithm, the set of parameters strung together makes
up a single chromosome. We maintain a pool of different chromosomes,
i.e. different sets of parameters, and breed these chromosomes
together to improve our parameter sets. We start out with a random
pool made of parameters that are most likely pretty terrible.</p>

<p>To evaluate the chromosomes, we need a fitness function, which
evaluates each chromosome for its level of “fitness” deciding if it
breeds or not. To do this we simply play the chromosome we are
evaluating against some base chromosome, which may just be parameters
chosen intuitively by the programmer. Or, the base chromosome could be
random too. Starting with a better base chromosome would be a good
head start, though. The fitness of the chromosome is how often it wins
against the base chromosome in, say, a few hundred games.</p>

<p>The most fit chromosomes are bred by taking a few parameters from each
to make a new chromosome. Mutations are occasionally added in order to
keep the chromosome pool from getting stuck in a local maximum. A
mutation involves changing one or more parameters in a chromosome
slightly in some random way. Mutations are rare and will usually be
detrimental to the chromosome quickly killing it off, but will
occasionally cause a good change that will be spread to other
chromosomes in the next generation, improving the gene pool.</p>

<p>We iterate this until either the maximum fitness level in the pool is
stuck for several iterations (we aren’t getting anywhere and mutations
aren’t helping), or the chromosomes are so good they always beat the
base chromosome, making the fitness algorithm meaningless. When this
happens, we replace the base chromosome with the best chromosome in
the pool and start over from scratch again with a random, or mostly
random, pool.</p>

<p>As you would expect, I have looked into parallelizing this process to
take advantage of a cluster. This is easy for several reasons. First,
evaluating chromosomes can be done simultaneously. No evaluation
depends on another chromosome’s evaluation. Second, the minimax game
tree search can be parallelized so that several different processes
search the game tree and give their results back to the parent
process. This works very well because the data being sent back to the
parent will be a single integer. No need to send large amounts of data
around the network.</p>

<p>I spent an afternoon hacking at this, but its still too crude to share
yet. I got the non-parallel version of the chess engine built but I am
still working on the evaluation function. The genetic algorithm hasn’t
been started. The only parameters at the moment are piece values. The
board evaluation function just adds up the piece values on the board
completely ignoring their positions. This makes the computer play
extremely aggressively, capturing the opponent’s pieces whenever it
can. This makes for a somewhat interesting bloodbath where the board
goes empty after just a few moves.</p>

<p>My problem right now is finding a good way to represent piece
movements so that it can be recycled. That is, I want to represent
movements when generating my search tree, verifying the legality of a
move, and evaluating the board all the same way so that I don’t have
to program in piece movements several times.</p>

]]>
    </content>
  </entry>
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  
    
  

</feed>
