This commit is contained in:
Nikolaj Danger
2020-08-12 13:45:05 +02:00
parent e9e08ef0d6
commit 25da2cc3eb
2 changed files with 16 additions and 20 deletions

View File

@ -2,6 +2,7 @@ import json
import random
import copy
import math
import asyncio
from . import fourInARowDraw
from funcs import logThis, getName, getID
@ -13,7 +14,7 @@ AIScores = {
"enemy two in a row": -35,
"enemy three in a row": -200,
"enemy win": -10000,
"win": 1000,
"win": 10000,
"avoid losing": 100
}
@ -232,7 +233,7 @@ def isWon(board):
return won, winDirection, winCoordinates
# Plays as the AI
def fourInARowAI(channel):
async def fourInARowAI(channel):
logThis("Figuring out best move")
with open("resources/games/games.json", "r") as f:
data = json.load(f)
@ -246,7 +247,7 @@ def fourInARowAI(channel):
testBoard = copy.deepcopy(board)
testBoard = placeOnBoard(testBoard,player,column)
if testBoard != None:
scores[column] = minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
scores[column] = await minimax(testBoard,difficulty,player%2+1,player,-math.inf,math.inf,False)
logThis("Best score for column "+str(column)+" is "+str(scores[column]))
possibleScores = scores.copy()
@ -266,12 +267,10 @@ def AICalcPoints(board,player):
otherPlayer = player%2+1
# Adds points for middle placement
for row in range(len(board)):
if board[row][3] == player:
score += AIScores["middle"]
# Checks horizontal
for row in range(rowCount):
if board[row][3] == player:
score += AIScores["middle"]
rowArray = [int(i) for i in list(board[row])]
for place in range(columnCount-3):
window = rowArray[place:place+4]
@ -290,8 +289,6 @@ def AICalcPoints(board,player):
window = [board[row][place],board[row+1][place+1],board[row+2][place+2],board[row+3][place+3]]
score += evaluateWindow(window,player,otherPlayer)
# Checks left diagonal
for row in range(rowCount-3):
for place in range(3,columnCount):
window = [board[row][place],board[row+1][place-1],board[row+2][place-2],board[row+3][place-3]]
score += evaluateWindow(window,player,otherPlayer)
@ -319,11 +316,12 @@ def evaluateWindow(window,player,otherPlayer):
else:
return 0
def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
terminal = ((isWon(board)[0] != 0) or (0 not in board[0]))
async def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer):
#terminal = ((0 not in board[0]) or (isWon(board)[0] != 0))
terminal = 0 not in board[0]
points = AICalcPoints(board,originalPlayer)
# The depth is how many moves ahead the computer checks. This value is the difficulty.
if depth == 0 or terminal:
points = AICalcPoints(board,originalPlayer)
if depth == 0 or terminal or (points > 5000 or points < -6000):
return points
if maximizingPlayer:
value = -math.inf
@ -331,12 +329,11 @@ def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer
testBoard = copy.deepcopy(board)
testBoard = placeOnBoard(testBoard,player,column)
if testBoard != None:
evaluation = minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,False)
if evaluation < -9000: evaluation += AIScores["avoid losing"]
value = max(value,evaluation)
alpha = max(alpha,evaluation)
if beta <= alpha:
break
if beta <= alpha: break
return value
else:
value = math.inf
@ -344,10 +341,9 @@ def minimax(board, depth, player , originalPlayer, alpha, beta, maximizingPlayer
testBoard = copy.deepcopy(board)
testBoard = placeOnBoard(testBoard,player,column)
if testBoard != None:
evaluation = minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
evaluation = await minimax(testBoard,depth-1,player%2+1,originalPlayer,alpha,beta,True)
if evaluation < -9000: evaluation += AIScores["avoid losing"]
value = min(value,evaluation)
beta = min(beta,evaluation)
if beta <= alpha:
break
if beta <= alpha: break
return value

View File

@ -94,7 +94,7 @@ async def fiar(channel,command,user):
if gameDone == False:
if gwendoTurn:
try:
response, showImage, deleteImage, gameDone, gwendoTurn = fourInARowAI(str(channel.id))
response, showImage, deleteImage, gameDone, gwendoTurn = await fourInARowAI(str(channel.id))
except:
logThis("AI error (error code 1420)")
await channel.send(response)