diff options
Diffstat (limited to 'solver.py')
-rwxr-xr-x | solver.py | 61 |
1 files changed, 41 insertions, 20 deletions
@@ -20,8 +20,9 @@ import yaml class Kana: - types = ('void', 'norm', 'froz', 'rock', 'myst', - 'ar_u', 'ar_l', 'ar_d', 'ar_r') + types = ('void', 'norm', 'froz', 'rock', 'myst', 'slim', + 'ar_u', 'ar_r', 'ar_d', 'ar_l') + slime_merge_types = ('norm', 'froz', 'ar_u', 'ar_r', 'ar_d', 'ar_l') def __init__(self, type_name, kana=None): self.type_name = type_name @@ -33,8 +34,11 @@ class Kana: # missing yet: 'n' and 'y...' and 'w...' are not we all vowels if kana: - assert kana[0] in 'kstnhmryw' - assert kana[1] in 'aiueo' + if type_name == 'slim': + assert kana[0] in 'aiueo' + else: + assert kana[0] in 'kstnhmryw' + assert kana[1] in 'aiueo' def __repr__(self): return "%s(%s)" % (self.type_name, self.kana) @@ -47,6 +51,8 @@ kana_void = Kana('void') class KanaGrid: + actions = ('reveal', 'up', 'right', 'down', 'left') + def __init__(self, size, grid, action_count=0, score=0, myst_count=0, parent=None): @@ -98,23 +104,35 @@ class KanaGrid: return False def action(self, pos, action_type): - if action_type == "reveal": - kana = self.get_kana(pos) + kana = self.get_kana(pos) + if action_type == 'reveal': if kana.type_name == 'myst': new_grid = self.copy() new_grid.action_count += 1 new_grid.set_kana(pos, Kana('norm', kana.kana)) return new_grid - elif action_type in ("up", "right", "down", "left"): - if action_type == "up": - pos_dest = (pos[0], pos[1]-1) - elif action_type == "right": - pos_dest = (pos[0]+1, pos[1]) - elif action_type == "down": - pos_dest = (pos[0], pos[1]+1) - elif action_type == "left": - pos_dest = (pos[0]-1, pos[1]) - if self.is_swappable(pos, pos_dest): + elif action_type in ('up', 'right', 'down', 'left'): + pos_map = { + 'up': (pos[0], pos[1]-1), + 'right': (pos[0]+1, pos[1]), + 'down': (pos[0], pos[1]+1), + 'left': (pos[0]-1, pos[1]), + } + pos_dest = pos_map[action_type] + if kana.type_name == 'slim': + kana2 = self.get_kana(pos_dest) + if kana2.type_name in Kana.slime_merge_types and kana2.kana: + new_grid = self.copy() + new_grid.action_count += 1 + new_kana1 = Kana('void') + new_kana2 = Kana( + kana2.type_name, + kana2.kana[0] + kana.kana[0], + ) + new_grid.set_kana(pos, new_kana1) + new_grid.set_kana(pos_dest, new_kana2) + return new_grid + elif self.is_swappable(pos, pos_dest): new_grid = self.copy() new_grid.action_count += 1 new_grid.swap_kana(pos, pos_dest) @@ -124,7 +142,7 @@ class KanaGrid: for y in range(self.height): for x in range(self.width): kana = self.get_kana((x, y)) - if kana.kana: + if kana.kana and kana.type_name != 'slim': yield (x, y) def populate_chain(self, pos1, chain_positions): @@ -145,7 +163,7 @@ class KanaGrid: if pos2 in chain_positions: continue kana2 = self.get_kana(pos2) - if kana2.kana: + if kana2.kana and kana2.type_name != 'slim': if is_kana_compatible(kana1, kana2): myst_count += self.populate_chain(pos2, chain_positions) return myst_count @@ -257,6 +275,7 @@ def repr_grid(grid, grid_size): 'froz': ('\x1b[36m[', ']\x1b[0m'), 'rock': (' \x1b[1;40m', '\x1b[0m '), 'myst': ('\x1b[33m?', '?\x1b[0m'), + 'slim': ('\x1b[32m~', '~\x1b[0m'), 'ar_u': ('\x1b[31m∧\x1b[0m', '\x1b[31m∧\x1b[0m'), 'ar_r': ('\x1b[31m>\x1b[0m', '\x1b[31m>\x1b[0m'), 'ar_d': ('\x1b[31m∨\x1b[0m', '\x1b[31m∨\x1b[0m'), @@ -275,7 +294,7 @@ def repr_grid(grid, grid_size): if tname == 'void': line += ' ' elif tname in indicator_map: - line += '|%s%s%s|' % ( + line += '|%s%2s%s|' % ( indicator_map[tname][0], kkana, indicator_map[tname][1], @@ -289,6 +308,8 @@ def display_grid(grid, grid_size): def is_kana_compatible(kana1, kana2): + if kana1.type_name == 'slim' or kana2.type_name == 'slim': + return False if kana1.kana[0] == kana2.kana[0] or kana1.kana[1] == kana2.kana[1]: return True return False @@ -297,7 +318,7 @@ def is_kana_compatible(kana1, kana2): def generate_possible_grids(kanagrid): for y in range(kanagrid.height): for x in range(kanagrid.width): - for action_type in ("reveal", "up", "right", "down", "left"): + for action_type in KanaGrid.actions: new_grid = kanagrid.action((x, y), action_type) if new_grid and new_grid.grid != kanagrid.grid: yield (x, y), action_type, new_grid |