Beispiel #1
0
 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)])
Beispiel #2
0
    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)])
Beispiel #3
0
    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