def minimax_1(self, current_depth: int, current_state: State) -> State or None:
        """
        Cette fonction contient la logique de l'algorithme minimax pour un
        seul joueur et retourne le meilleur coup à prendre à partir de l'état
        courant
        """
        self.rushhour.state = current_state

        possible_states = self.rushhour.get_possible_moves()
        current_state.score_heuristic_1(self.visited, self.rushhour.free_pos, self.rushhour.length,
                                        self.rushhour.move_on, self.rushhour.horiz)

        current_score = current_state.score

        if current_depth is self.search_depth or current_state.success():
            return current_state

        current_state.score = - (sys.maxsize - 1)
        best_state = None
        for possible_state in possible_states:
            possible_state.previous_state = None
            possible_state.nb_moves -= 1  # because it adds one in get_possible_moves
            tmp_state = self.minimax_1(current_depth + 1, possible_state)
            tmp_state.score += current_score
            if tmp_state is None: continue
            if current_state.score < tmp_state.score:
                current_state.score = tmp_state.score
                best_state = tmp_state

        return best_state if current_depth is 0 else current_state
예제 #2
0
    def test_print_move(self):
        rh = RushHour([True], [2], [2], ["rouge"])
        s = State([0])
        s = s.put_rock((3, 1))  # Roche dans la case 3-1
        s = s.move(0, 1)  # Voiture rouge vers la droite

        algo = MiniMaxSearch(rh, s, 1)
        self.assertEqual(algo.str_move(True, s), 'Voiture rouge vers la droite')
        self.assertEqual(algo.str_move(False, s), 'Roche dans la case 3-1')
예제 #3
0
 def testPossibleRockMoves(self):
     s = State([1, 0, 3, 1, 1, 4, 3, 4, 4, 2, 4, 1])
     self.rh.state = s
     sols = self.rh.possible_rock_moves()
     print(len(sols))
     self.assertEqual(7, len(sols))
     s1 = s.put_rock((3, 4))
     self.rh.state = s1
     sols = self.rh.possible_rock_moves()
     print(len(sols))
     self.assertEqual(3, len(sols))
    def test_blocking_heuristics(self):
        heuristics = Heuristics(RushHour(*rush_hour_data_1))
        nb = heuristics.blocking(State(state_data_1))
        self.assertEqual(2, nb)

        # heuristics = Heuristics(RushHour(*rush_hour_data_2))
        # nb = heuristics.blocking(State(state_data_2))
        # self.assertEqual(2, nb)

        heuristics = Heuristics(RushHour(*rush_hour_data_3))
        nb = heuristics.blocking(State(state_data_3))
        self.assertEqual(3, nb)
예제 #5
0
 def execute_minimax_single_player(self):
     rush_hour: RushHour = RushHour(*self.rush_hour_data)
     rush_hour.state = State(self.state_data)
     algo = MiniMaxSearch(rush_hour, rush_hour.state, 1)
     algo.rushhour.update_free_pos()
     algo.solve_single_player(verbose=False)
     print(rush_hour.state.nb_moves)
 def test_solve_expectimax(self):
     """
     best outcome = 9 moves
     """
     rush_hour = RushHour(*rush_hour_data_1)
     rush_hour.state = State(state_data_1)
     algo = ExpectimaxSearch(rush_hour, rush_hour.state, 3)
     nb_moves = self.execute_algo_single_player(algo)
     print(nb_moves)
     self.assertEqual(9, nb_moves)
예제 #7
0
 def execute_pruning(self, test_name):
     rush_hour: RushHour = RushHour(*self.rush_hour_data)
     rush_hour.state = State(self.state_data)
     algo = MiniMaxSearch(rush_hour, rush_hour.state, 3)
     algo.rushhour.update_free_pos()
     start = time()
     algo.solve_pruning(verbose=False)
     duration = (time() - start) * 1000
     self.table_maker.append_row([test_name, f'{duration:.2f}'])
     print(rush_hour.state.nb_moves)
