diff options
| -rw-r--r-- | levels/level_4.05.yaml | 4 | ||||
| -rw-r--r-- | levels/level_4.06.yaml | 11 | ||||
| -rw-r--r-- | levels/level_4.07.yaml | 6 | ||||
| -rw-r--r-- | levels/level_4.08.yaml | 4 | ||||
| -rw-r--r-- | levels/level_4.10.yaml | 6 | ||||
| -rw-r--r-- | levels/level_4.15.yaml | 6 | ||||
| -rw-r--r-- | levels/level_4.16.yaml | 8 | ||||
| -rw-r--r-- | levels/level_4.17.yaml | 12 | ||||
| -rw-r--r-- | levels/level_4.18.yaml | 11 | ||||
| -rw-r--r-- | levels/level_4.19.yaml | 11 | ||||
| -rw-r--r-- | levels/template_level_X.XX.yaml | 6 | ||||
| -rwxr-xr-x | solver.py | 87 | ||||
| -rw-r--r-- | tests_solver/level_test_ar_x.yaml | 2 | ||||
| -rw-r--r-- | tests_solver/level_test_type.yaml | 4 | ||||
| -rw-r--r-- | tests_solver/test_solver.py | 66 | 
15 files changed, 142 insertions, 102 deletions
diff --git a/levels/level_4.05.yaml b/levels/level_4.05.yaml index 9606662..0316d78 100644 --- a/levels/level_4.05.yaml +++ b/levels/level_4.05.yaml @@ -5,8 +5,8 @@ max_actions: 8  target_score: 7  grid: [    [void, null], [myst, su  ], [void, null], [myst, ko  ], [void, null], -  [froz, se  ], [empt, null], [empt, null], [empt, null], [froz, so  ], -  [froz, ku  ], [empt, null], [empt, null], [empt, null], [froz, 'no'], +  [froz, se  ], [norm, null], [norm, null], [norm, null], [froz, so  ], +  [froz, ku  ], [norm, null], [norm, null], [norm, null], [froz, 'no'],    [void, null], [void, null], [rock, ka  ], [void, null], [void, null],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.06.yaml b/levels/level_4.06.yaml index 000ad57..6ed80d0 100644 --- a/levels/level_4.06.yaml +++ b/levels/level_4.06.yaml @@ -1,11 +1,12 @@  # kana quest grid level 4.6  size: [4, 4] -max_actions: 13 +max_actions: 12 +#max_actions: 13  target_score: 7  grid: [ -    [myst, ka  ], [empt, null], [empt, null ], [froz, ke  ], -    [empt, null], [norm, ko  ], [empt, null ], [rock, so  ], -    [empt, null], [empt, null], [empt, null ], [empt, null], -    [froz, sa  ], [rock, ki  ], [empt, null ], [rock, se  ], +    [myst, ka  ], [norm, null], [norm, null ], [froz, ke  ], +    [norm, null], [norm, ko  ], [norm, null ], [rock, so  ], +    [norm, null], [norm, null], [norm, null ], [norm, null], +    [froz, sa  ], [rock, ki  ], [norm, null ], [rock, se  ],  ] diff --git a/levels/level_4.07.yaml b/levels/level_4.07.yaml index 992f104..28218c3 100644 --- a/levels/level_4.07.yaml +++ b/levels/level_4.07.yaml @@ -3,8 +3,8 @@ size: [7, 3]  max_actions: 9  target_score: 5  grid: [ -  [void, null], [empt, null], [empt, null], [empt, null], [empt, null], [ar_l, ko  ], [void, null], -  [froz, 'no'], [empt, null], [empt, null], [rock, sa  ], [empt, null], [empt, null], [froz, ne  ], -  [void, null], [ar_r, se  ], [empt, null], [empt, null], [empt, null], [empt, null], [void, null], +  [void, null], [norm, null], [norm, null], [norm, null], [norm, null], [ar_l, ko  ], [void, null], +  [froz, 'no'], [norm, null], [norm, null], [rock, sa  ], [norm, null], [norm, null], [froz, ne  ], +  [void, null], [ar_r, se  ], [norm, null], [norm, null], [norm, null], [norm, null], [void, null],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.08.yaml b/levels/level_4.08.yaml index 813301e..43bb483 100644 --- a/levels/level_4.08.yaml +++ b/levels/level_4.08.yaml @@ -4,7 +4,7 @@ max_actions: 6  target_score: 4  grid: [    [void, null], [void, null], [void, null], [void, null], [rock, ne  ], [void, null], -  [froz, so  ], [void, null], [froz, se  ], [void, null], [empt, null], [void, null], -  [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], [ar_l, ko  ], +  [froz, so  ], [void, null], [froz, se  ], [void, null], [norm, null], [void, null], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [ar_l, ko  ],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.10.yaml b/levels/level_4.10.yaml index 3affafc..7c2fdde 100644 --- a/levels/level_4.10.yaml +++ b/levels/level_4.10.yaml @@ -3,8 +3,8 @@ size: [7, 3]  max_actions: 10  target_score: 7  grid: [ -  [void, null], [void, null], [void, null], [norm, sa  ], [empt, null], [norm, 'no'], [void, null], -  [void, null], [void, null], [void, null], [void, null], [empt, null], [void, null], [void, null], -  [rock, se  ], [ar_l, ko  ], [ar_l, na  ], [ar_l, so  ], [empt, null], [empt, null], [froz, ke  ], +  [void, null], [void, null], [void, null], [norm, sa  ], [norm, null], [norm, 'no'], [void, null], +  [void, null], [void, null], [void, null], [void, null], [norm, null], [void, null], [void, null], +  [rock, se  ], [ar_r, ko  ], [ar_r, na  ], [ar_r, so  ], [norm, null], [norm, null], [froz, ke  ],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.15.yaml b/levels/level_4.15.yaml index 8d16c12..7e76f22 100644 --- a/levels/level_4.15.yaml +++ b/levels/level_4.15.yaml @@ -4,8 +4,8 @@ max_actions: 9  #max_actions: 8  target_score: 6  grid: [ -  [froz, ne  ], [froz, ku  ], [void, null], [empt, null], [froz, ko  ], [void, null], -  [empt, null], [empt, null], [myst, su  ], [empt, null], [empt, null], [rock, so  ], -  [empt, null], [empt, null], [rock, se  ], [empt, null], [empt, null], [void, null], +  [froz, ne  ], [froz, ku  ], [void, null], [norm, null], [froz, ko  ], [void, null], +  [norm, null], [norm, null], [myst, su  ], [norm, null], [norm, null], [rock, so  ], +  [norm, null], [norm, null], [rock, se  ], [norm, null], [norm, null], [void, null],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.16.yaml b/levels/level_4.16.yaml index 45cb826..77bc954 100644 --- a/levels/level_4.16.yaml +++ b/levels/level_4.16.yaml @@ -4,9 +4,9 @@ max_actions: 15  #max_actions: 16  target_score: 7  grid: [ -  [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], [froz, 'no'], -  [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], -  [empt, null], [empt, null], [rock, ni  ], [empt, null], [rock, so  ], [empt, null], [empt, null], -  [fblk, null], [rock, se  ], [froz, sa  ], [empt, null], [empt, null], [rock, su  ], [froz, ne  ], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [froz, 'no'], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], +  [norm, null], [norm, null], [rock, ni  ], [norm, null], [rock, so  ], [norm, null], [norm, null], +  [froz, null], [rock, se  ], [froz, sa  ], [norm, null], [norm, null], [rock, su  ], [froz, ne  ],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.17.yaml b/levels/level_4.17.yaml new file mode 100644 index 0000000..96b411b --- /dev/null +++ b/levels/level_4.17.yaml @@ -0,0 +1,12 @@ +# kana quest grid level 1.01 +size: [7, 4] +max_actions: 8 +#max_actions: 12 +target_score: 7 +grid: [ +  [void, null], [void, null], [norm, null], [norm, null], [froz, so  ], [void, null], [void, null], +  [norm, null], [norm, null], [rock, se  ], [norm, null], [rock, 'no'], [norm, null], [froz, sa  ], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], +  [froz, su  ], [norm, null], [norm, null], [froz, ko  ], [froz, ke  ], [norm, null], [norm, null], +] +# The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.18.yaml b/levels/level_4.18.yaml new file mode 100644 index 0000000..4eddc09 --- /dev/null +++ b/levels/level_4.18.yaml @@ -0,0 +1,11 @@ +# kana quest grid level 1.01 +size: [7, 3] +max_actions: 9 +#max_actions: 10 +target_score: 7 +grid: [ +  [froz, null], [norm, null], [froz, 'no'], [froz, su  ], [norm, null], [norm, null], [froz, ke  ], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], +  [rock, sa  ], [norm, null], [rock, se  ], [norm, null], [rock, ne  ], [norm, null], [rock, so  ], +] +# The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/level_4.19.yaml b/levels/level_4.19.yaml new file mode 100644 index 0000000..8d3c4d5 --- /dev/null +++ b/levels/level_4.19.yaml @@ -0,0 +1,11 @@ +# kana quest grid level 1.01 +size: [7, 4] +max_actions: 17 +target_score: 8 +grid: [ +  [void, null], [void, null], [froz, se  ], [void, null], [void, null], [void, null], [void, null], +  [ar_r, ne  ], [ar_r, ke  ], [norm, null], [norm, null], [norm, null], [norm, null], [ar_d, null], +  [norm, null], [norm, null], [norm, null], [norm, null], [ar_l, sa  ], [ar_l, na  ], [ar_d, null], +  [ar_r, ka  ], [ar_r, ki  ], [norm, null], [norm, null], [norm, null], [norm, null], [ar_u, so  ], +] +# The kana 'no' need to be protected else the program convert it into False... diff --git a/levels/template_level_X.XX.yaml b/levels/template_level_X.XX.yaml index 78b9477..9165e8f 100644 --- a/levels/template_level_X.XX.yaml +++ b/levels/template_level_X.XX.yaml @@ -3,7 +3,9 @@ size: [1, 1]  max_actions: 1  target_score: 1  grid: [ -  [void, null], [myst, su  ], [rock, hu  ], [norm, ku  ], [froz, nu  ], -  [empt, null], [empt, null], [empt, null], [empt, null], [empt, null], +  [void, null], [myst, su  ], [rock, hu  ], [norm, ku  ], [froz, nu  ], [froz, null], [ar_u, mu  ], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], +  [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null], [norm, null],  ]  # The kana 'no' need to be protected else the program convert it into False... @@ -20,10 +20,8 @@ import yaml  class Kana: -    types_without_kana = ('void', 'empt', 'fblk') -    types_valid_for_chain = ('norm', 'froz', 'rock', 'ar_u', 'ar_l', 'ar_d', 'ar_r') -    types_with_kana = types_valid_for_chain + ('myst', ) -    types_all = types_with_kana + types_without_kana +    types = ('void', 'norm', 'froz', 'rock', 'myst', +             'ar_u', 'ar_l', 'ar_d', 'ar_r')      def __init__(self, type_name, kana=None):          self.type_name = type_name @@ -31,10 +29,12 @@ class Kana:          #print(type_name)          #print(kana) -        assert type_name in self.types_all -        if type_name in self.types_with_kana: -            assert kana[0] in ('k', 's', 'n', 'h', 't', 'm') -            assert kana[1] in ('a', 'i', 'u', 'e', 'o') +        assert type_name in self.types + +        # missing yet: 'n' and 'y...' and 'w...' are not we all vowels +        if kana: +            assert kana[0] in 'kstnhmryw' +            assert kana[1] in 'aiueo'      def __repr__(self):          return "%s(%s)" % (self.type_name, self.kana) @@ -47,14 +47,16 @@ kana_void = Kana('void')  class KanaGrid: -    def __init__(self, size, grid, action_count=0, score=0, parent=None): +    def __init__(self, size, grid, +                 action_count=0, score=0, myst_count=0, parent=None):          self.width = size[0]          self.height = size[1]          self.grid = grid          self.action_count = action_count          self.score = score -        self.parent = None +        self.myst_count = myst_count +        self.parent = parent      def copy(self):          return KanaGrid( @@ -62,21 +64,20 @@ class KanaGrid:                  copy.copy(self.grid),                  action_count=self.action_count,                  score=self.score, +                myst_count=self.myst_count,                  parent=self.parent, -                ) +        )      def is_swappable(self, pos1, pos2):          kana1 = self.get_kana(pos1)          kana2 = self.get_kana(pos2)          table_ok = { -            'norm': ('norm', 'empt', 'froz', 'fblk', 'ar_u', 'ar_r', 'ar_d', 'ar_l'), -            'empt': ('norm',         'froz', 'fblk', 'ar_u', 'ar_r', 'ar_d', 'ar_l'), -            'froz': ('norm', 'empt',                 'ar_u', 'ar_r', 'ar_d', 'ar_l'), -            'fblk': ('norm', 'empt',                 'ar_u', 'ar_r', 'ar_d', 'ar_l'), -            'ar_u': ('norm', 'empt', 'froz', 'fblk',                 'ar_d'        ), -            'ar_r': ('norm', 'empt', 'froz', 'fblk',                         'ar_l'), -            'ar_d': ('norm', 'empt', 'froz', 'fblk', 'ar_u'                        ), -            'ar_l': ('norm', 'empt', 'froz', 'fblk',         'ar_r'                ), +            'norm': ('norm', 'froz', 'ar_u', 'ar_r', 'ar_d', 'ar_l'), +            'froz': ('norm',         'ar_u', 'ar_r', 'ar_d', 'ar_l'), +            'ar_u': ('norm', 'froz',                 'ar_d'        ), +            'ar_r': ('norm', 'froz',                         'ar_l'), +            'ar_d': ('norm', 'froz', 'ar_u'                        ), +            'ar_l': ('norm', 'froz',         'ar_r'                ),          }          if kana1.type_name in table_ok:              if kana2.type_name in table_ok[kana1.type_name]: @@ -123,13 +124,16 @@ class KanaGrid:          for y in range(self.height):              for x in range(self.width):                  kana = self.get_kana((x, y)) -                if kana.type_name in Kana.types_valid_for_chain: +                if kana.kana:                      yield (x, y)      def populate_chain(self, pos1, chain_positions): +        myst_count = 0          if pos1 in chain_positions: -            return +            return myst_count          kana1 = self.get_kana(pos1) +        if kana1.type_name == 'myst': +            myst_count += 1          chain_positions.add(pos1)          pos2_list = [                  (pos1[0], pos1[1]-1), # up @@ -141,27 +145,32 @@ class KanaGrid:              if pos2 in chain_positions:                  continue              kana2 = self.get_kana(pos2) -            if kana2.type_name in Kana.types_valid_for_chain: +            if kana2.kana:                  if is_kana_compatible(kana1, kana2): -                    self.populate_chain(pos2, chain_positions) +                    myst_count += self.populate_chain(pos2, chain_positions) +        return myst_count      def longest_chain(self):          already_evaluated_pos = set()          highest_length = 0          highest_length_chain = 0 +        highest_myst_count = 0          for pos in self.generate_valid_pos_for_chain():              if pos in already_evaluated_pos:                  continue              chain = set() -            self.populate_chain(pos, chain) +            myst_count = self.populate_chain(pos, chain)              already_evaluated_pos = already_evaluated_pos.union(chain) +            if myst_count > highest_myst_count: +                highest_myst_count = myst_count              if highest_length < len(chain):                  highest_length = len(chain)                  highest_length_chain = chain -        return highest_length #, highest_length_chain # easy to add if needed +        return highest_length, highest_myst_count +        #, highest_length_chain # easy to add if needed      def update_score(self): -        self.score = self.longest_chain() +        self.score, self.myst_count = self.longest_chain()      def get_hash(self):          data = ''.join(( @@ -244,14 +253,14 @@ class KanaGrid:  def repr_grid(grid, grid_size):      indicator_map = { +            'norm': (' ', ' '), +            'froz': ('\x1b[36m[', ']\x1b[0m'), +            'rock': (' \x1b[1;40m', '\x1b[0m '), +            'myst': ('\x1b[33m?', '?\x1b[0m'),              'ar_u': ('\x1b[30m∧\x1b[0m', '\x1b[30m∧\x1b[0m'),              'ar_r': ('\x1b[30m>\x1b[0m', '\x1b[30m>\x1b[0m'),              'ar_d': ('\x1b[30m∨\x1b[0m', '\x1b[30m∨\x1b[0m'),              'ar_l': ('\x1b[30m<\x1b[0m', '\x1b[30m<\x1b[0m'), -            'froz': (' \x1b[36m', '\x1b[0m '), -            'fblk': (' \x1b[36m[]', '\x1b[0m '), -            'rock': (' \x1b[1;40m', '\x1b[0m '), -            'myst': ('\x1b[33m?', '?\x1b[0m'),      }      lines = []      kana_iter = iter(grid) @@ -260,23 +269,17 @@ def repr_grid(grid, grid_size):          for x in range(grid_size[0]):              kana = next(kana_iter)              tname = kana.type_name +            kkana = kana.kana +            if not kkana: +                kkana = '  '              if tname == 'void':                  line += '      ' -            elif tname == 'empt': -                line += '|    |' -            elif tname == 'fblk': -                line += '|%s%s|' % ( -                        indicator_map[tname][0], -                        indicator_map[tname][1], -                )              elif tname in indicator_map:                  line += '|%s%s%s|' % (                          indicator_map[tname][0], -                        kana.kana, +                        kkana,                          indicator_map[tname][1],                  ) -            elif kana.type_name in Kana.types_with_kana: -                line += '| %s |' % kana.kana          lines.append(line)      return '\n'.join(lines) @@ -298,7 +301,7 @@ def generate_possible_grids(kanagrid):                  new_grid = kanagrid.action((x, y), action_type)                  #if new_grid and new_grid.grid != kanagrid.grid:                  #    yield (x, y), action_type, new_grid -                if new_grid is not None: +                if new_grid is not None and new_grid.grid != kanagrid.grid:                      yield (x, y), action_type, new_grid # debug test @@ -350,7 +353,7 @@ def main():      generate_all_possible_grids(kanagrid, grids=grids, max_actions=max_actions)      for grid in grids.values():          grid.update_score() -        if grid.score >= target_score: +        if grid.score >= target_score and grid.myst_count == 0:              print("="*80)              if args['-p']:                  print(repr_grid_with_parents(grid)) diff --git a/tests_solver/level_test_ar_x.yaml b/tests_solver/level_test_ar_x.yaml index 633a843..45e50d1 100644 --- a/tests_solver/level_test_ar_x.yaml +++ b/tests_solver/level_test_ar_x.yaml @@ -3,6 +3,6 @@ size: [3, 1]  max_actions: 1  target_score: 2  grid: [ -  [ar_r, su  ], [empt, null], [norm, so  ], +  [ar_r, su  ], [norm, null], [norm, so  ],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/tests_solver/level_test_type.yaml b/tests_solver/level_test_type.yaml index 0eec70a..f48634f 100644 --- a/tests_solver/level_test_type.yaml +++ b/tests_solver/level_test_type.yaml @@ -3,7 +3,7 @@ size: [6, 2]  max_actions: 6  target_score: 8  grid: [ -  [ar_r, sa  ], [empt, null], [norm, so  ], [rock, se  ], [myst, ka  ], [ar_d, na  ], -  [ar_u, su  ], [ar_l, nu  ], [void, null], [void, null], [void, null], [froz, ke  ], +  [ar_r, sa  ], [norm, null], [norm, so  ], [rock, se  ], [myst, ka  ], [ar_d, na  ], +  [ar_u, su  ], [ar_l, nu  ], [void, null], [void, null], [froz, null], [froz, ke  ],  ]  # The kana 'no' need to be protected else the program convert it into False... diff --git a/tests_solver/test_solver.py b/tests_solver/test_solver.py index 82aca73..03d68ed 100644 --- a/tests_solver/test_solver.py +++ b/tests_solver/test_solver.py @@ -13,8 +13,9 @@ def test_is_swappable():      swappable_grids = [              [Kana("norm", "su"), Kana("norm", "su")],              [Kana("froz", "su"), Kana("norm", "su")], -            [Kana("norm", "su"), Kana("empt"      )], -            [Kana("empt"      ), Kana("froz", "su")], +            [Kana("norm", "su"), Kana("norm"      )], +            [Kana("norm"      ), Kana("froz", "su")], +            [Kana("norm"      ), Kana("norm"      )],      ]      for swappable_grid in swappable_grids: @@ -25,7 +26,6 @@ def test_is_swappable():      not_swappable_grids = [              [Kana("norm", "su"), Kana("rock", "su")],              [Kana("froz", "su"), Kana("froz", "su")], -            [Kana("empt"      ), Kana("empt"      )],      ]      for not_swappable_grid in not_swappable_grids: @@ -38,8 +38,8 @@ def test_kana_grid():      initial_grid = [          kana_void         , Kana("myst", "su"), kana_void         , Kana("myst", "ko"), kana_void         , -        Kana("froz", "se"), Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), Kana("froz", "so"), -        Kana("froz", "ku"), Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), Kana("froz", "no"), +        Kana("froz", "se"), Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), Kana("froz", "so"), +        Kana("froz", "ku"), Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), Kana("froz", "no"),          kana_void         , kana_void         , Kana("rock", "ka"), kana_void         , kana_void         ,      ]      initial_grid_size = 5, 4 @@ -47,8 +47,8 @@ def test_kana_grid():      expected_grid = [          kana_void         , Kana("myst", "su"), kana_void         , Kana("myst", "ko"), kana_void         , -        Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), Kana("froz", "se"), Kana("froz", "so"), -        Kana("froz", "ku"), Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), Kana("froz", "no"), +        Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), Kana("froz", "se"), Kana("froz", "so"), +        Kana("froz", "ku"), Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), Kana("froz", "no"),          kana_void         , kana_void         , Kana("rock", "ka"), kana_void         , kana_void         ,      ] @@ -66,9 +66,9 @@ def test_kana_grid():  def test_kana_arrow_swap(): -    kanagrid_orig = KanaGrid((2, 1), [Kana("ar_r", "su"), Kana("empt",)]) +    kanagrid_orig = KanaGrid((2, 1), [Kana("ar_r", "su"), Kana("norm",)])      kanagrid_new = kanagrid_orig.action(pos=(0, 0), action_type="right") -    expected_grid = KanaGrid((2, 1), [Kana("empt",), Kana("ar_r", "su")]) +    expected_grid = KanaGrid((2, 1), [Kana("norm",), Kana("ar_r", "su")])      print("kanagrid_orig")      print(kanagrid_orig) @@ -86,14 +86,14 @@ def test_kana_arrow_swap():              'other_move_ok': 'down',              'dest_pos': (1, 0),              'orig': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("ar_u", "ko"), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("ar_u", "ko"), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ]),              'moved': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("ar_u", "ko"), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("ar_u", "ko"), Kana("void"      ), +                Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ], action_count=1),          },          { @@ -101,14 +101,14 @@ def test_kana_arrow_swap():              'other_move_ok': 'left',              'dest_pos': (2, 1),              'orig': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("ar_r", "ko"), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("ar_r", "ko"), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ]),              'moved': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("ar_r", "ko"), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("norm"      ), Kana("ar_r", "ko"), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ], action_count=1),          },          { @@ -116,14 +116,14 @@ def test_kana_arrow_swap():              'other_move_ok': 'up',              'dest_pos': (1, 2),              'orig': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("ar_d", "ko"), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("ar_d", "ko"), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ]),              'moved': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("ar_d", "ko"), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("norm"      ), Kana("norm"      ), +                Kana("void"      ), Kana("ar_d", "ko"), Kana("void"      ),              ], action_count=1),          },          { @@ -131,14 +131,14 @@ def test_kana_arrow_swap():              'other_move_ok': 'right',              'dest_pos': (0, 1),              'orig': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("ar_l", "ko"), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("norm"      ), Kana("ar_l", "ko"), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ]),              'moved': KanaGrid((3, 3), [ -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), -                Kana("ar_l", "ko"), Kana("empt"      ), Kana("empt"      ), -                Kana("empt"      ), Kana("empt"      ), Kana("empt"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ), +                Kana("ar_l", "ko"), Kana("norm"      ), Kana("norm"      ), +                Kana("void"      ), Kana("norm"      ), Kana("void"      ),              ], action_count=1),          },      ]  | 
