Pathfinding with Dijkstra

This commit is contained in:
jona605a
2020-08-08 13:23:11 +02:00
parent 73b0a21a48
commit 3b7769599a

View File

@@ -16,6 +16,12 @@ AIScoresHex = {
} }
BOARDWIDTH = 11 BOARDWIDTH = 11
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
ALL_SET = set(ALL_POSITIONS)
EMPTY_DIJKSTRA = {}
for position in ALL_POSITIONS:
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
# Parses command # Parses command
@@ -200,14 +206,48 @@ def placeOnHexBoard(board,player,position):
logThis("Cannot place on existing piece (error code 1532)") logThis("Cannot place on existing piece (error code 1532)")
return "Error. You must place on an empty space." return "Error. You must place on an empty space."
# Checks if someone has won the game and returns the winner
def isHexWon(board):
won = 0
winningPieces = []
# you know... code here def evaluateBoard(board):
score = {1:0, 2:0}
isWon = False
# 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]):
# An empty hex adds a of distance of 1. A hex of own color add distance 0. Opposite color adds infinite distance.
Distance[start] = 1 if (board[v[0]][v[1]] == 0) else 0 if (board[v[0]][v[1]] == player) else math.inf
visited = set() # Also called sptSet, short for "shortest path tree Set"
while len(ALL_SET.difference(visited)): # While there are any un-visited hexes
# Find the next un-visited hex, that has the lowest distance
remainingHexes = ALL_SET.difference(visited)
A = [Distance[k] for k in remainingHexes] # Find the distance to each un-visited hex
u = list(remainingHexes)[A.index(min(A))] # Chooses the one with the lowest distance
# Find neighbors of the hex u
for di in HEX_DIRECTIONS:
v = (u[0] + di[0] , u[1] + di[1]) # v is a neighbor of u
if v[0] in range(11) and v[1] in range(11) and v not in visited:
new_dist = Distance[u] + (1 if (board[v[0]][v[1]] == 0) else 0 if (board[v[0]][v[1]] == player) else math.inf)
Distance[v] = min(Distance[v], new_dist)
# If at the goal and the distance is still 0, we've won!
if new_dist == 0 and v[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal
isWon = True
break
if isWon:
score[player] = math.inf # Winner!
score[player%2 +1] = -math.inf # loser!
break
# After a hex has been visited, this is noted
visited.add(u)
logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u]))
# When all hexes on the board have been checked:
score = # the minimum distance of the row of the goal
return score, isWon
return won, winningPieces
# Plays as the AI # Plays as the AI
def hexAI(channel): def hexAI(channel):
@@ -257,33 +297,6 @@ def hexAI(channel):
placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1) placement = "abcdefghijk"[chosenMove[1]]+str(chosenMove[0]+1)
return placeHex(channel,placement, "Gwendolyn") return placeHex(channel,placement, "Gwendolyn")
# Calculates points for a board
def AICalcHexPoints(board,player):
score = 0
#otherPlayer = player%2+1
## Checks if anyone has won
#won = isHexWon(board)[0]
## Add points if AI wins
#if won == player:
# score += AIScoresHex["win"]
return score
#def evaluateWindow(window,player,otherPlayer):
# if window.count(player) == 4:
# return AIScoresHex["win"]
# elif window.count(player) == 3 and window.count(0) == 1:
# return AIScoresHex["three in a row"]
# elif window.count(player) == 2 and window.count(0) == 2:
# return AIScoresHex["two in a row"]
# elif window.count(otherPlayer) == 4:
# return AIScoresHex["enemy win"]
# else:
# return 0
def minimaxHex(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer): def minimaxHex(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
terminal = ((isHexWon(board)[0] != 0) or (0 not in board[0])) terminal = ((isHexWon(board)[0] != 0) or (0 not in board[0]))