예제 #8
0
    def test_hash_function(self):
        s0 = State([random.randint(1, 10) for i in range(12)])
        s1 = State([random.randint(1, 10) for i in range(12)])
        s2 = State([random.randint(1, 10) for i in range(12)])

        s0_copy = copy(s0)
        s1_copy = copy(s1)
        s2_copy = copy(s2)

        self.assertEqual(hash(s0), hash(s0_copy))
        self.assertEqual(hash(s1), hash(s1_copy))
        self.assertEqual(hash(s2), hash(s2_copy))

        self.assertNotEqual(hash(s0), hash(s1))
        self.assertNotEqual(hash(s0), hash(s2))

        self.assertNotEqual(hash(s1), hash(s0))
        self.assertNotEqual(hash(s1), hash(s2))

        self.assertNotEqual(hash(s2), hash(s0))
        self.assertNotEqual(hash(s2), hash(s1))
    def test_state_order_sanity(self):
        """
        validate state history make sense
        """
        rush_hour = RushHour(*rush_hour_data_1)
        rush_hour.state = State(state_data_1)
        algo = ExpectimaxSearch(rush_hour, rush_hour.state, 3)
        try:
            self.execute_algo_single_player(algo)
        except Exception:
            pass

        state_history = algo.state_history
        for i, in range(len(state_history) - 1):
            pair = (state_history[i],
                    state_history[i + 1])
            self.assertTrue(TestRushHour.states_are_consecutives(pair[0],
                                                                 pair[1]))
예제 #10
0
 def test_print_pretty(self):
     rh = RushHour(*rush_hour_data_1)
     state = State(state_data_1)
     rh.print_pretty_grid_and_update_free_pos(state)
예제 #11
0
    def testRocks(self):
        s0 = State([1, 0, 3, 1, 1, 4, 3, 4, 4, 2, 4, 1])
        s1 = s0.put_rock((4, 4))
        s2 = s1.put_rock((3, 2))

        print("État initial")

        self.rh.state = s0
        self.rh.print_pretty_grid_and_update_free_pos(s0)
        print(self.rh.free_pos)
        print('\n')
        grid_reference = np.array(
            [['-', '-', 'v', 'j', 'j', 'j'],
             ['o', '-', 'v', 'v', 'b', 'b'],
             ['o', 'r', 'r', 'v', '-', '-'],
             ['-', 'r', '-', 'v', 'v', 'v'],
             ['v', 'r', 'n', 'n', '-', 'b'],
             ['v', 'b', 'b', 'b', '-', 'b']],
            dtype='|S1'
        )
        free_pos_reference = np.array(
            [[True, True, False, False, False, False],
             [False, True, False, False, False, False],
             [False, False, False, False, True, True],
             [True, False, True, False, False, False],
             [False, False, False, False, True, False],
             [False, False, False, False, True, False]],
            dtype='bool'
        )

        np.testing.assert_array_equal(self.rh.get_formatted_grid_and_update_free_pos(s0), grid_reference)
        np.testing.assert_array_equal(self.rh.free_pos, free_pos_reference)

        print("Roche 4-4")

        self.rh.state = s1
        self.rh.update_free_pos()
        print(self.rh.free_pos)
        print('\n')
        grid_reference = np.array(
            [[b'-', b'-', b'v', b'j', b'j', b'j'],
             [b'o', b'-', b'v', b'v', b'b', b'b'],
             [b'o', b'r', b'r', b'v', b'-', b'-'],
             [b'-', b'r', b'-', b'v', b'v', b'v'],
             [b'v', b'r', b'n', b'n', b'x', b'b'],
             [b'v', b'b', b'b', b'b', b'-', b'b']],
            dtype='|S1'
        )
        free_pos_reference = np.array(
            [[True, True, False, False, False, False],
             [False, True, False, False, False, False],
             [False, False, False, False, True, True],
             [True, False, True, False, False, False],
             [False, False, False, False, False, False],
             [False, False, False, False, True, False]],
            dtype='bool'
        )
        np.testing.assert_array_equal(self.rh.get_formatted_grid_and_update_free_pos(s1), grid_reference)
        np.testing.assert_array_equal(self.rh.free_pos, free_pos_reference)

        print("Roche 3-2")

        self.rh.state = s2
        print(self.rh.free_pos)
        print('\n')
        grid_reference = np.array(
            [[b'-', b'-', b'v', b'j', b'j', b'j'],
             [b'o', b'-', b'v', b'v', b'b', b'b'],
             [b'o', b'r', b'r', b'v', b'-', b'-'],
             [b'-', b'r', b'x', b'v', b'v', b'v'],
             [b'v', b'r', b'n', b'n', b'-', b'b'],
             [b'v', b'b', b'b', b'b', b'-', b'b']],
            dtype='|S1'
        )
        free_pos_reference = np.array(
            [[True, True, False, False, False, False],
             [False, True, False, False, False, False],
             [False, False, False, False, True, True],
             [True, False, False, False, False, False],
             [False, False, False, False, True, False],  # Todo: Demander au chargé multiple rock à (4,4)
             [False, False, False, False, True, False]],
            dtype='bool'
        )
        np.testing.assert_array_equal(self.rh.get_formatted_grid_and_update_free_pos(s2), grid_reference)
        np.testing.assert_array_equal(self.rh.free_pos, free_pos_reference)