✨ Hex is winable!
This commit is contained in:
@ -62,7 +62,8 @@ async def runHex(channel,command,user):
|
|||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
winner = data[str(channel.id)]["winner"]
|
winner = data[str(channel.id)]["winner"]
|
||||||
if winner != 0:
|
if winner != 0:
|
||||||
addMoney(data[str(channel.id)]["players"][winner-1].lower(),50)
|
winnings = data[str(channel.id)]["difficulty"]*10
|
||||||
|
addMoney(data[str(channel.id)]["players"][winner-1].lower(),winnings)
|
||||||
|
|
||||||
#deleteGame("hex games",str(channel.id))
|
#deleteGame("hex games",str(channel.id))
|
||||||
with open("resources/games/hexGames.json", "r") as f:
|
with open("resources/games/hexGames.json", "r") as f:
|
||||||
|
@ -6,15 +6,6 @@ import math
|
|||||||
from . import hexDraw
|
from . import hexDraw
|
||||||
from funcs import logThis, getName, getID
|
from funcs import logThis, getName, getID
|
||||||
|
|
||||||
# This is totally copied from the four in a row game. Just modified
|
|
||||||
|
|
||||||
AIScoresHex = {
|
|
||||||
"lol, dunno": 3,
|
|
||||||
"enemy win": -10000,
|
|
||||||
"win": 1000,
|
|
||||||
"avoid losing": 100
|
|
||||||
}
|
|
||||||
|
|
||||||
BOARDWIDTH = 11
|
BOARDWIDTH = 11
|
||||||
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
|
ALL_POSITIONS = [(i,j) for i in range(11) for j in range(11)]
|
||||||
ALL_SET = set(ALL_POSITIONS)
|
ALL_SET = set(ALL_POSITIONS)
|
||||||
@ -23,7 +14,6 @@ for position in ALL_POSITIONS:
|
|||||||
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
|
EMPTY_DIJKSTRA[position] = math.inf # an impossibly high number
|
||||||
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
|
HEX_DIRECTIONS = [(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0)]
|
||||||
|
|
||||||
|
|
||||||
# Parses command
|
# Parses command
|
||||||
def parseHex(command, channel, user):
|
def parseHex(command, channel, user):
|
||||||
commands = command.lower().split()
|
commands = command.lower().split()
|
||||||
@ -119,7 +109,6 @@ def hexStart(channel, user, opponent):
|
|||||||
# draw the board
|
# draw the board
|
||||||
hexDraw.drawBoard(channel)
|
hexDraw.drawBoard(channel)
|
||||||
|
|
||||||
|
|
||||||
gwendoTurn = True if players[0] == "Gwendolyn" else False
|
gwendoTurn = True if players[0] == "Gwendolyn" else False
|
||||||
showImage = True
|
showImage = True
|
||||||
return "Started Hex game against "+getName(opponent)+ diffText+". It's "+getName(players[0])+"'s turn", showImage, False, False, gwendoTurn
|
return "Started Hex game against "+getName(opponent)+ diffText+". It's "+getName(players[0])+"'s turn", showImage, False, False, gwendoTurn
|
||||||
@ -149,32 +138,23 @@ def placeHex(channel : str,position : str, user):
|
|||||||
data[channel]["turn"] = turn
|
data[channel]["turn"] = turn
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
# Checking for a win
|
# Checking for a win
|
||||||
logThis("Checking for win")
|
logThis("Checking for win")
|
||||||
won, winningPieces = isHexWon(data[channel]["board"])
|
score, winner = evaluateBoard(data[channel]["board"])
|
||||||
|
|
||||||
if won != 0:
|
|
||||||
gameWon = True
|
|
||||||
data[channel]["winner"] = won
|
|
||||||
data[channel]["winningPieces"] = winningPieces
|
|
||||||
|
|
||||||
|
|
||||||
message = data[channel]["players"][won-1]+" won!"
|
|
||||||
if data[channel]["players"][won-1] != "Gwendolyn":
|
|
||||||
winAmount = data[channel]["difficulty"]^2+5
|
|
||||||
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
|
||||||
else:"""
|
|
||||||
|
|
||||||
|
if winner == 0: # Continue with the game.
|
||||||
gameWon = False
|
gameWon = False
|
||||||
message = getName(data[channel]["players"][player-1])+" placed at "+position.upper()+". It's now "+getName(data[channel]["players"][turn-1])+"'s turn."
|
message = getName(data[channel]["players"][player-1])+" placed at "+position.upper()+". It's now "+getName(data[channel]["players"][turn-1])+"'s turn. The score is "+str(score)
|
||||||
|
|
||||||
|
else: # Congratulations!
|
||||||
|
gameWon = True
|
||||||
|
data[channel]["winner"] = winner
|
||||||
|
message = getName(data[channel]["players"][player-1])+" placed at "+position.upper()+" and won!"
|
||||||
|
if data[channel]["players"][winner-1] != "Gwendolyn":
|
||||||
|
winAmount = data[channel]["difficulty"]*10
|
||||||
|
message += " Adding "+str(winAmount)+" GwendoBucks to their account."
|
||||||
|
|
||||||
data[channel]["lastMove"] = (int(position[1])-1, ord(position[0])-97)
|
data[channel]["lastMove"] = (int(position[1])-1, ord(position[0])-97)
|
||||||
with open("resources/games/hexGames.json", "w") as f:
|
|
||||||
json.dump(data,f,indent=4)
|
|
||||||
|
|
||||||
# Is it now Gwendolyn's turn?
|
# Is it now Gwendolyn's turn?
|
||||||
gwendoTurn = False
|
gwendoTurn = False
|
||||||
@ -182,6 +162,10 @@ def placeHex(channel : str,position : str, user):
|
|||||||
logThis("It's Gwendolyn's turn")
|
logThis("It's Gwendolyn's turn")
|
||||||
gwendoTurn = True
|
gwendoTurn = True
|
||||||
|
|
||||||
|
# Save the data
|
||||||
|
with open("resources/games/hexGames.json", "w") as f:
|
||||||
|
json.dump(data,f,indent=4)
|
||||||
|
|
||||||
# Update the board
|
# Update the board
|
||||||
hexDraw.drawHexPlacement(channel,player,position)
|
hexDraw.drawHexPlacement(channel,player,position)
|
||||||
|
|
||||||
@ -312,7 +296,7 @@ def evaluateBoard(board):
|
|||||||
# Initialize the starting hexes. For the blue player, this is the leftmost column. For the red player, this is the tom row.
|
# 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]):
|
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.
|
# 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
|
Distance[start] = 1 if (board[start[0]][start[1]] == 0) else 0 if (board[start[0]][start[1]] == player) else math.inf
|
||||||
visited = set() # Also called sptSet, short for "shortest path tree Set"
|
visited = set() # Also called sptSet, short for "shortest path tree Set"
|
||||||
for _ in range(BOARDWIDTH**2): # We can at most check every 121 hexes
|
for _ in range(BOARDWIDTH**2): # We can at most check every 121 hexes
|
||||||
# Find the next un-visited hex, that has the lowest distance
|
# Find the next un-visited hex, that has the lowest distance
|
||||||
@ -326,17 +310,12 @@ def evaluateBoard(board):
|
|||||||
if v[0] in range(11) and v[1] in range(11) and v not in visited:
|
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)
|
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)
|
Distance[v] = min(Distance[v], new_dist)
|
||||||
|
|
||||||
# If at the goal, we've found the shortest distance
|
|
||||||
if v[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal
|
|
||||||
atGoal = True
|
|
||||||
break
|
|
||||||
if atGoal:
|
|
||||||
score[player] = Distance[v] # A player's score is the shortest distance to goal. Which equals the number of remaining moves they need to win if unblocked by the opponent.
|
|
||||||
break
|
|
||||||
# After a hex has been visited, this is noted
|
# After a hex has been visited, this is noted
|
||||||
visited.add(u)
|
visited.add(u)
|
||||||
logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u]))
|
#logThis("Distance from player {}'s start to {} is {}".format(player,u,Distance[u]))
|
||||||
|
if u[player-1] == 10: # if the right coordinate of v is 10, it means we're at the goal
|
||||||
|
score[player] = Distance[u] # A player's score is the shortest distance to goal. Which equals the number of remaining moves they need to win if unblocked by the opponent.
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
logThis("For some reason, no path to the goal was found. ")
|
logThis("For some reason, no path to the goal was found. ")
|
||||||
if score[player] == 0:
|
if score[player] == 0:
|
||||||
@ -346,7 +325,6 @@ def evaluateBoard(board):
|
|||||||
return score, winner
|
return score, winner
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def minimaxHex(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
|
def minimaxHex(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
|
||||||
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
# The depth is how many moves ahead the computer checks. This value is the difficulty.
|
||||||
if depth == 0 or 0 not in sum(board,[0]):
|
if depth == 0 or 0 not in sum(board,[0]):
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 80 KiB |
Reference in New Issue
Block a user