def test_get_valid_next_moves_1(self): self.board = np.array([ [1, 1, 1, 1], [1, 1, 1, 0], [0, 0, 0, 0] ]) self.tiles = [(2, 1), (1, 2)] self.state = State(self.board, self.tiles) next_moves = SolutionChecker.get_valid_next_moves(self.state, self.tiles) self.assertEqual(next_moves, [(2, 1)])
def test_get_valid_next_moves_2(self): self.board = np.array([ [1, 1, 1, 1], [1, 1, 1, 0], [0, 0, 0, 0] ]) tiles_list = [(2, 1), (1, 2), (3, 3), (4, 4), (1, 1)] self.tiles = sorted(tiles_list, key=lambda x: (x[1], x[0])) self.state = State(self.board, self.tiles) next_moves = SolutionChecker.get_valid_next_moves(self.state, self.tiles) self.assertEqual(next_moves, [(1, 1), (2, 1)])
def perform_simulation(self, state): ''' Performs the simulation until legal moves are available. If simulation ends by finding a solution, a root state starting from this simulation is returned ''' solution_tiles_order = [] depth = 0 simulation_root_state = state # in case simulation ends in solution; these states are the solution if len(state.tiles) == 0: print('perform_simulation called with empty tiles') return ALL_TILES_USED, simulation_root_state, solution_tiles_order val = self.val while True: val += 1 if len(state.tiles) == 0: print('solution found in simulation') return ALL_TILES_USED, simulation_root_state, solution_tiles_order valid_moves = SolutionChecker.get_valid_next_moves(state, state.tiles, val=val, colorful_states=self.colorful_states) if not valid_moves: return depth, simulation_root_state, solution_tiles_order next_random_tile_index = random.randint(0, len(valid_moves) -1) success, new_board = SolutionChecker.get_next_turn( state, valid_moves[next_random_tile_index], val, destroy_state=True, colorful_states=self.colorful_states ) self.n_tiles_placed += 1 solution_tiles_order.append(valid_moves[next_random_tile_index]) if success == ALL_TILES_USED: print('grid is full') # no LFB on grid; probably means grid is full solution_tiles_order.append(valid_moves[next_random_tile_index]) return ALL_TILES_USED, simulation_root_state, solution_tiles_order elif success == NO_NEXT_POSITION_TILES_UNUSED: print('no next position with unused tiles') return depth, simulation_root_state, solution_tiles_order elif success == TILE_CANNOT_BE_PLACED: # cannot place the tile. return depth reached return depth, simulation_root_state, solution_tiles_order else: new_tiles = SolutionChecker.eliminate_pair_tiles(state.tiles, valid_moves[next_random_tile_index]) new_state = State(board=new_board, tiles=new_tiles, parent=state) new_state.score = -1 # because no choice is performed for sequent actions state.children.append(new_state) state = new_state depth += 1 return depth, simulation_root_state, solution_tiles_order