Exemplo n.º 1
0
    def __init__(self, setup_time, player_color, time_per_k_turns, k):
        abstract.AbstractPlayer.__init__(self, setup_time, player_color,
                                         time_per_k_turns, k)
        self.clock = time.time()

        # We are simply providing (remaining time / remaining turns) for each turn in round.
        # Taking a spare time of 0.05 seconds.
        self.turns_remaining_in_round = self.k
        self.time_remaining_in_round = self.time_per_k_turns
        self.time_for_current_move = self.time_remaining_in_round / self.turns_remaining_in_round - 0.05
        self.book = OpeningBook()
        self.prev_state = GameState()
        self.moves_list = ""
        self.book_to_our_dic = self.build_book_to_our_dic()
        self.our_to_book_dic = self.build_our_to_book_dic()
Exemplo n.º 2
0
    def run(self):
        """The main loop.
        :return: The winner.
        """
        # Setup each player
        x_player_exceeded = self.setup_player(
            sys.modules[self.x_player].Player, X_PLAYER)
        o_player_exceeded = self.setup_player(
            sys.modules[self.o_player].Player, O_PLAYER)
        winner = self.handle_time_expired(x_player_exceeded, o_player_exceeded)
        if winner:  # One of the players exceeded the setup time
            return winner

        board_state = GameState()
        remaining_run_times = copy.deepcopy(self.player_move_times)
        k_count = 0

        # Running the actual game loop. The game ends if someone is left out of moves,
        # or exceeds his time.
        while True:
            if self.verbose == 'y':
                board_state.draw_board()

            player = self.players[board_state.curr_player]
            remaining_run_time = remaining_run_times[board_state.curr_player]
            try:
                possible_moves = board_state.get_possible_moves()
                if not possible_moves:
                    winner = self.make_winner_result(board_state.get_winner())
                    break
                # Get move from player
                move, run_time = utils.run_with_limited_time(
                    player.get_move,
                    (copy.deepcopy(board_state), possible_moves), {},
                    remaining_run_time * 1.5)

                remaining_run_times[board_state.curr_player] -= run_time
                if remaining_run_times[board_state.curr_player] < 0:
                    raise utils.ExceededTimeError
            except (utils.ExceededTimeError, MemoryError):
                print('Player {} exceeded resources.'.format(player))
                winner = self.make_winner_result(
                    OPPONENT_COLOR[board_state.curr_player])
                break

            board_state.perform_move(move[0], move[1])
            if self.verbose == 'y':
                print('Player ' + repr(player) + ' performed the move: [' +
                      str(move[0]) + ', ' + str(move[1]) + ']')

            if board_state.curr_player == X_PLAYER:
                k_count = (k_count + 1) % self.k
                if k_count == 0:
                    # K rounds completed. Resetting timers.
                    remaining_run_times = copy.deepcopy(self.player_move_times)

        self.end_game(winner)
        return winner
Exemplo n.º 3
0
    def __init__(self, setup_time, player_color, time_per_k_turns, k):
        AbstractPlayer.__init__(self, setup_time, player_color,
                                time_per_k_turns, k)
        self.clock = None

        # We are simply providing (remaining time / remaining turns) for each turn in round.
        # Taking a spare time of 0.05 seconds.
        self.turns_remaining_in_round = self.k
        self.time_remaining_in_round = self.time_per_k_turns
        self.time_for_current_move = self.time_remaining_in_round / self.turns_remaining_in_round - 0.05

        # New fields - for section F
        self.dict_for_10_common_openings = self._calculate_ten_common_openings(
        )
        self.moves_till_now = ""
        self.game_board = GameState().board
        if self.color == X_PLAYER:
            self.sign = '+'
            self.opponent_sign = '-'
            self.num_round = 1
        else:
            self.sign = '-'
            self.opponent_sign = '+'
            self.num_round = 4
        self.board_opening_lost_track = False
Exemplo n.º 4
0
    def __init__(self, setup_time, player_color, time_per_k_turns, k):
        abstract.AbstractPlayer.__init__(self, setup_time, player_color, \
                time_per_k_turns, k)
        self.clock = time.time()

        # We are simply providing (remaining time / remaining turns) for each \
        #       turn in round.
        # Taking a spare time of 0.05 seconds.
        self.turns_remaining_in_round = self.k
        self.time_remaining_in_round = self.time_per_k_turns
        self.time_for_current_move = self.time_remaining_in_round / \
                self.turns_remaining_in_round - 0.05
        # keep the game-moves as a string
        self.moves = ''
        self.last_state = GameState()

        # chose board configuration
        if self.color == O_PLAYER:
            # will be set after opponent first move
            self.book2reality = None
            self.reality2book = None
        else:
            self.book2reality = self.book2reality1
            self.reality2book = self.reality2book1

        self.alpha_beta_algorithm = MiniMaxWithAlphaBetaPruning(self.utility, \
                self.color, self.no_more_time, None)

        # for performence
        self.max_steps_left = 62

        # create opening book
        opening_book = {}
        f = open("best_70_opens.gam", 'r')
        # FIXME: remove error check before submmision
        if not f:
            print("cannot open file")
            sys.exit(1)

        # assume we play first and update otherwise
        first_move_index = 0
        if self.color == O_PLAYER:
            first_move_index = 1

        for line in f:
            tmp = line.split(' ')[1]
            tmp = re.split(r'[+-]', tmp)
            moves = ''.join(tmp)
            for i in range(first_move_index, 10, 2):
                tmp = re.split('r[+-]', moves)
                key = moves[0:2 * i]
                if key not in opening_book:
                    opening_book[key] = moves[2 * i:2 * i + 2]
        f.close()
        self.opening_book = opening_book
Exemplo n.º 5
0
def _is_in_immediate_danger(state: GameState, x: int, y: int, player_on_tile, x_direction: int, y_direction: int) -> bool:
    curr_x = x + x_direction
    curr_y = y + y_direction
    opposite_x = x - x_direction
    opposite_y = y - y_direction

    if not state.isOnBoard(x-x_direction, y-y_direction):
        return False

    if (state.board[curr_x][curr_y] == EM and state.board[opposite_x][opposite_y] == OPPONENT_COLOR[player_on_tile]) \
            or (state.board[curr_x][curr_y] == OPPONENT_COLOR[player_on_tile] and state.board[opposite_x][opposite_y] == EM):
        return True
Exemplo n.º 6
0
    def __init__(self, setup_time, player_color, time_per_k_turns, k):
        abstract.AbstractPlayer.__init__(self, setup_time, player_color, time_per_k_turns, k)
        self.clock = time.time()

        # We are simply providing (remaining time / remaining turns) for each turn in round.
        # Taking a spare time of 0.05 seconds.
        self.turns_remaining_in_round = self.k
        self.time_remaining_in_round = self.time_per_k_turns
        self.time_for_current_move = self.time_remaining_in_round / self.turns_remaining_in_round - 0.05
        self._last_game_state = ''
        self._last_game_board = GameState().board
        self.opening_dict = ExtractMostPopularOpenningMoves(70)
        self.opponent_sign = '-' if self.color == 'X' else '+'
Exemplo n.º 7
0
def simple_utility(state: GameState, color: str):
    if len(state.get_possible_moves()) == 0:
        return INFINITY if state.curr_player != color else -INFINITY

    my_u = 0
    op_u = 0
    for x in range(BOARD_COLS):
        for y in range(BOARD_ROWS):
            if state.board[x][y] == color:
                my_u += 1
            if state.board[x][y] == OPPONENT_COLOR[color]:
                op_u += 1

    if my_u == 0:
        # I have no tools left
        return -INFINITY
    elif op_u == 0:
        # The opponent has no tools left
        return INFINITY
    else:
        return my_u - op_u
Exemplo n.º 8
0
class Player(abstract.AbstractPlayer):
    def __init__(self, setup_time, player_color, time_per_k_turns, k):
        abstract.AbstractPlayer.__init__(self, setup_time, player_color,
                                         time_per_k_turns, k)
        self.clock = time.time()

        # We are simply providing (remaining time / remaining turns) for each turn in round.
        # Taking a spare time of 0.05 seconds.
        self.turns_remaining_in_round = self.k
        self.time_remaining_in_round = self.time_per_k_turns
        self.time_for_current_move = self.time_remaining_in_round / self.turns_remaining_in_round - 0.05
        self.book = OpeningBook()
        self.prev_state = GameState()
        self.moves_list = ""
        self.book_to_our_dic = self.build_book_to_our_dic()
        self.our_to_book_dic = self.build_our_to_book_dic()

    def get_move(self, game_state, possible_moves):
        self.clock = time.time()
        self.time_for_current_move = self.time_remaining_in_round / self.turns_remaining_in_round - 0.05
        if len(possible_moves) == 1:
            return possible_moves[0]

        best_move = self.opening_move(game_state)

        if best_move == None:
            best_move = possible_moves[0]
            next_state = copy.deepcopy(game_state)
            next_state.perform_move(best_move[0], best_move[1])
            # Choosing an arbitrary move
            # Get the best move according the utility function
            for move in possible_moves:
                new_state = copy.deepcopy(game_state)
                new_state.perform_move(move[0], move[1])
                if self.utility(new_state) > self.utility(next_state):
                    next_state = new_state
                    best_move = move
            self.moves_list = self.moves_list + "+" + self.our_to_book_dic[
                best_move[0]][best_move[1]]
            self.prev_state = next_state

        if self.turns_remaining_in_round == 1:
            self.turns_remaining_in_round = self.k
            self.time_remaining_in_round = self.time_per_k_turns
        else:
            self.turns_remaining_in_round -= 1
            self.time_remaining_in_round -= (time.time() - self.clock)

        return best_move

    def utility(self, state):
        mobility_adv = self.mobility_adv(state)
        if mobility_adv > 100 or mobility_adv < -100:
            return mobility_adv

        coin_adv = self.coin_adv(state)
        if coin_adv > 100 or coin_adv < -100:
            return coin_adv

        corner_adv = self.corner_adv(state)
        corner_closeness_adv = self.corner_closeness_adv(state)

        weight_total_adv = (0.50 * coin_adv) + (0.30 * corner_adv) + (
            0.15 * corner_closeness_adv) + (0.05 * mobility_adv)

        return weight_total_adv

    def coin_adv(self, state):
        my_coins = 0
        op_coins = 0
        for x in range(BOARD_COLS):
            for y in range(BOARD_ROWS):
                if state.board[x][y] == self.color:
                    my_coins += 1
                if state.board[x][y] == OPPONENT_COLOR[self.color]:
                    op_coins += 1

        if my_coins == 0:
            # I have no tools left
            return -INFINITY
        elif op_coins == 0:
            # The opponent has no tools left
            return INFINITY

        if my_coins > op_coins:
            coin_adv = (100.0 * my_coins) / (my_coins + op_coins)
        elif my_coins < op_coins:
            coin_adv = -(100.0 * op_coins) / (my_coins + op_coins)
        else:
            coin_adv = 0

        return coin_adv

    def corner_adv(self, state):
        me, op = self.get_colors()
        my_corners = 0
        op_corners = 0
        if state.board[0][0] == me:
            my_corners += 1
        elif state.board[0][0] == op:
            op_corners += 1
        if state.board[0][7] == me:
            my_corners += 1
        elif state.board[0][7] == op:
            op_corners += 1
        if state.board[7][0] == me:
            my_corners += 1
        elif state.board[7][0] == op:
            op_corners += 1
        if state.board[7][7] == me:
            my_corners += 1
        elif state.board[7][7] == op:
            op_corners += 1

        corner_adv = 25 * (my_corners - op_corners)

        return corner_adv

    def get_colors(self):
        me = self.color
        if me == 'O':
            op = 'X'
        else:
            op = 'O'
        return me, op

    def corner_closeness_adv(self, state):
        me, op = self.get_colors()
        my_coins = 0
        op_coins = 0

        if state.board[0][0] == EM:
            if state.board[0][1] == me:
                my_coins += 1
            elif state.board[0][1] == op:
                op_coins += 1
            if state.board[1][1] == me:
                my_coins += 1
            elif state.board[1][1] == op:
                op_coins += 1
            if state.board[1][0] == me:
                my_coins += 1
            elif state.board[1][0] == op:
                op_coins += 1

        if state.board[0][7] == EM:
            if state.board[0][6] == me:
                my_coins += 1
            elif state.board[0][6] == op:
                op_coins += 1
            if state.board[1][6] == me:
                my_coins += 1
            elif state.board[1][6] == op:
                op_coins += 1
            if state.board[1][7] == me:
                my_coins += 1
            elif state.board[1][7] == op:
                op_coins += 1

        if state.board[7][0] == EM:
            if state.board[7][1] == me:
                my_coins += 1
            elif state.board[7][1] == op:
                op_coins += 1
            if state.board[6][1] == me:
                my_coins += 1
            elif state.board[6][1] == op:
                op_coins += 1
            if state.board[6][0] == me:
                my_coins += 1
            elif state.board[6][0] == op:
                op_coins += 1

        if state.board[7][7] == EM:
            if state.board[6][7] == me:
                my_coins += 1
            elif state.board[6][7] == op:
                op_coins += 1
            if state.board[6][6] == me:
                my_coins += 1
            elif state.board[6][6] == op:
                op_coins += 1
            if state.board[7][6] == me:
                my_coins += 1
            elif state.board[7][6] == op:
                op_coins += 1

        corner_closeness = -8.333 * (my_coins - op_coins)

        return corner_closeness

    def mobility_adv(self, state):
        me, op = self.get_colors()

        my_state = copy.deepcopy(state)
        my_state.curr_player = me
        my_possible_moves = len(my_state.get_possible_moves())
        if my_possible_moves == 0:
            return -INFINITY

        op_state = copy.deepcopy(state)
        op_state.curr_player = op
        op_possible_moves = len(op_state.get_possible_moves())
        if op_possible_moves == 0:
            return INFINITY

        if my_possible_moves > op_possible_moves:
            mobility = (100.0 * my_possible_moves) / (my_possible_moves +
                                                      op_possible_moves)
        elif my_possible_moves < op_possible_moves:
            mobility = -(100.0 * op_possible_moves) / (my_possible_moves +
                                                       op_possible_moves)
        else:
            mobility = 0

        return mobility

    def selective_deepening_criterion(self, state):
        # Better player does not selectively deepen into certain nodes.
        return False

    def no_more_time(self):
        return (time.time() - self.clock) >= self.time_for_current_move

    def __repr__(self):
        return '{} {}'.format(abstract.AbstractPlayer.__repr__(self), 'better')

    def opening_move(self, state):
        if len(self.moves_list) >= 30:
            return None

        if self.prev_state.board == state.board:
            book_move = self.book.dic[self.moves_list]
            self.moves_list = self.moves_list + book_move
            reg_move = self.book_to_our_dic[book_move[1:3]]
            self.prev_state.perform_move(reg_move[0], reg_move[1])
            return reg_move

        opp_move = self.find_opp_move(state)
        if len(self.moves_list) % 2 == 0:
            opp_move = "+" + opp_move
        else:
            opp_move = "-" + opp_move
        self.moves_list = self.moves_list + opp_move
        self.prev_state = copy.deepcopy(state)
        if self.moves_list in self.book.dic.keys():
            book_move = self.book.dic[self.moves_list]
            self.moves_list = self.moves_list + book_move
            reg_move = self.book_to_our_dic[book_move[1:3]]
            self.prev_state.perform_move(reg_move[0], reg_move[1])
            return reg_move

        return None

    def build_our_to_book_dic(self):
        dic = {}
        for x in range(BOARD_COLS):
            dic[x] = {}
            for y in range(BOARD_ROWS):
                key = [x, y]
                val = chr(ord('h') - 7 + y) + chr(ord('8') - x)
                dic[x][y] = val
        return dic

    def build_book_to_our_dic(self):
        dic = {}
        for x in range(BOARD_COLS):
            for y in range(BOARD_ROWS):
                key = chr(ord('a') + x) + chr(ord('1') + y)
                val = [7 - y, x]
                dic[key] = val
        return dic

    def find_opp_move(self, state):
        for x in range(BOARD_COLS):
            for y in range(BOARD_ROWS):
                if (self.prev_state.board[x][y] == EM
                        and state.board[x][y] != EM and state.board[x][y]):
                    return self.our_to_book_dic[x][y]
Exemplo n.º 9
0
import sys
from players.AI2_302279138_303086854.better_player import Player
from Reversi.board import GameState

## __init__ test
player = Player(2, 'X', 10, 5)
assert (player.moves == '')
assert (player.last_state == GameState())
assert (player.book2reality == player.book2reality1)

player = Player(2, 'O', 10, 5)
assert (player.moves == '')
assert (player.last_state == GameState())
assert (player.book2reality == None)

# book2reality1 test
assert (player.book2reality1('a1') == 'a8')
assert (player.book2reality1('f7') == 'f2')

# reality2book1 test
assert (player.reality2book1('a8') == 'a1')
assert (player.reality2book1('f2') == 'f7')
assert (player.reality2book1('d6') == 'd3')

# book2reality2 test
assert (player.book2reality2('a1') == 'h1')
assert (player.book2reality2('c4') == 'f4')

# reality2book2 test
assert (player.reality2book2('h1') == 'a1')
assert (player.reality2book2('f4') == 'c4')
Exemplo n.º 10
0
def better_utility(state: GameState, color: str):
    # Add 3 more parameters when calculating how much the state is 'good'
    opp_color = OPPONENT_COLOR[color]

    # Calculate Disks parameter
    curr_disks = 0
    opp_disks = 0
    for x in range(BOARD_COLS):
        for y in range(BOARD_ROWS):
            if state.board[x][y] == color:
                curr_disks += 1
            if state.board[x][y] == opp_color:
                opp_disks += 1

    disks_parameter = 100 * (curr_disks - opp_disks) / (curr_disks + opp_disks)

    # Calculate Mobility parameter
    real_curr_player = state.curr_player
    state.curr_player = color
    curr_mobility = len(state.get_possible_moves())
    state.curr_player = opp_color
    opp_mobility = len(state.get_possible_moves())
    state.curr_player = real_curr_player

    # Check if we got to a final state and in which condition.
    if not curr_mobility or not opp_mobility:  # Final state
        return INFINITY if curr_disks > opp_disks else -INFINITY

    mobility_parameter = 0 if curr_mobility + opp_mobility == 0 else 100 * (curr_mobility - opp_mobility) / (curr_mobility + opp_mobility)

    # Calculate Corners parameter
    curr_corners = 0
    opp_corners = 0
    corners = [(0, 0), (0, 7), (7, 7), (7, 0)]
    for x, y in corners:
        curr_board_place = state.board[x][y]
        if curr_board_place == color:
            curr_corners += 1
        elif curr_board_place == opp_color:
            opp_corners += 1

    corners_parameter = 0 if curr_corners + opp_corners == 0 \
        else 100 * (curr_corners - opp_corners) / (curr_corners + opp_corners)

    # Calculate Stability parameter
    stability = {color: curr_corners, opp_color: opp_corners}
    for x in range(BOARD_COLS):
        for y in range(BOARD_ROWS):
            if (x, y) in corners:
                continue
            else:
                player_on_tile = state.board[x][y]
                if player_on_tile == EM:
                    continue
                for x_direction, y_direction in [(0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)]:
                    curr_x = x + x_direction  # step in the direction
                    curr_y = y + y_direction  # step in the direction
                    if state.isOnBoard(curr_x, curr_y):
                        if state.board[curr_x][curr_y] == player_on_tile:
                            # The tile is adjacent to a corner
                            if (curr_x, curr_y) in corners and (x_direction, y_direction) not in [(1, 1), (1, -1), (-1, -1), (-1, 1)]:
                                stability[player_on_tile] += 1
                                break
                        # The tile is in immediate danger
                        elif _is_in_immediate_danger(state, x, y, player_on_tile, x_direction, y_direction):
                            stability[player_on_tile] -= 1
                            break

    stability_parameter = 0 if stability[color] + stability[opp_color] == 0 \
        else 100 * (stability[color] - stability[opp_color]) / (stability[color] + stability[opp_color])

    return 25*disks_parameter + 8*mobility_parameter + 12*corners_parameter + 25*stability_parameter