Use fixed seed for benchmarking
Removed statistics gathering and printing
Replace std::map with std::unordered_map

This gave a large speedup (~25% faster). Though it requires c++11.
Also enable debug symbols (-g), this gives more useful profiling reports.
Replace #defines with inline functions or constants

IMHO makes it easier to see what is actually going on. And in this particular
case the code without macro's is even shorter than the original.
Replace pack_col() with transpose()

Profiling indicated that a lot of time was spend in the pack_col() function.
This function is always called 4 times (for all 4 columns). It turns out to be
cheaper to only once transpose the board (turn columns into rows) and then
extract 4 rows.
Tweak insert_tile_rand() and initial_board()

This is a preparation for the next patch: that patch will add an optimized way
of counting the number of empty tiles on the board. Though that new routine
doesn't work on a completely empty board. Luckily that situation only occurs
before the game has actually started in the initial_board() function and that
one is very easy to rewrite (don't use insert_tile_rand() for the very first
tile).

This patch also makes a small tweak in insert_tile_rand(). Unless there's a
bug in the game logic, it can never happen that insert_tile_rand() is called
on a board without at least one empty position. So we can remove the check for
that.
Add new count_empty() function

This bit-hack turns out to be faster than the original way to count empty cells
in a board (was loop over 16 nibbles). Though it doesn't work on a completely
empty board. But the previous patch already made sure we don't need it anymore
for empty boards.
Optimize insert_tile_rand()

Though this function isn't called very often, so I doubt it has a measurable
impact on the total performance.

Also, the result of the draw_tile() function is now always (explicitly or
implicitly) converted to board_t. So we can as well immediately return a
board_t.
Replace powf(2, x) with (1 << x)
No need to memset() tables because they are fully overwritten
Store row_{left,right}_table in 16-bit

The tables row_left_table and row_right_table always contain values less than
0x10000, so it's possible to store them in 16-bit instead of 64-bit.

This reduces the size of each of these two tables from 512kB to 128kB. Combined
with some of the later patches in this series this has a positive effect on
memory cache efficiency.
Cleanup init_xxx_table() routines

Both init_move_tables() and init_score_tables() fill in tables which have
0x10000 entries. Both routines contain some common operations. It's possible
to merge both into one. (Of course this won't be noticable in the total
execution speed).

This also changes the API of the .so file. Though IMHO it's better to only
expose one init() function to better hide the internal implementation details.
Score_table can use int instead of float
Only use one move-table

Before this patch move up,down,left,right each had their own table. Combined
those tables take 1.25MB (was even 2MB in the original code). This patch only
keeps the table for move-left and implements the other directions in terms of
move-left with some pre- and post-transformations.

This is a trade-off between larger lookup-tables vs more calculations. On
modern platforms CPUs are very fast but memory becomes more and more a
bottleneck.

So this patch reduces the total size of all move-tables from 1.25MB to 128kB.
Moving right,up,down now require extra calculations. Overall this patch has
(only a small) positive effect on speed.
Tweak score_move_node()
Small cleanup in get_max_rank()
Small tweaks

'eval_state' constructor is not very useful anymore.

Slightly better way for commit ad2b748 (force legal moves to have a nonzero score)
Tweak score_tilechoose_node()
Experiment: unroll move-loop in score_move_node

Goal is to eventually get rid of the execute_move(int move) function.
Changed find_best_move() -> do_best_move()

Before this patch the main loop looked (very roughly) like this:
  0) are there still legal moves?
  1) find best move
  1b) did step 1 really find a move?
  2) execute that move
  2b) was step 2 really a valid move?
But internally step 1 already executes that move, so the work in step 2 is
redundant. This patch changes step 1 to instead of the move (up, down, left,
right) return the resulting board of the move.

There were also a lot of redundant checks for valid moves. Step 0, 1b and 2b
are now collapsed into a single check.

This patch changes the interface of some of the exported functions. So it very
likely breaks the python bindings. I'm sure it's possible to update the python
stuff, but (for now) I didn't bother. Also the ask_for_move() function is
broken now (but can easily be fixed), but again I didn't do this.

@Robert Xiao:
The original game-loop was a more natural fit for interactivly playing the game
and likely also to automatically controlling a web-based game. This new code is
(only) better suited to quickly solve the game. So feel free to drop this patch
when integrating this branch into yours.