def __init__(self, m, n, mode): # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) # save size and mode self.size = [m,n] self.mode = mode # just to init the value self._currentPlayer = 1 # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) # set the game to entry point self.start(self._currentPlayer) if self.UIRequired(): # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.MachineGUI.gameLoop()
def gameLoop(self): print("Entering Game Loop") player = 1 Q = [] while self.IterationCounter < self.targetIterations: q= 0 while not self._finished: q += 1 if player == 0: player = 1 else: player = 0 move = self.KI[player].nextMove() self.KI[0].receiveMove(move) self.KI[1].receiveMove(move) self.Game.makeMove(move) #print(self.KI[player].PatternMatcher.mapGameState()) if q < 50: Q.append(q) self.IterationCounter = self.IterationCounter + 1 for key, value in self.Game.HexBoard.Vertices.items(): if value.player == self.Game.HexBoard.winner(): self.WonVertices.append(str(value.i) + ";" + str(value.j)) if self.IterationCounter // (self.targetIterations / 20) != self.q: self.q = self.IterationCounter // (self.targetIterations / 20) print(round(self.IterationCounter/self.targetIterations * 100,1), "%", self.IterationCounter) self.Game.HexBoard = HexBoard(self.size[0], self.size[1]) self.Game.HexBoard.setReferenceToGame(self.Game) self._finished = False self.start() print("FINISHED") f = open('output.txt', 'r+') f.write("Move Count: Average:" + str(round(sum(Q) / len(Q))) + ", Min:", str(min(Q)) + ", Max:" + str(max(Q)) + str(Q)) print(collections.Counter(self.WonVertices))
def __init__(self, m, n, mode): # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) EventManager.subscribe("MoveFinished", self.onMoveFinished) # save size and mode self.size = [m,n] self.mode = mode # just to init the value self._currentPlayer = 1 self._currentPlayerType = "human" # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) if self.mode == "ki": self.KI = MainKI(self) # set the game to entry point self.start(self._currentPlayer) if self.UIRequired(): # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.MachineGUI.gameLoop()
def start(self, firstPlayer): EventManager.notify("GameStarting") # move counter init self.moveCounter = 0 # generate fresh state self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) # current player depending on decision self._currentPlayer = firstPlayer # if random number wanted, generate one if firstPlayer == 0: self.chooseFirst() EventManager.notify("GameStarted")
def minimax(hex_board, depth, max_or_min, evaluator): """The minimax algorithm on the HexBoard Args: hex_board (HexBoard): The current hex board. depth (int): maximum depth to search max_or_min (str): maximise or minimise the current color to play (hex_board.blue_to_move). Is either 'min' or 'max'. evaluator (function): evaluator function. Called with args hex_board, maximiser_color Returns: int: maximised/minimised value according to the evaluator """ moves = hex_board.get_free_positions() maximiser_color = [hex_board.BLUE, hex_board.RED][(max_or_min == 'max') ^ (hex_board.blue_to_move)] is_game_over = False if hex_board.check_win(hex_board.BLUE) or hex_board.check_win(hex_board.RED): is_game_over = True # minimax: if depth <= 0 or is_game_over or len(moves) == 0: # end state return (evaluator(hex_board, maximiser_color)) elif max_or_min == 'max': # maximise value = float('-inf') for move in moves: deepened_board = HexBoard(board.board_size, n_players=2, enable_gui=False, interactive_text=False, ai_move=None, blue_ai_move=None, red_ai_move=None, move_list=board.move_list) deepened_board.set_position_auto(move) new_value = minimax(deepened_board, depth - 1, 'min', evaluator) value = [value, new_value][new_value > value] return value elif (max_or_min == 'min'): # minimise value = float('inf') for move in moves: deepened_board = HexBoard(board.board_size, n_players=2, enable_gui=False, interactive_text=False, ai_move=None, blue_ai_move=None, red_ai_move=None, move_list=board.move_list) deepened_board.set_position_auto(move) new_value = minimax(deepened_board, depth - 1, 'max', evaluator) value = [value, new_value][new_value < value] return value print("@minimax: unknown max_or_min objective", max_or_min) return None
class Game: def __init__(self, m, n, mode): # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) # save size and mode self.size = [m, n] self.mode = mode # just to init the value self._currentPlayer = 1 self._currentPlayerType = "human" # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) if self.mode == "ki" or self.mode == "machine": self.KI = PatternKI(self) # set the game to entry point self.start(self._currentPlayer) if self.UIRequired(): # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.MachineGUI.gameLoop() def UIRequired(self): if self.mode == "human" or self.mode == "ki" or self.mode == "inter": return True else: return False def start(self, firstPlayer): EventManager.notify("GameStarting") # move counter init self.moveCounter = 0 # generate fresh state self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) # current player depending on decision self._currentPlayer = firstPlayer if self.mode == "ki" or self.mode == "machine": self.KI = PatternKI(self) # if random number wanted, generate one if firstPlayer == 0: self.chooseFirst() EventManager.notify("GameStarted") def onGameStarted(self): if self.UIRequired(): # draw the gui self.HexGUI.draw() # Game finished event def onGameFinished(self): if self.UIRequired(): # move over to main menu and present the winner self.HexGUI.openPage("menu") self.HexGUI.won(self.HexBoard.winner()) # generate random player number def chooseFirst(self): self._currentPlayer = round(random.random()) + 1 # is the getter for the private variable def currentPlayer(self): return self._currentPlayer # is the current Player human? def isPlayerHuman(self): return self._currentPlayerType == "human" # alter the players def changePlayer(self): if self._currentPlayer == 1: self._currentPlayer = 2 else: self._currentPlayer = 1 if self.mode == "ki": if self._currentPlayerType == "human": self._currentPlayerType = "ki" else: self._currentPlayerType = "human" # control flow for click event def makeMove(self, move): # Notify EventManager.notify("MoveBegan") # if already marked dont do anything if self.HexBoard.isMarked(move[1], move[0]): EventManager.notify("MoveDenied") else: # otherwise count the click self.moveCounter = self.moveCounter + 1 # notify Model self.HexBoard.receiveMove(move) # notify View self.changePlayer() EventManager.notify("PlayerChanged") if not self.isPlayerHuman(): move = self.KI.getMove() self.makeMove(move) EventManager.notify("MoveFinished")
def get_elo_and_time(N, C_p, max_time=0, debug=False): if debug: print("Evaluting N=%d and C_p=%.3f" % (N, C_p)) BOARD_SIZE = 6 MAX_TURNS = BOARD_SIZE**2 N_ROUNDS = 12 terminator = TerminatorHex.TerminatorHex(2, do_transposition=False, max_time=max_time) terminator_player_move = terminator.terminator_move MCTS_AI = MCTSHex.MCTSHex(N, C_p, expansion_function=('constant', 1), random_seed="random", enh_WinScan=False, enh_FreqVisitor=False, enh_EnsureTopLevelExplr=False) terminator_rating = ts.Rating() mcts_rating = ts.Rating() average_time = [] for game in range(N_ROUNDS): if debug: print("Currently playing game number %d of %d" % (game + 1, N_ROUNDS)) time_array = np.zeros((MAX_TURNS, 1)) partial_move = partial(timeEvalMoveHook, AI_move_func=MCTS_AI.MCTS_move, timing_vector=time_array) if game % 2 == 0: mcts_color = HexBoard.BLUE terminator_color = HexBoard.RED blue_ai_move = partial_move red_ai_move = terminator_player_move else: mcts_color = HexBoard.RED terminator_color = HexBoard.BLUE blue_ai_move = terminator_player_move red_ai_move = partial_move board = HexBoard(BOARD_SIZE, n_players=0, enable_gui=False, interactive_text=False, ai_color=None, ai_move=None, blue_ai_move=blue_ai_move, red_ai_move=red_ai_move, move_list=[]) winning_color = board.get_winning_color() if winning_color == mcts_color: mcts_rating, terminator_rating = ts.rate_1vs1( mcts_rating, terminator_rating) elif winning_color == terminator_color: terminator_rating, mcts_rating = ts.rate_1vs1( terminator_rating, mcts_rating) if mcts_color == HexBoard.BLUE: time_array = time_array[0::2] else: time_array = time_array[1::2] if debug: print("Average time was %.3f seconds" % np.mean(time_array)) average_time.append(np.mean(time_array)) mcts_trueskill = mcts_rating.mu - 3 * mcts_rating.sigma terminator_trueskill = terminator_rating.mu - 3 * terminator_rating.sigma return mcts_trueskill - terminator_trueskill, np.mean(average_time)
if game % 2 == 0: mcts_color = HexBoard.BLUE terminator_color = HexBoard.RED blue_ai_move = MCTS_AI.MCTS_move red_ai_move = terminator_player_move else: mcts_color = HexBoard.RED terminator_color = HexBoard.BLUE blue_ai_move = terminator_player_move red_ai_move = MCTS_AI.MCTS_move board = HexBoard(BOARD_SIZE, n_players=0, enable_gui=False, interactive_text=False, ai_color=None, ai_move=None, blue_ai_move=blue_ai_move, red_ai_move=red_ai_move, move_list=[]) winning_color = board.get_winning_color() if winning_color == mcts_color: mcts_rating, terminator_rating = ts.rate_1vs1( mcts_rating, terminator_rating) elif winning_color == terminator_color: terminator_rating, mcts_rating = ts.rate_1vs1( terminator_rating, mcts_rating) rating_list.append(terminator_rating.mu)
interface by setting enable_gui to True.""" if __name__ == '__main__': board_size = 4 enable_gui = False if enable_gui: enable_text_interface = False else: enable_text_interface = True evaluator_function = TerminatorHex.random_score_heuristic # Random evaluator function ai = TerminatorHex.TerminatorHex(3, use_suggested_heuristic=False, heuristic_evaluator=evaluator_function, depth_weighting=0, random_seed=10, do_iterative_deepening=False, max_time=None, do_transposition=False) move_generator = ai.terminator_move # Move generator that uses alpha_beta search board = HexBoard(board_size, n_players=1, enable_gui=enable_gui, interactive_text=enable_text_interface, ai_move=move_generator, ai_color=HexBoard.RED, blue_ai_move=None, red_ai_move=None, move_list=[])
def alpha_beta(hex_board, depth, max_or_min, alpha, beta, evaluator, depth_weighting=0, transposition_table=None, TT_offset=0): """The minimax algorithm on the HexBoard with alpha-beta-pruning Args: hex_board (HexBoard): The current hex board. depth (int): maximum depth to search max_or_min (str): maximise or minimise the current color to play (hex_board.blue_to_move). Is either 'min' or 'max'. alpha, beta (int): initial alpha and beta bounds. Can be float('-inf') and float('inf') evaluator (function): evaluator function. Called with args hex_board, maximiser_color depth-weighting (float): add heuristic score weight to the current evaluation depth. This can be used to force immediate capitalisation on good moves transposition_table: use transposition table. Enter None to disable transposition table usage. TT_offset (int): level index offset in the transpostion table. This is necessary when using iterative deepening, i.e. when a shallower than TerminatorHex.max_depth search is performed Returns: int: maximised/minimised value according to the evaluator """ maximiser_color = [hex_board.BLUE, hex_board.RED][(max_or_min == 'max') ^ (hex_board.blue_to_move)] is_game_over = False if (hex_board.check_win(hex_board.BLUE) or hex_board.check_win(hex_board.RED)): is_game_over = True use_transposition = [False, True][transposition_table != None] if depth > 0: if use_transposition: moves = order_moves_TT(hex_board, max_or_min, transposition_table[depth + TT_offset]) else: moves = hex_board.get_free_positions() else: moves = None # don't need to compute this, save time # minimax with alpha-beta pruning: if (depth <= 0 or is_game_over or len(moves) == 0): # end state value = evaluator(hex_board, maximiser_color) + (depth_weighting * depth) if use_transposition: transposition_table[depth][board_as_hash_key(hex_board)] = value return (value, alpha, beta) elif (max_or_min == 'max'): # maximise value = float('-inf') for move in moves: deepened_board = HexBoard(hex_board.board_size, n_players=2, enable_gui=False, interactive_text=False, ai_move=None, blue_ai_move=None, red_ai_move=None, move_list=hex_board.move_list) deepened_board.set_position_auto(move) new_value, _, _ = alpha_beta(deepened_board, depth - 1, 'min', alpha, beta, evaluator, depth_weighting=depth_weighting, transposition_table=transposition_table, TT_offset=TT_offset) if new_value > value: value = new_value if use_transposition: transposition_table[depth + TT_offset][board_as_hash_key(hex_board)] = value alpha = [alpha, new_value][new_value > alpha] if alpha >= beta: # beta cutoff # print("beta", alpha, beta) break return (value, alpha, beta) elif (max_or_min == 'min'): # minimise value = float('inf') for move in moves: deepened_board = HexBoard(hex_board.board_size, n_players=2, enable_gui=False, interactive_text=False, ai_move=None, blue_ai_move=None, red_ai_move=None, move_list=hex_board.move_list) deepened_board.set_position_auto(move) new_value, _, _ = alpha_beta(deepened_board, depth - 1, 'max', alpha, beta, evaluator, depth_weighting=depth_weighting, transposition_table=transposition_table, TT_offset=TT_offset) if new_value < value: value = new_value if use_transposition: transposition_table[depth + TT_offset][board_as_hash_key(hex_board)] = value beta = [beta, new_value][new_value < beta] if alpha >= beta: # alpha cutoff # print("alpha", alpha, beta) break return (value, alpha, beta) print("@alpha_beta: unknown max_or_min objective", max_or_min) return None
import random import torch if __name__ == "__main__": board_size = config.BOARD_SIZE exploration_bonus = config.EXPLORATION_BONUS num_simulations = config.NUM_SIMULATIONS num_episodes = config.NUM_EPISODES save_every = config.SAVE_EVERY folder_results = config.FOLDER_RESULTS lr = config.LEARNING_RATE utils.create_directory(folder_results) time_start = time.time() board = HexBoard(board_size) mapper = Mapper(board_size=board_size) state_manager = StateManager(board, mapper, verbose=config.VISUALIZE_MOVES) #anet_nn = ANET_NN_COMPLEX(input_size=board_size*board_size, output_size = board_size*board_size).float() anet_nn = ANET_NN_GENERAL(input_size=board_size * board_size, output_size=board_size * board_size, hidden_layers=config.HIDDEN_LAYERS, activation=config.ACTIVATION).float() anet = ANET_MODEL(anet_nn, max_cases_in_buffer=config.REPLAY_BUFFER_MAX_SIZE) optimizer = config.OPTIMIZERS[config.OPTIMIZER](anet_nn.parameters(), lr=lr) for episode in range(num_episodes):
class Game: def __init__(self, m, n, mode): # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) # save size and mode self.size = [m, n] self.mode = mode # just to init the value self._currentPlayer = 1 # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) # set the game to entry point self.start(self._currentPlayer) if self.UIRequired(): # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.MachineGUI.gameLoop() def UIRequired(self): if self.mode == "human" or self.mode == "ki" or self.mode == "inter": return True else: return False def start(self, firstPlayer): EventManager.notify("GameStarting") # move counter init self.moveCounter = 0 # generate fresh state self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) # current player depending on decision self._currentPlayer = firstPlayer # if random number wanted, generate one if firstPlayer == 0: self.chooseFirst() EventManager.notify("GameStarted") def onGameStarted(self): if self.UIRequired(): # draw the gui self.HexGUI.draw() # Game finished event def onGameFinished(self): if self.UIRequired(): # move over to main menu and present the winner self.HexGUI.openPage("menu") self.HexGUI.won(self.HexBoard.winner()) # generate random player number def chooseFirst(self): self._currentPlayer = round(random.random()) + 1 # is the getter for the private variable def currentPlayer(self): return self._currentPlayer # alter the players def changePlayer(self): if self._currentPlayer == 1: self._currentPlayer = 2 else: self._currentPlayer = 1 # control flow for click event def makeMove(self, move): # Notify EventManager.notify("MoveBegan") # if already marked dont do anything if self.HexBoard.isMarked(move[1], move[0]): EventManager.notify("MoveDenied") else: # otherwise count the click self.moveCounter = self.moveCounter + 1 # notify Model self.HexBoard.receiveMove(move) # notify View self.changePlayer() EventManager.notify("PlayerChanged") EventManager.notify("MoveFinished")
def __init__(self, m, n, mode): self._pause = False # save size and mode self.size = [m, n] self.mode = mode # just to init the value self._currentPlayer = 1 self._currentPlayerType = "human" if mode == "copy": return # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) EventManager.subscribe("MoveFinished", self.onMoveFinished) EventManager.subscribe("GameUILoaded", self.onGameUILoaded) EventManager.subscribe("ToggleVictoryPath", self.onToggleVictoryPath) # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) self.GameState = 0 self.moveCounter = 0 if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) if self.mode == "ki": self.KI = HexKI(self.size[0], self.size[1]) if self.mode == "inter" or self.mode == "machine": self.KI = [] self.KI.append(HexKI(self.size[0], self.size[1])) self.KI.append(HexKI(self.size[0], self.size[1])) self._currentPlayerType = "ki" # set the game to entry point #self.start(self._currentPlayer) if self.UIRequired(): EventManager.subscribe("UITick", self.onUITick) # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.GameState = 1 self.MachineGUI.gameLoop()
class Game: def __init__(self, m, n, mode): self._pause = False # save size and mode self.size = [m, n] self.mode = mode # just to init the value self._currentPlayer = 1 self._currentPlayerType = "human" if mode == "copy": return # init all events EventManager.initEvents() EventManager.subscribe("GameFinished", self.onGameFinished) EventManager.subscribe("GameStarted", self.onGameStarted) EventManager.subscribe("MoveFinished", self.onMoveFinished) EventManager.subscribe("GameUILoaded", self.onGameUILoaded) EventManager.subscribe("ToggleVictoryPath", self.onToggleVictoryPath) # instantiate model and view self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) self.GameState = 0 self.moveCounter = 0 if self.UIRequired(): self.HexGUI = HexGUI(self.size[0], self.size[1], self) else: self.MachineGUI = MachineGUI(self.size[0], self.size[1], self) if self.mode == "ki": self.KI = HexKI(self.size[0], self.size[1]) if self.mode == "inter" or self.mode == "machine": self.KI = [] self.KI.append(HexKI(self.size[0], self.size[1])) self.KI.append(HexKI(self.size[0], self.size[1])) self._currentPlayerType = "ki" # set the game to entry point #self.start(self._currentPlayer) if self.UIRequired(): EventManager.subscribe("UITick", self.onUITick) # main loop starts for event receiving self.HexGUI.mainloop() if self.UIRequired() == False: self.GameState = 1 self.MachineGUI.gameLoop() def onUITick(self): self.doKIMove() def onToggleVictoryPath(self): if self.UIRequired(): vertices = self.HexBoard.getVictoryPath() self.HexGUI._GUIGameBoard.Pattern.toggleVictoryPath(vertices) def pause(self): self._pause = not self._pause def UIRequired(self): if self.mode == "human" or self.mode == "ki" or self.mode == "inter": return True else: return False def start(self, firstPlayer): self.GameState = 0 EventManager.notify("GameStarting") # move counter init self.moveCounter = 0 # generate fresh state self.HexBoard = HexBoard(self.size[0], self.size[1]) self.HexBoard.setReferenceToGame(self) # current player depending on decision self._currentPlayer = firstPlayer if self.mode == "ki": self.KI = MonteCarloTreeSearch(self, 2) # TODO: ki_player_id == 2? # self.KI = HexKI(self.size[0], self.size[1]) if self.mode == "inter" or self.mode == "machine": self.KI = [] self.KI.append(HexKI(self.size[0], self.size[1])) self.KI.append(HexKI(self.size[0], self.size[1])) self._currentPlayerType = "ki" # if random number wanted, generate one if firstPlayer == 0: self.chooseFirst() EventManager.notify("GameStarted") def onGameStarted(self): self.GameState = 1 if self.UIRequired(): # draw the gui self.HexGUI.draw() # Game finished event def onGameFinished(self): self.GameState = 0 if self.UIRequired(): # move over to main menu and present the winner self.HexGUI.openPage("menu") self.HexGUI.won(self.HexBoard.winner()) def onGameUILoaded(self): pass #if self.mode == "inter" or (self.mode == "ki" and self._currentPlayerType == "human"): # print("IM KI") # generate random player number def chooseFirst(self): self._currentPlayer = round(random.random()) + 1 # is the getter for the private variable def currentPlayer(self): return self._currentPlayer # is the current Player human? def isPlayerHuman(self): return self._currentPlayerType == "human" # alter the players def changePlayer(self): if self._currentPlayer == 1: self._currentPlayer = 2 else: self._currentPlayer = 1 if self.mode == "ki": if self._currentPlayerType == "human": self._currentPlayerType = "ki" else: self._currentPlayerType = "human" if self.mode in ["inter", "machine"]: self._currentPlayerType = "ki" # control flow for click event def makeMove(self, move): # Notify EventManager.notify("MoveBegan") # if already marked dont do anything if self.HexBoard.isMarked(move[0], move[1]): EventManager.notify("MoveDenied") assert False else: # otherwise count the click self.moveCounter = self.moveCounter + 1 # notify Model self.HexBoard.receiveMove(move) if self.mode == "inter": self.KI[0].receiveMove(move) self.KI[1].receiveMove(move) elif self.mode == "ki": self.KI.receiveMove(move) # notify View self.changePlayer() EventManager.notify("PlayerChanged") EventManager.notify("MoveFinished") def doKIMove(self): if self.GameState == 1: if not self.isPlayerHuman() and self.mode == "ki": move = self.KI.nextMove() self.makeMove(move) elif self.mode == "inter" or self.mode == "machine": move = self.KI[self.currentPlayer() - 1].nextMove() #print(move, self.currentPlayer()) #print("making", move) self.makeMove(move) def onMoveFinished(self): pass
import numpy as np import TerminatorHex from HexBoard import HexBoard """ Simple class to play a single player game against an AI using the GUI. """ if __name__ == '__main__': enable_GUI = True enable_interactive_text = True board_size = 5 n_players = 1 ai_color = HexBoard.BLUE terminator_AI = TerminatorHex.TerminatorHex(3, True) board = HexBoard(board_size, n_players=n_players, enable_gui=enable_GUI, interactive_text=enable_interactive_text, ai_move=terminator_AI.terminator_move, ai_color=ai_color, blue_ai_move=None, red_ai_move=None, move_list=[])
import math import MCTSHex from HexBoard import HexBoard if __name__ == '__main__': enable_GUI = True enable_interactive_text = True board_size = 6 n_players = 1 ai_color = HexBoard.RED MCTS_AI_1 = MCTSHex.MCTSHex(500, 10, expansion_function=('constant', 1), enh_WinScan=True, enh_EnsureTopLevelExplr=True) MCTS_AI_2 = MCTSHex.MCTSHex(500, 10, expansion_function=('constant', 0.5), enh_WinScan=True, enh_FreqVisitor=True) board = HexBoard(board_size, n_players=n_players, enable_gui=enable_GUI, interactive_text=enable_interactive_text, ai_move=MCTS_AI_1.MCTS_move, ai_color=ai_color, blue_ai_move=MCTS_AI_1.MCTS_move, red_ai_move=MCTS_AI_2.MCTS_move, move_list=[]) if not enable_GUI and not enable_interactive_text: # sanity check that wins are detected for i in range(0, 2): winner = HexBoard.RED if i == 0 else HexBoard.BLUE loser = HexBoard.BLUE if i == 0 else HexBoard.RED board = HexBoard(3) board.place_with_color((1, 1), loser) board.place_with_color((2, 1), loser) board.place_with_color((1, 2), loser) board.place_with_color((2, 2), loser) board.place_with_color((0, 0), winner) board.place_with_color((1, 0), winner)