diff options
| -rw-r--r-- | levels/level_5.01.yaml | 10 | ||||
| -rwxr-xr-x | solver.py | 61 | 
2 files changed, 51 insertions, 20 deletions
diff --git a/levels/level_5.01.yaml b/levels/level_5.01.yaml new file mode 100644 index 0000000..3f6bd99 --- /dev/null +++ b/levels/level_5.01.yaml @@ -0,0 +1,10 @@ +# kana quest grid level 5.01 +size: [3, 3] +max_actions: 3 +target_score: 3 +grid: [ +  [slim, i   ], [slim, i   ], [void, null], +  [norm, ke  ], [norm, null], [norm, ni  ], +  [void, null], [norm, so  ], [void, null], +] +# The kana 'no' need to be protected else the program convert it into False... @@ -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  | 
