예제 #1
0
    def defensive_evaluation(self, state):
        defensive_coef = 1 / 8  # how safe the agent plays
        if state.phase == 2:
            score = state.get_player_info(self.position)["score"]
            opp_score = state.get_player_info(self.position * -1)["score"]
            balance = score - opp_score

            if SeegaRules.is_end_game(state) and balance < 0:
                return float('-inf')
            elif SeegaRules.is_end_game(state) and balance > 0:
                return float('inf')
            else:
                return defensive_coef + defensive_coef * self.safety_evaluation(
                    state)
        else:
            return 0
예제 #2
0
    def evaluate(self, state, details=False):
        """
        The evaluate function returns a value representing the utility function of the board.
        """
        # TODO necessity to make eval fucnction symmetric ??
        is_end = SeegaRules.is_end_game(state)
        captured = state.score[self.ME] - state.score[self.OTHER]
        other_is_stuck = state.phase == 2 and SeegaRules.is_player_stuck(
            state, self.OTHER)
        control_center = state.board.get_cell_color((2, 2)) == self.color

        # weights of liner interpolation of heuristics
        w_end = 100 * (-1 if captured < 0 else (0 if captured == 0 else 1))
        w_capt = 1
        w_stuck = 1
        w_center = 0.6

        random = .001 * np.random.random(
        )  # random is to avoid always taking the first move when there is a draw
        if not details:
            return w_capt * captured + \
                   w_stuck * (1 if other_is_stuck else 0) + \
                   w_end * (1 if is_end else 0) + \
                   w_center * (1 if control_center else 0) + \
                   random
        else:
            return {
                'captured': captured,
                'other_is_stuck': other_is_stuck,
                'is_end': is_end,
                'control_center': control_center
            }
예제 #3
0
    def cutoff(self, state, depth):
        """cutoff.
        The cutoff function returns true if the alpha-beta/minimax search has to stop and false otherwise.

        :param state: the state for which we want to know if we have to apply the cutoff
        :param depth: the depth of the cutoff
        """
        def timing_cutoff():
            return self._running_time > self._max_running_time

        def depth_cutoff():
            return depth > self._max_depth

        is_cutoff = False

        # Check if the game is at the end
        is_cutoff |= SeegaRules.is_end_game(state)

        # Get the cutoff from the current depth
        is_cutoff |= depth_cutoff()

        # Get the current cutoff from the time running the minimax
        is_cutoff |= timing_cutoff()

        # Track the maximum depth
        self._running_depth = max(self._running_depth, depth)

        return is_cutoff
예제 #4
0
 def cutoff(self, state, depth):
     """
     The cutoff function returns true if the alpha-beta/minimax search has to stop and false otherwise.
     """
     game_over = SeegaRules.is_end_game(state)
     max_depth = depth == self.max_depth or depth == absolute_max_depth
     cutoff = game_over or max_depth
     return cutoff
예제 #5
0
    def cutoff(self, state, depth):
        """cutoff.
        The cutoff function returns true if the alpha-beta/minimax search has to stop and false otherwise.

        :param state: the state for which we want to know if we have to apply the cutoff
        :param depth: the depth of the cutoff
        """
        return SeegaRules.is_end_game(state) or depth > 0
예제 #6
0
    def cutoff(self, state, depth):
        if state in self.state_dict and self.state_dict[state] == [
                state.score[-1], state.score[1]
        ]:  # Redundant state
            return True
        else:
            self.state_dict[state] = [state.score[-1], state.score[1]]

        if SeegaRules.is_end_game(state):
            return True
        else:
            if state.phase == 1 and depth > 0:
                return True
            if depth > self.depth:
                return True
            else:
                if time.time() - self.start_time > self.remaining_time:
                    return True
                else:
                    return False
예제 #7
0
 def cutoff(self, state, depth):
     game_over = SeegaRules.is_end_game(state)
     return game_over or depth == 1  # greedy search
예제 #8
0
def is_end_game(state):
    return SeegaRules.is_end_game(state)
예제 #9
0
    def evaluate(self, state):
        """evaluate.
        The evaluate function must return an integer value representing the utility function of the board.

        :param state: the state for which we want the evaluation scalar
        """
        cell_groups = dict(
            center=(2, 2),
            star_center=[(2, 1), (2, 3), (1, 2), (3, 2)],
            square_center=[(1, 1), (1, 3), (3, 1), (3, 3)],
            star_ext=[(2, 0), (2, 4), (0, 2), (4, 2)],
            square_ext=[(0, 0), (0, 4), (4, 0), (4, 4)],
        )

        def player_wins(player):
            return state.score[player] == state.MAX_SCORE

        def evaluate_cells(color):
            def is_player_cell(cell, color):
                return state.board.get_cell_color(cell) == color

            def direct_center_score():
                score = 0.0
                for base_cell in cell_groups["star_center"]:
                    for oponent_cell, ext_cell in zip(
                            cell_groups["star_center"],
                            cell_groups["star_ext"]):
                        if (is_player_cell(base_cell, color)
                                and is_player_cell(oponent_cell, -color)
                                and is_player_cell(ext_cell, color)):
                            score += 1
                return score

            score = 0.0

            if state.phase == 1:
                score += direct_center_score()
            else:
                score += is_player_cell(cell_groups["center"], color)

            return score

        score = 0.0

        if state.phase == 1:

            score += evaluate_cells(self.position)
            score -= evaluate_cells(-self.position)

        elif state.phase == 2:

            # Self score
            score += state.score[self.position]
            score -= state.score[-self.position]

            score += evaluate_cells(self.color)
            score -= evaluate_cells(self.oponent)

            # Winning state
            if SeegaRules.is_end_game(state):
                score += 100 if self._alpha_winning(state) > 0.5 else -100

        return score