Aaron Krohn

Started on binary file format; Added num_tiles attribute to _2048

... ... @@ -30,6 +30,7 @@ class _2048(object):
self.size = board_size
self.init_tiles = init_tiles
self.num_tiles = self.size ** 2
self.fname_base = '.2048save_'
... ...
from _2048 import new_game
from _2048.exceptions import *
from math import ceil, log, sqrt
from random import choice
def bits_per_tile(num_tiles):
return int( ceil( log(num_tiles + 1, 2) ) )
def board_to_bin(g):
# Number of bits needed for each tile
bpt = bits_per_tile(g.num_tiles)
# Each tile bit string's length depends on board size
fmt_str = '0{0}b'.format(bpt)
out_str = ''
for row in g.board:
for tile in row:
# Base 2 logarithm of the tile value is easily
# converted to a bit string for storage
log_val = 0 if tile == 0 else int(log(tile, 2))
out_str += format(log_val, fmt_str)
# Return binary string in hexadecimal notation
return '%x' % int(out_str, 2)
def bin_to_board(hex_str, num_tiles):
# hex_str is a hexadecimal representation of the board
# as generated by the board_to_bin() function
# Number of bits in hex_str occupied by each board tile
bpt = bits_per_tile(num_tiles)
# Total number of bits hex_str should have
bsl = bpt * num_tiles
# Tiles per row
row_size = int(sqrt(num_tiles))
# Leading zeros are truncated by board_to_bin() so we
# use the 'bsl' value to create a format string that
# will set the length correctly
fmt_str = '0{0}b'.format(bsl)
# Turn our hex string into a binary string of proper length
bin_str = format( int( hex_str, 16), fmt_str)
# Initialize our output array
out = [[0 for _ in range(row_size)] for x in range(row_size)]
# Row counter
row = -1
# 'i' will be the string index of the first bit of each tile
for i in range(0, len(bin_str), bpt):
# increment row if needed
row += 1 if i % (bpt * row_size) == 0 else 0
# convert our tile bits to an integer
powa = int(bin_str[i:i+bpt], 2)
# bit shift '2' the correct number of times
out[row][i % row_size] = 2 << (powa - 1) if powa > 0 else 0
return out
for _ in range(100):
mv = choice(g.moves_list)
try:
g.move( mv )
except InvalidMove:
pass
except GameOver:
break
g = new_game(board_size=4)
foo = board_to_bin(g)
print(bin_to_board(foo, g.num_tiles))
... ...