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
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)
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
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))
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