diff options
Diffstat (limited to 'solver.py')
| -rwxr-xr-x | solver.py | 87 | 
1 files changed, 45 insertions, 42 deletions
| @@ -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)) | 
