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
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 }
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
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
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
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
def cutoff(self, state, depth): game_over = SeegaRules.is_end_game(state) return game_over or depth == 1 # greedy search
def is_end_game(state): return SeegaRules.is_end_game(state)
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