From 3ccb1587f31aee53fb93f88b40456cfaabf808e2 Mon Sep 17 00:00:00 2001 From: jona605a Date: Mon, 10 Aug 2020 01:41:09 +0200 Subject: [PATCH] :bug: --- funcs/games/hex.py | 39 +++++++++++---------------------------- funcs/games/hexDraw.py | 2 +- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/funcs/games/hex.py b/funcs/games/hex.py index 97357bc..bbeeac4 100644 --- a/funcs/games/hex.py +++ b/funcs/games/hex.py @@ -247,43 +247,25 @@ def hexAI(channel): board = data[channel]["board"] difficulty = data[channel]["difficulty"] - """ - if len(data[channel]["gameHistory"]): - lastMove = data[channel]["gameHistory"][-1] - else: - lastMove = (5,5) - - # These moves are the last move +- 2. - moves = [[(lastMove[0]+j-2,lastMove[1]+i-2) for i in range(5) if lastMove[1]+i-2 in range(11)] for j in range(5) if lastMove[0]+j-2 in range(11)] - moves = sum(moves,[]) - chosenMove = None - safety = 0 - while chosenMove == None: - safety += 1 - if safety > 1000: - break - candidate = random.choice(moves) - if board[candidate[0]][candidate[1]] == 0: - chosenMove = candidate - logThis("Last move was "+str(lastMove)) - logThis("Chosen move is "+str(chosenMove)) """ - possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0] judgements = [-math.inf]*len(possiblePlaces) # All possible moves are yet to be judged - + GwenColor = data[channel]["players"].index("Gwendolyn") + 1 # either 1 or 2 - red or blue + + current_score = evaluateBoard(board)[0] for i in possiblePlaces: testBoard = copy.deepcopy(board) testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 - # Testing a move and evaluating it - judgements[i] = minimaxHex(testBoard,difficulty,-math.inf,math.inf,False) - logThis("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i])) + if evaluateBoard(testBoard)[0] != current_score: # only think about a move if it improves the score (it's impossible to get worse) + # Testing a move and evaluating it + judgements[i] = minimaxHex(testBoard,difficulty,-math.inf,math.inf,GwenColor==2) + logThis("Best score for place {} is {}".format((i // BOARDWIDTH,i % BOARDWIDTH),judgements[i])) - GwenColor = data[channel]["players"].index("Gwendolyn") + 1 bestScore = max(judgements) if (GwenColor == 1) else min(judgements) indices = [i for i, x in enumerate(judgements) if x == bestScore] # which moves got that score? i = random.choice(indices) chosenMove = (i // BOARDWIDTH , i % BOARDWIDTH) placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1) + logThis("ChosenMove is {} at {}".format(chosenMove,placement)) return placeHex(channel,placement, "Gwendolyn") @@ -292,7 +274,6 @@ def evaluateBoard(board): winner = 0 # Here, I use Dijkstra's algorithm to evaluate the board, as proposed by this article: https://towardsdatascience.com/hex-creating-intelligent-adversaries-part-2-heuristics-dijkstras-algorithm-597e4dcacf93 for player in [1,2]: - logThis("Running Dijkstra for player "+str(player)) Distance = copy.deepcopy(EMPTY_DIJKSTRA) # Initialize the starting hexes. For the blue player, this is the leftmost column. For the red player, this is the tom row. for start in (ALL_POSITIONS[::11] if player == 2 else ALL_POSITIONS[:11]): @@ -329,12 +310,13 @@ def evaluateBoard(board): def minimaxHex(board, depth, alpha, beta, maximizingPlayer): # The depth is how many moves ahead the computer checks. This value is the difficulty. if depth == 0 or 0 not in sum(board,[]): - score = evaluateBoard(board) + score = evaluateBoard(board)[0] return score # if final depth is not reached, look another move ahead: if maximizingPlayer: # red player predicts next move maxEval = -math.inf possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0] + #logThis("Judging a red move at depth {}".format(depth)) for i in possiblePlaces: testBoard = copy.deepcopy(board) testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 1 # because maximizingPlayer is Red which is number 1 @@ -347,6 +329,7 @@ def minimaxHex(board, depth, alpha, beta, maximizingPlayer): else: # blue player predicts next move minEval = math.inf possiblePlaces = [i for i,v in enumerate(sum(board,[])) if v == 0] + #logThis("Judging a blue move at depth {}".format(depth)) for i in possiblePlaces: testBoard = copy.deepcopy(board) testBoard[i // BOARDWIDTH][i % BOARDWIDTH] = 2 # because minimizingPlayer is Blue which is number 2 diff --git a/funcs/games/hexDraw.py b/funcs/games/hexDraw.py index d765872..36772de 100644 --- a/funcs/games/hexDraw.py +++ b/funcs/games/hexDraw.py @@ -121,7 +121,7 @@ def drawBoard(channel): def drawHexPlacement(channel,player,position): FILEPATH = "resources/games/hexBoards/board"+channel+".png" - logThis("Drawing a newly placed hex. Filepath:"+FILEPATH) + logThis("Drawing a newly placed hex. Filepath: "+FILEPATH) # Translates position # We don't need to error-check, because the position is already checked in placeOnHexBoard()