Skip to content

Instantly share code, notes, and snippets.

@greeness
Created July 14, 2014 20:46
Show Gist options
  • Save greeness/d51e7b7730aaeec76306 to your computer and use it in GitHub Desktop.
Save greeness/d51e7b7730aaeec76306 to your computer and use it in GitHub Desktop.
board init and hexagon printout
import json
from sys import stdout
from random import choice, seed, shuffle
from copy import deepcopy
basic_shapes = [
[(0,0), (1,0), (2,0)],
[(0,0), (0,1), (0,2)],
[(0,0), (-1,1), (-2,2)],
[(0,0), (-1,0), (-2,0)],
[(0,0), (0,-1), (0,-2)],
[(0,0), (1,-1), (2,-2)]]
def all_preshapes(basic_shape):
""" Algorithm to generate all potential shapes """
preshapes = []
for shape in basic_shape:
for idx in range(0, 3):
x, y = shape[idx]
for dx,dy in neighbors:
x1 = x + dx
y1 = y + dy
if (x1,y1) not in shape:
s = [loc for loc in shape if loc != (x, y)]
s.extend([(x1, y1)])
preshapes.append({"shape": s, "earth": (x,y), "id": len(preshapes)})
return preshapes
# offset of the 6-neighbor
neighbors = [(0,-1), (1,-1), (1,0), (0,1), (-1,1), (-1,0)]
preshapes = all_preshapes(basic_shapes)
colors = range(0, 7)
class HexagonPrint:
def __init__(self, size, board):
# length of hexagon edge
self.size = size
# height of the board
self.height = board.height
self.loc = board.loc
self.b = board.b
def print_left_blank(self, row):
if row % 2 == 0:
stdout.write(' ' + '%02d ' % (row/2))
else:
stdout.write(' ')
def print_up_left(self):
stdout.write('/'),
def print_up_right(self, row, col):
x = int(col*2)
y = int(row/2 - col)
char = self.get_cell_title(x, y, False)
stdout.write(char + '\\' + '_'*self.size)
def print_down_left(self):
stdout.write('\\' + '_'*self.size + '/')
def get_cell_title(self, x, y, show_coordinate=False):
key = (x,y)
if key in self.loc:
char = '%2s' % self.b[x][y] if self.size == 2 else '%3s' % self.b[x][y]
else:
char = '%d,%d' % (x,y) if show_coordinate else ' '*self.size
return char
def print_down_right(self, row,col):
x = int(col*2) + 1
y = int(row/2) - col
char = self.get_cell_title(x, y, False)
stdout.write(char)
def print_newline(self, row):
if row < self.height:
stdout.write('%02d\n' % row)
else:
stdout.write('\n')
def print_top_flat(self, row):
stdout.write(' ' + '_'*self.size)
for _ in range(row-1):
stdout.write(' '*(self.size+1) + '_'*self.size)
self.print_newline(0)
def print_upper_half(self, row, cols):
self.print_left_blank(row)
for col in range(0, cols):
self.print_up_left()
self.print_up_right(row, col)
self.print_up_left()
self.print_newline(row+1)
def print_bottom_half(self, row, cols):
self.print_left_blank(row)
for col in range(0, cols):
self.print_down_left()
self.print_down_right(row, col)
self.print_down_left()
self.print_newline(row+1)
def print_row(self, row, cols, bees={}):
if row == 0:
self.print_top_flat(cols)
if row % 2 == 0:
self.print_upper_half(row, cols)
else:
self.print_bottom_half(row, cols)
def print_board(self):
for row in range(0, self.height*2):
width = row/2+1 if row < self.height else self.height/2
self.print_row(row, width)
class Board:
def __init__(self, board_data):
self.height = board_data["height"]
self.width = board_data["width"]
self.loc = {}
self.b = [[' ' for y in xrange(self.width + 1)] for x in xrange(self.height + 1)]
for k,v in board_data["boardCells"].iteritems():
if not v['passthrough']:
x, y = eval(k)
self.loc[(x, y)] = v
self.b[x][y] = 'x'
def is_on_board(self, x, y):
return (x,y) in self.loc
def is_loc_taken(self, x, y):
return self.b[x][y] != 'x'
def same_color(self, loc1, loc2):
return self.is_on_board(loc1[0], loc1[1]) and self.is_loc_taken(loc1[0], loc1[1]) and \
self.is_on_board(loc2[0], loc2[1]) and self.is_loc_taken(loc2[0], loc2[1]) and \
self.b[loc1[0]][loc1[1]] == self.b[loc2[0]][loc2[1]]
def is_continuous_same_color(self, root, up1, up2, down1, down2):
if self.same_color(root, up1) and self.same_color(up1, up2):
return True
if self.same_color(root, down1) and self.same_color(down1, down2):
return True
if self.same_color(root, up1) and self.same_color(root, down1):
return True
return False
def is_ok_to_add_shape(self, x, y, shape, color):
nextb = deepcopy(self)
for (dx, dy) in shape:
nextb.b[x+dx][y+dy] = color
#neighbors = [(0,-1), (1,-1), (1,0), (0,1), (-1,1), (-1,0)]
for (dx, dy) in shape:
x0 = x + dx
y0 = y + dy
root = (x0, y0)
#print "check root at ", root, "color", color, "shape", shape
# up and down (0,-1) & (0,1)
up1 = (x0, y0 - 1)
up2 = (x0, y0 - 2)
down1 = (x0, y0 + 1)
down2 = (x0, y0 + 2)
if nextb.is_continuous_same_color(root, up1, up2, down1, down2):
#print "csc"
return False
# top-left to right-bottom (-1,0) & (1,0)
up1 = (x0-1, y0)
up2 = (x0-2, y0)
down1 = (x0+1, y0)
down2 = (x0+2, y0)
if nextb.is_continuous_same_color(root, up1, up2, down1, down2):
#print "csc"
return False
# bottom-left to top-right (-1,1) & (1,-1)
up1 = (x0-1, y0+1)
up2 = (x0-2, y0+2)
down1 = (x0+1, y0-1)
down2 = (x0+2, y0-2)
if nextb.is_continuous_same_color(root, up1, up2, down1, down2):
#print "csc"
return False
#print "root", root, "is ok."
return True
def is_placeable(self, preshape, x, y, color):
x0, y0 = preshape["earth"]
if not self.is_on_board(x+x0, y+y0):
return False
for dx, dy in preshape["shape"]:
x1 = x + dx
y1 = y + dy
if not self.is_on_board(x1, y1) or \
self.is_loc_taken(x1, y1) or \
not self.is_ok_to_add_shape(x, y, preshape["shape"], color) :
return False
return True
def neighbor_colors(self, x, y):
nc = set()
for dx, dy in neighbors:
x1 = x + dx
y1 = y + dy
if self.is_on_board(x1, y1) and self.is_loc_taken(x1, y1):
nc.add(self.b[x1][y1])
return nc
def init(board, num_preshapes):
""" Given a board representation and the number of potential
shapes to generate, performs the board initialization
board: a class that contains two data members:
- board.loc: a set that contains all valid locations on board;
each location is represented with a tuple (x,y)
- board.b: a 2-d array that keeps track of what type of bees
is located at b[x][y] where x is the height and y is the width.
Invalid positions are initialized to have ' ' as the value.
Valid but uninitialized locations are initialized to contain 'x'.
Valid and initialized locations should contain value 0-6.
num_preshapes: the number of potential shapes to generate.
"""
placed = 0
all_locs = board.loc.keys()
shuffle(all_locs)
for (x,y) in all_locs:
if placed >= num_preshapes: break
shuffle(colors)
found = False
for color in colors:
shuffle(preshapes)
for preshape in preshapes:
if board.is_placeable(preshape, x, y, color):
for (dx, dy) in preshape["shape"]:
board.b[x+dx][y+dy] = color
#print 'set colr to', color, 'at', x+dx, y+dy
print 'pick random pos', x, y
print 'pick random color', color
print 'place shape', preshape["shape"], 'at', x, y, "earth at", preshape["earth"]
placed += 1
print "No", placed
h = HexagonPrint(2, board)
h.print_board()
found = True
break
if found:
break
if placed < num_preshapes:
print "Only placed", placed, "shapes on board."
def rand_fill(board):
for x in range(0, board.height):
for y in range(0, board.width):
if board.is_on_board(x,y) and not board.is_loc_taken(x, y):
neighbor_colors = board.neighbor_colors(x, y)
available_colors = list(set(colors) - neighbor_colors)
board.b[x][y] = choice(available_colors)
print "After random fill"
h = HexagonPrint(2, board)
h.print_board()
if __name__ == '__main__':
level_0_6 = '{"worldNumber":"0","availableBoosters":["stingers","exploders","colorBomb"],"board":{"gravityType":"directional","width":9,"graviationalCenter":[0,0],"gravityDirection":"3","boardCells":{"7,6":{"honey":false,"passthrough":false},"6,1":{"honey":false,"passthrough":false},"4,5":{"honey":false,"passthrough":false},"1,4":{"honey":false,"passthrough":false},"9,3":{"honey":false,"passthrough":false},"7,7":{"honey":false,"passthrough":false},"6,2":{"honey":false,"passthrough":false},"4,6":{"honey":false,"passthrough":false},"3,1":{"honey":false,"passthrough":false},"1,5":{"honey":false,"passthrough":false},"6,3":{"honey":false,"passthrough":false},"4,7":{"honey":false,"passthrough":false},"3,2":{"honey":false,"passthrough":false},"1,6":{"honey":false,"passthrough":false},"6,4":{"honey":false,"passthrough":false},"3,3":{"honey":false,"passthrough":false},"1,7":{"honey":false,"passthrough":false},"8,1":{"passthrough":true,"punk":0,"babee":0,"honey":false,"waterDrop":false,"smoke":false},"6,5":{"honey":false,"passthrough":false},"5,0":{"honey":false,"passthrough":false},"3,4":{"honey":false,"passthrough":false},"1,8":{"honey":false,"passthrough":false},"10,0":{"honey":false,"passthrough":false},"8,2":{"honey":false,"passthrough":false},"6,6":{"honey":false,"passthrough":false},"5,1":{"honey":false,"passthrough":true},"3,5":{"honey":false,"passthrough":false},"8,3":{"honey":false,"passthrough":false},"6,7":{"honey":false,"passthrough":false},"5,2":{"honey":false,"passthrough":false},"3,6":{"honey":false,"passthrough":false},"10,1":{"honey":false,"passthrough":false},"0,5":{"honey":false,"passthrough":false},"8,4":{"honey":false,"passthrough":false},"6,8":{"honey":false,"passthrough":false},"5,3":{"honey":false,"passthrough":false},"3,7":{"honey":false,"passthrough":false},"2,2":{"honey":false,"passthrough":false},"0,6":{"honey":false,"passthrough":false},"8,5":{"honey":false,"passthrough":false},"5,4":{"honey":false,"passthrough":true},"2,3":{"honey":false,"passthrough":false},"0,7":{"honey":false,"passthrough":false},"7,1":{"honey":false,"passthrough":false},"5,5":{"honey":false,"passthrough":false},"4,0":{"honey":false,"passthrough":false},"2,4":{"honey":false,"passthrough":false},"0,8":{"honey":false,"passthrough":false},"7,2":{"honey":false,"passthrough":false},"5,6":{"honey":false,"passthrough":false},"4,1":{"honey":false,"passthrough":false},"2,5":{"honey":false,"passthrough":false},"7,3":{"honey":false,"passthrough":false},"5,7":{"passthrough":true,"punk":0,"babee":0,"honey":false,"waterDrop":false,"smoke":false},"4,2":{"honey":false,"passthrough":false},"2,6":{"honey":false,"passthrough":false},"9,0":{"honey":false,"passthrough":false},"7,4":{"honey":false,"passthrough":false},"5,8":{"honey":false,"passthrough":false},"4,3":{"honey":false,"passthrough":false},"2,7":{"honey":false,"passthrough":true},"9,1":{"honey":false,"passthrough":false},"7,5":{"honey":false,"passthrough":false},"4,4":{"honey":false,"passthrough":false},"1,3":{"honey":false,"passthrough":false},"9,2":{"honey":false,"passthrough":false}},"height":14},"levelNumber":"6","twoStarThreshold":4000,"levelVersion":"0","pollenCount":0,"oneStarThreshold":1100,"threeStarThreshold":6500,"typeCount":"7","levelGoal":"just-score","bees":{},"limitQuantity":13,"pollenOnBoard":1,"levelLimit":"moves","allowBonus":0,"pollenOnBoardCount":1,"collections":{}}'
level_5_17 = '{"worldNumber": "5","levelNumber": "17","levelVersion": "0","typeCount": "6","availableBoosters": ["stingers","exploders","colorBomb"],"levelGoal": "pollen-to-the-queen","pollenCount": 5,"pollenOnBoardCount": 1,"levelLimit": "moves","limitQuantity": 53,"oneStarThreshold": 12000,"twoStarThreshold": 25000,"threeStarThreshold": 40000,"board": {"width": 9,"height": 14,"gravityType": "directional","gravityDirection": "3","graviationalCenter": [0,0],"boardCells": {"4,2": {"honey": false,"passthrough": false},"5,1": {"honey": false,"passthrough": false},"5,2": {"honey": false,"passthrough": false},"5,3": {"honey": 0,"passthrough": false},"5,4": {"honey": 0,"passthrough": true},"6,1": {"honey": false,"passthrough": false},"6,2": {"honey": false,"passthrough": true},"6,3": {"honey": 0,"passthrough": false},"6,4": {"honey": 0,"passthrough": true},"6,5": {"honey": 0,"passthrough": false},"7,1": {"honey": false,"passthrough": false},"7,2": {"honey": false,"passthrough": false},"7,3": {"honey": 0,"passthrough": false},"7,4": {"honey": 0,"passthrough": true},"7,5": {"honey": false,"passthrough": false},"8,1": {"honey": false,"passthrough": true},"8,2": {"honey": false,"passthrough": false},"8,3": {"honey": false,"passthrough": false},"8,4": {"honey": false,"passthrough": true},"8,5": {"honey": false,"passthrough": false},"9,1": {"honey": false,"passthrough": true},"9,2": {"honey": false,"passthrough": false},"9,3": {"honey": false,"passthrough": false},"9,4": {"honey": false,"passthrough": false},"9,5": {"honey": false,"passthrough": false,"pollenSource": true},"10,2": {"honey": false,"passthrough": false},"10,1": {"honey": false,"passthrough": true},"11,1": {"honey": false,"passthrough": false},"5,0": {"honey": false,"passthrough": false},"6,0": {"honey": false,"passthrough": false},"7,0": {"honey": false,"passthrough": false},"8,0": {"honey": false,"passthrough": false},"11,0": {"honey": false,"passthrough": false},"10,0": {"honey": false,"passthrough": false},"9,0": {"honey": false,"passthrough": false},"11,2": {"honey": false,"passthrough": false,"pollenSource": true},"12,0": {"honey": false,"passthrough": false,"pollenSource": true},"4,5": {"honey": false,"passthrough": false},"4,0": {"honey": false,"waterDrop": false,"passthrough": false},"3,0": {"honey": false,"waterDrop": false,"passthrough": false},"4,4": {"honey": false,"waterDrop": false,"passthrough": false},"5,5": {"honey": false,"waterDrop": false,"passthrough": false},"3,5": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"2,5": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"1,5": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"3,2": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"4,3": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"6,6": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"5,6": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false},"5,7": {"honey": false,"punk": 0,"babee": 0,"smoke": false,"waterDrop": false,"passthrough": false}}},"bees": {"5,7": {"zombee": 1},"5,6": {"zombee": 1}},"pollenOnBoard": 1,"allowBonus": 0.072,"collections": {}}'
data = json.loads(level_5_17)
seed(1234)
b = Board(data["board"])
init(b, 6)
rand_fill(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment