class Player:
    def __init__(self, colour):
        if colour == 'white':
            self.colour = constant.WHITE_PIECE
        elif colour == 'black':
            self.colour = constant.BLACK_PIECE

        # each players internal board representation
        self.board = Board()

        self.opponent = self.board.get_opp_piece_type(self.colour)

    def update(self, action):

        # update the board based on the action of the opponent
        # get move type
        if self.board.phase == constant.PLACEMENT_PHASE:
            self.board.update_board(action, self.opponent)

        elif self.board.phase == constant.MOVING_PHASE:
            if isinstance(action[0], tuple) is False:
                raise InvalidAction

            direction = self.board.convert_coord_to_direction(
                action[0], action[1])
            self.board.update_board((action[0], direction), self.opponent)

    def action(self, turns):
        available_actions = self.board.update_actions(self.colour)
        available_actions.sort()

        for i, action in enumerate(available_actions):
            print(str(i) + " : " + str(action))

        print("+" * 50)
        index = int(input("Enter move for {}: ".format(self.colour)))
        next_move = available_actions[index]
        print("+" * 50)

        print(self.board.move_counter)
        if self.board.phase == constant.PLACEMENT_PHASE:

            # making moves during the placement phase
            self.board.update_board(next_move, self.colour)
            return next_move
        else:
            new_pos = self.board.convert_direction_to_coord(
                next_move[0], next_move[1])
            # making moves during the placement phase
            self.board.update_board(next_move, self.colour)
            return next_move[0], new_pos
Example #2
0
class Manual(object):
    def __init__(self,player):
        self.board = Board()
        self.player = player

    def return_actions(self,player, piece_pos):
        if player == constant.WHITE_PIECE:
            my_pieces = self.board.white_pieces
        else:
            my_pieces = self.board.black_pieces

        if piece_pos in my_pieces:
            piece = my_pieces[piece_pos]
            return piece.get_legal_actions()
        else:
            return []

    def choose_action(self,action):
        self.board.update_board(action,self.player)

    def update_board(self,board):
        self.board = deepcopy(board)
Example #3
0
class Player:
    def __init__(self, colour):
        if colour == 'white':
            self.colour = constant.WHITE_PIECE
        elif colour == 'black':
            self.colour = constant.BLACK_PIECE

        # each players internal board representation
        self.board = Board()

        self.opponent = self.board.get_opp_piece_type(self.colour)

    def update(self, action):

        # update the board based on the action of the opponent
        # get move type
        if self.board.phase == constant.PLACEMENT_PHASE:
            self.board.update_board(action, self.opponent)

        elif self.board.phase == constant.MOVING_PHASE:
            if isinstance(action[0], tuple) is False:
                raise InvalidAction

            direction = self.board.convert_coord_to_direction(
                action[0], action[1])
            self.board.update_board((action[0], direction), self.opponent)
        # print("UPDATE BOARD _______________________________")
        # print(self.board)
        # print("UPDATE BOARD _______________________________")

    def action(self, turns):
        available_actions = self.board.update_actions(self.colour)
        next_action = available_actions[randint(0, len(available_actions) - 1)]

        if self.board.phase == constant.PLACEMENT_PHASE:
            # making moves during the placement phase
            self.board.update_board(next_action, self.colour)
            # print(next_action)
            return next_action
        else:
            new_pos = self.board.convert_direction_to_coord(
                next_action[0], next_action[1])
            # making moves during the placement phase
            # print(next_action)
            self.board.update_board(next_action, self.colour)
            #print(next_action)
            return next_action[0], new_pos
Example #4
0
class Window(Frame):
    def __init__(self, master=None):

        Frame.__init__(self, master)
        self.master = master
        self.p1_strategy = None
        self.p1_name = ""
        self.p1_name_obj = None
        self.p2_strategy = None
        self.p2_name = ""
        self.p2_name_obj = None
        self.canvas = None
        self.information = None

        # the board representation of this game
        self.board = None
        self.obj_dict = None
        self.info_objs = None
        self.init_window()

    def init_window(self):
        self.master.title("Watch Your Back")

        self.pack(fill=BOTH, expand=1)

        exit_button = Button(self, text="EXIT", command=self.exit_program)
        exit_button.place(x=5, y=5)

        self.canvas = Canvas(self)
        self.info_objs = []
        self.init_information()
        canvas = self.canvas

        self.board = Board()
        self.obj_dict = self.draw_board(canvas)
        self.draw_grid(canvas)
        canvas.pack(fill=BOTH, expand=1)
        # create the menu
        menu = Menu(self.master)
        self.master.config(menu=menu)

        # create the algorithm chooser
        player_1 = Menu(menu)
        player_1.add_command(label="Random", command=self.p1_random)
        player_1.add_command(label="Manual", command=self.p1_manual)
        player_1.add_command(label="Negamax - No Transpostion Table",
                             command=self.p1_negamax)
        player_1.add_command(label="Negamax - w/ Transpostion Table",
                             command=self.p1_negamax_tt)
        player_1.add_command(label="Negascout", command=self.p1_negascout)

        menu.add_cascade(label="Player 1", menu=player_1)

        player_2 = Menu(menu)
        player_2.add_command(label="Random", command=self.p2_random)
        player_2.add_command(label="Manual", command=self.p2_manual)
        player_2.add_command(label="Negamax - No Transpostion Table",
                             command=self.p2_negamax)
        player_2.add_command(label="Negamax - w/ Transpostion Table",
                             command=self.p2_negamax_tt)
        player_2.add_command(label="Negascout", command=self.p2_negascout)

        menu.add_cascade(label="Player 2", menu=player_2)

        # button
        begin_button = Button(text="BEGIN",
                              command=self.nextmove,
                              height=2,
                              width=10)
        begin_button.place(x=805, y=650)

    def nextmove(self):
        print("STARTED GAME")
        player = constant.WHITE_PIECE

        if self.p1_name in ("Random", "Human"):
            pass
        else:
            self.p1_strategy.update_board(self.board)

        if self.p2_name in ("Random", "Human"):
            pass
        else:
            self.p2_strategy.update_board(self.board)

        action = self.generate_moves(1)
        print("88888888888888")
        print(action)
        print("88888888888888")
        self.board.update_board(action, constant.WHITE_PIECE)
        print(self.board)
        # self.canvas.delete("all")
        self.draw_board(self.canvas)

        if self.p1_name in ("Random", "Human"):
            pass
        else:
            self.p1_strategy.update_board(self.board)

        if self.p2_name in ("Random", "Human"):
            pass
        else:
            self.p2_strategy.update_board(self.board)

        action = self.generate_moves(2)
        self.board.update_board(action, constant.BLACK_PIECE)
        self.draw_board(self.canvas)
        if self.p1_name in ("Random", "Human"):
            pass
        else:
            self.p1_strategy.update_board(self.board)

        if self.p2_name in ("Random", "Human"):
            pass
        else:
            self.p2_strategy.update_board(self.board)
        return
        # return

    def generate_moves(self, player):
        if player == 1:
            if self.p1_name == "Random":
                actions = self.board.update_actions(constant.WHITE_PIECE)
                action = actions[self.p1_strategy.choose_move(actions)]
                return action

            elif self.p1_name == "Negamax":
                action = self.p1_strategy.itr_negamax()
                return action
            elif self.p1_name == "TT":
                action = self.p1_strategy.itr_negamax()
                return action
            elif self.p1_name == "Human":
                pass
                action = self.p1_strategy.itr_negamax()
                return action
            elif self.p1_name == "NS":
                action = self.p1_strategy.itr_negascout()
                return action

        elif player == 2:
            if self.p2_name == "Random":
                actions = self.board.update_actions(constant.BLACK_PIECE)
                action = actions[self.p2_strategy.choose_move(actions)]
                return action
            elif self.p2_name == "Negamax":
                action = self.p2_strategy.itr_negamax()
                return action
            elif self.p2_name == "TT":
                action = self.p2_strategy.itr_negamax()
                return action
            elif self.p2_name == "Human":
                pass
                action = self.p1_strategy.itr_negamax()
                return action
            elif self.p2_name == "NS":
                action = self.p1_strategy.itr_negascout()
                return action

    def exit_program(self):
        exit()

    def p1_negamax(self):
        self.canvas.delete(self.p1_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.choose_negamax(1)
        self.p1_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 30,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 1: Negamax")
        self.p1_name = "Negamax"

    def p2_negamax(self):
        self.canvas.delete(self.p2_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.choose_negamax(2)
        self.p2_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 60,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 2: Negamax")
        self.p2_name = "Negamax"

    def p1_manual(self):
        self.canvas.delete(self.p1_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.choose_human(1)
        self.p1_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 30,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 1: Human")
        self.p1_name = "Human"

    def p2_manual(self):
        self.choose_human(2)
        self.canvas.delete(self.p2_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p2_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 60,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 2: Manual")
        self.p2_name = "Human"

    def p1_negamax_tt(self):
        self.choose_negamax_tt(1)
        self.canvas.delete(self.p1_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p1_name_obj = self.canvas.create_text(
            (x_1 + 20),
            y_1 + 30,
            anchor=W,
            font="Helvetica",
            text="Player 1: Negamax w/ TT")
        self.p1_name = "TT"

    def p2_negamax_tt(self):
        self.choose_negamax_tt(2)
        self.canvas.delete(self.p2_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p2_name_obj = self.canvas.create_text(
            (x_1 + 20),
            y_1 + 60,
            anchor=W,
            font="Helvetica",
            text="Player 2: Negamax w/ TT")
        self.p2_name = "TT"

    def p1_negascout(self):
        self.choose_negascout(1)
        self.canvas.delete(self.p1_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p1_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 30,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 1: Negascout")
        self.p1_name = "NS"

    def p2_negascout(self):
        self.choose_negascout(2)
        self.canvas.delete(self.p2_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p2_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 60,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 2: Negascout")
        self.p2_name = "NS"

    def p1_random(self):
        self.choose_random_player(1)
        self.canvas.delete(self.p1_name_obj)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p1_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 30,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 1: Random")
        self.p1_name = "Random"

    def p2_random(self):
        self.canvas.delete(self.p2_name_obj)
        self.choose_random_player(2)
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690
        self.p2_name_obj = self.canvas.create_text((x_1 + 20),
                                                   y_1 + 60,
                                                   anchor=W,
                                                   font="Helvetica",
                                                   text="Player 2: Random")
        self.p2_name = "Random"

    def choose_random_player(self, player):
        if player == 1:
            self.p1_strategy = Random()
            print("CHOOSE")
        else:
            self.p2_strategy = Random()

    def choose_negamax(self, player):
        if player == 1:
            self.p1_strategy = NMX(self.board, constant.WHITE_PIECE)
        else:
            self.p2_strategy = NMX(self.board, constant.BLACK_PIECE)

    def choose_negascout(self, player):
        if player == 1:
            self.p1_strategy = NSTT(self.board, constant.WHITE_PIECE)
        else:
            self.p2_strategy = NSTT(self.board, constant.BLACK_PIECE)

    def choose_negamax_tt(self, player):
        if player == 1:
            self.p1_strategy = NMXTT(self.board, constant.WHITE_PIECE)
        else:
            self.p2_strategy = NMXTT(self.board, constant.BLACK_PIECE)

    def choose_human(self, player):
        if player == 1:
            self.p1_strategy = Manual(constant.WHITE_PIECE)
        else:
            self.p2_strategy = Manual(constant.BLACK_PIECE)

    def choose_evaluation(self, filename):
        pass

    def draw_grid(self, canvas):
        spacing = 80
        offset = 50
        line_width = spacing * 8

        for i in range(8):
            canvas.create_line(offset + spacing * i, offset,
                               offset + spacing * i, line_width + offset)
            canvas.create_line(offset, offset + spacing * i,
                               line_width + offset, offset + spacing * i)

        canvas.create_line(offset, offset, line_width + offset, offset)
        canvas.create_line(offset, line_width + offset, offset, offset)
        canvas.create_line(offset, line_width + offset, line_width + offset,
                           line_width + offset)
        canvas.create_line(line_width + offset, offset, line_width + offset,
                           line_width + offset)
        canvas.pack(expand=0)

    @staticmethod
    def draw_boardpiece(canvas, row, col, piece_type):
        if piece_type == constant.INVALID_SPACE:
            colour = "#FF0000"
            size = 80
            offset = 50
            inset = 5
            x_1 = col * (size) + (offset + inset)
            y_1 = row * (size) + (offset + inset)

            x_2 = (col + 1) * (size) + (offset - inset)
            y_2 = (row + 1) * (size) + (offset - inset)
            # return the canvas object ID
            return canvas.create_rectangle(x_1,
                                           y_1,
                                           x_2,
                                           y_2,
                                           outline="#000",
                                           fill=colour,
                                           width=5)
        elif piece_type == constant.BLACK_PIECE:
            colour = "#000"
            size = 80
            offset = 50
            inset = 5
            x_1 = col * (size) + (offset + inset)
            y_1 = row * (size) + (offset + inset)

            x_2 = (col + 1) * (size) + (offset - inset)
            y_2 = (row + 1) * (size) + (offset - inset)

            # return the canvas object ID
            return canvas.create_oval(x_1,
                                      y_1,
                                      x_2,
                                      y_2,
                                      outline="#000",
                                      fill=colour,
                                      width=5)

        elif piece_type == constant.WHITE_PIECE:
            colour = "#FFFFFF"
            size = 80
            offset = 50
            inset = 5
            x_1 = col * (size) + (offset + inset)
            y_1 = row * (size) + (offset + inset)

            x_2 = (col + 1) * (size) + (offset - inset)
            y_2 = (row + 1) * (size) + (offset - inset)

            # return the canvas object ID
            return canvas.create_oval(x_1,
                                      y_1,
                                      x_2,
                                      y_2,
                                      outline="#000",
                                      fill=colour,
                                      width=5)
        elif piece_type == constant.CORNER_PIECE:
            size = 80
            offset = 50
            inset = 5
            x_1 = col * (size) + (offset + inset)
            y_1 = row * (size) + (offset + inset)

            x_2 = (col + 1) * (size) + (offset - inset)
            y_2 = (row + 1) * (size) + (offset - inset)

            # return the canvas object ID
            return canvas.create_rectangle(x_1,
                                           y_1,
                                           x_2,
                                           y_2,
                                           outline="#CBC2C0",
                                           fill="#CBC2C0",
                                           width=2)
        else:
            colour = "#FFFFFF"
            size = 80
            offset = 50
            inset = 5
            x_1 = col * (size) + (offset + inset)
            y_1 = row * (size) + (offset + inset)

            x_2 = (col + 1) * (size) + (offset - inset)
            y_2 = (row + 1) * (size) + (offset - inset)
            # return the canvas object ID
            return canvas.create_rectangle(x_1,
                                           y_1,
                                           x_2,
                                           y_2,
                                           outline=colour,
                                           fill=colour,
                                           width=5)

    def draw_board(self, canvas):
        piece_arr = {}
        # canvas.delete("all")
        # self.draw_grid(canvas)
        for row in range(8):
            for col in range(8):
                piece = self.board.get_board_piece(row, col)
                piece_arr.update({
                    (col, row):
                    self.draw_boardpiece(canvas, row, col, piece)
                })

        return piece_arr

    def init_information(self):
        c1 = "#000"
        c2 = "#FFFFF0"
        x_1 = 740
        y_1 = 50
        x_2 = 974
        y_2 = 690

        canvas = self.canvas
        self.info_objs.append(
            canvas.create_rectangle(x_1,
                                    y_1,
                                    x_2,
                                    y_2,
                                    outline=c1,
                                    fill=c2,
                                    width=2))
Example #5
0
class Player:
    def __init__(self, colour):
        # set the colour of the player
        if colour == 'white':
            self.colour = constant.WHITE_PIECE
        elif colour == 'black':
            self.colour = constant.BLACK_PIECE

        # each players internal board representation
        self.board = Board()

        # set up the minimax search strategy -- NEGAMAX
        self.minimax = Negamax(self.board, self.colour, "/eval_weights")

        # set the colour of the opponent
        self.opponent = self.board.get_opp_piece_type(self.colour)

        # set up the mini-max return values
        self.depth_eval = 0
        self.minimax_val = 0
        self.policy_vector = 0

        # initialise the action book
        self.action_book = ActionBook(self.colour)

    def update(self, action):
        # update the board based on the action of the opponent
        if self.board.phase == constant.PLACEMENT_PHASE:
            # update board also returns the pieces of the board that will be eliminated
            self.board.update_board(action, self.opponent)
            self.minimax.update_board(self.board)

        elif self.board.phase == constant.MOVING_PHASE:
            if isinstance(action[0], tuple) is False:
                print("ERROR: action is not a tuple")
                return

            # get the "to" square direction using the provided positions
            move_type = self.board.convert_coord_to_direction(
                action[0], action[1])

            # update the player board representation with the action
            self.board.update_board((action[0], move_type), self.opponent)

    def action(self, turns):

        # update the negamax/minimax board representation
        self.minimax.update_board(self.board)

        # reset the move counter of the board
        if turns == 0 and self.board.phase == constant.MOVING_PHASE:
            self.board.move_counter = 0
            self.board.phase = constant.MOVING_PHASE

        # check the action book to see if there is a state
        board_state = self.board.board_state
        if self.board.phase == constant.PLACEMENT_PHASE:
            action = self.action_book.check_state(board_state)

            # check if the action is legal
            if action is not None and self.board.check_free_square(
                    action) is True:
                # return the action found and update the board representations
                self.board.update_board(action, self.colour)
                self.minimax.update_board(self.board)
                return action

        # if there is no found state in the action book, therefore we just do a negamax search
        best_move = self.minimax.itr_negamax()

        self.depth_eval = self.minimax.eval_depth
        self.minimax_val = self.minimax.minimax_val

        # do an alpha beta search on this node
        # once we have found the best move we must apply it to the board representation
        if self.board.phase == constant.PLACEMENT_PHASE:
            self.board.update_board(best_move, self.colour)
            self.minimax.update_board(self.board)
            return best_move
        else:
            # if we are in moving phase, return the correctly formatted positions
            if best_move is None:
                self.board.update_board(best_move, self.colour)
                self.minimax.update_board(self.board)
                return None

            new_pos = Board.convert_direction_to_coord(best_move[0],
                                                       best_move[1])
            self.board.update_board(best_move, self.colour)
            self.minimax.update_board(self.board)
            return best_move[0], new_pos
a = board.apply_placement((2,2),constant.WHITE_PIECE)
b = board.apply_move((2,2), 1, constant.WHITE_PIECE)
print(board)
print(board.white_pieces)
print(board.black_pieces)
print(board.white_eliminate_pieces)
print(board.black_eliminate_pieces)
print(a, b)
e = board.update_board((2,2),constant.WHITE_PIECE)
print(board.get_piece((2,3)))
print("UNDO MOVE")
board.undo_move((2,2),constant.WHITE_PIECE, e)
print(board.get_piece((2,3)))
print(board)
'''
board.update_board((2, 2), constant.WHITE_PIECE)

board.update_board((3, 2), constant.BLACK_PIECE)
print("___________________________")
print(board.get_piece((2, 2)))
print(board.get_piece((3, 2)))
print("___________________________")
e = board.update_board((4, 2), constant.WHITE_PIECE)
print(board.white_pieces)
print("UNDO MOVE -------------------------------------")
board.undo_move((4, 2), constant.WHITE_PIECE, e)
print(board)
print(board.white_pieces)
print(board.black_pieces)
print("*" * 20)
print(board.get_piece((2, 2)))
class Player:

    def __init__(self, colour):
        if colour == 'white':
            self.colour = constant.WHITE_PIECE
        elif colour == 'black':
            self.colour = constant.BLACK_PIECE

        self.available_moves = []

        # each players internal board representation
        self.board = Board()

        # TODO -- need to see if this works correctly

        self.minimax = Negascout(self.board, self.colour)

        self.opponent = self.board.get_opp_piece_type(self.colour)

        self.depth_eval = 0
        self.minimax_val = 0
        self.policy_vector = 0

    def update(self, action):
        # update the board based on the action of the opponent
        if self.board.phase == constant.PLACEMENT_PHASE:
            # update board also returns the pieces of the board that will be eliminated
            self.board.update_board(action, self.opponent)
            # self.board.eliminated_pieces[self.opponent]
            self.minimax.update_board(self.board)

        elif self.board.phase == constant.MOVING_PHASE:
            if isinstance(action[0], tuple) is False:
                print("ERROR: action is not a tuple")
                return

            direction = self.board.convert_coord_to_direction(action[0], action[1])

            # update the player board representation with the action
            self.board.update_board((action[0], direction), self.opponent)
            self.minimax.update_board(self.board)

    def action(self, turns):
        self.minimax.update_board(self.board)

        if turns == 0 and self.board.phase == constant.MOVING_PHASE:
            self.board.move_counter = 0
            self.board.phase = constant.MOVING_PHASE

        # find the best move
        best_move = self.minimax.itr_negascout()
        # if the best move we have found so far is a Forfeit -- return this
        if best_move is None:
            self.board.update_board(best_move, self.colour)
            self.minimax.update_board(self.board)
            return None

        self.depth_eval = self.minimax.eval_depth
        self.minimax_val = self.minimax.minimax_val

        # once we have found the best move we must apply it to the board representation
        if self.board.phase == constant.PLACEMENT_PHASE:
            # print(best_move)
            self.board.update_board(best_move, self.colour)
            self.minimax.update_board(self.board)
            return best_move
        else:
            # (best_move is None)
            # print(best_move[0],best_move[1])
            new_pos = Board.convert_direction_to_coord(best_move[0], best_move[1])
            self.board.update_board(best_move, self.colour)
            self.minimax.update_board(self.board)
            return best_move[0], new_pos