Ich habe versucht, mein Verständnis von Python durch die Programmierung kleiner Spiele, wie Tic Tac Toe zu verbessern. Ich habe eine Kopie des Spiels von Grund auf neu erstellt, bin dann aber gegangen, um einen Weg zu finden, ein vernünftiges API für das Spiel zu erstellen. Ich habe mich für den Einsatz von minimax entschieden, um dieses Ziel zu erreichen. Ich habe ein Tutorial für den Algorithmus gefunden und versucht, es für das Spiel zu formen.Python - Minimax-Algorithmus für Tic Tac Toe Aktualisierung der Platine durch Füllen jedes leeren Raum mit dem gleichen Symbol
Allerdings, wenn der Code ausgeführt wird, auf der ai der erste Zug ist. Jeder leere Platz, der auf dem Spielfeld übrig ist, wird mit dem gleichen Symbol gefüllt, was einen Gewinn erzwingt und das Spiel unspielbar macht.
Da ich mit dem Algorithmus nicht vertraut und unerfahren war, nahm ich den Code von einem Youtube-Tutorial und editierte es, so dass es für das Spiel funktional war.
Hier ist der Code
import random
import time
import sys
from sys import maxsize
#converts numbers from the board to X O and "" for printing out the board
def numToSymbol(board):
visual = board
for i in range(0, 9):
if visual[i] == -1:
visual[i]= "X"
elif visual[i] == 1:
visual[i] = "O"
elif visual[i] == 0:
visual[i] = " "
return visual
def symbolToNum(visual):
board = visual
for i in range(0, 9):
if board[i] == "X":
board[i] = -1
elif board[i] == "O":
board[i] = 1
elif board[i] == " ":
board[i] = 0
return board
# prints the board, first coverting numbers throught numtoSymbol
def drawBoard():
visual = numToSymbol(board)
print(
"|"+ str(visual[0]) + "|" + str(visual[1]) + "|" + str(visual[2]) + "| \n"
"-------\n"
"|"+ str(visual[3]) + "|" + str(visual[4]) + "|" + str(visual[5]) + "| \n"
"-------\n"
"|"+ str(visual[6]) + "|" + str(visual[7]) + "|" + str(visual[8]) + "| \n"
"-------")
symbolToNum(visual)
# checks the possible options for 3 in a row and if any are all held by one side returns true
def checkWin(board, winConditions, ai):
if ai == True:
win = 3
if ai == False:
win = -3
for row in winConditions:
checkA = board[row[0]]
checkB = board[row[1]]
checkC = board[row[2]]
if checkA + checkB + checkC == int(win):
return True
return False
def checkDraw(board):
emptyTile = 9
for tile in board:
if tile != 0:
emptyTile -= 1
if emptyTile == 0:
completion(2)
def availableMoves(board, bonus):
availableSlots = []
for position in range(0,9):
if board[position] == 0:
availableSlots.append(position + bonus)
return availableSlots
def playerTurn(board, remainingTurns):
board = board
checkDraw(board)
visual =drawBoard()
print("pick one of the available slots \n")
availableSlots = availableMoves(board, 1)
print(availableSlots)
choice = int(input('Select a tile from those shown above:\n')) -1
while True:
if 0 <= choice <= 8:
if board[choice] == 0:
board[choice] = -1
break
else:
choice = int(input('Select a tile from those shown above which has not already been selected:\n')) -1
else:
choice = int(input('Select a tile from those shown above:\n')) -1
visual = drawBoard()
if checkWin(board, winConditions, False) == True:
completion(0)
else:
aiTurn(board, remainingTurns - 1)
class Node(object):
def __init__(self, remainingTurns, playerNum, board, value = 0):
self.depth = remainingTurns
self.playerNum = playerNum
self.board = board
self.value = value
self.moves = availableMoves(self.board, 0)
self.children = []
self.createChildren()
def availableMoves(self, board):
self.availableSlots = []
for position in range(0,9):
if board[position] == 0:
availableSlots.append(position)
return self.availableSlots
def winCheck(self, state, playerNum):
self.winConditions = [[0, 1, 2],[3, 4, 5],[6, 7, 8],[0, 3, 6],[1, 4, 7],[2, 5, 8],[0, 4, 8],[2, 4, 6]]
self.win = 3
for row in self.winConditions:
self.checkA = self.state[row[0]]
self.checkB = self.state[row[1]]
self.checkC = self.state[row[2]]
if self.checkA + self.checkB + self.checkC == int(self.win * self.playerNum):
return True
return False
def createChildren(self):
if self.depth > 0:
for i in self.moves:
self.state = self.board
self.state[i] = self.playerNum
print(board)
self.children.append(Node(self.depth - 1, self.playerNum * -1, self.state, self.realVal(self.state, self.playerNum)))
def realVal(self, value, playerNum):
value = self.winCheck(self.state, self.playerNum)
if value == True:
return maxsize * self.playerNum
else:
return 0
def minimax(node, depth, playerNum):
if depth == 0 or abs(node.value) == maxsize:
return node.value
bestValue = maxsize * -playerNum
for i in range(len(node.children)):
child = node.children[i]
val = minimax(child, depth - 1, -playerNum)
if (abs(maxsize * playerNum - val) < abs(maxsize * playerNum - bestValue)):
bestValue = val
return bestValue
def aiTurn(board, remainingTurns):
checkDraw(board)
print('Waiting for ai')
time.sleep(2)
board = board
state = board
currentPlayer = 1
tree = Node(remainingTurns, currentPlayer, state)
bestChoice = -100
bestValue = maxsize * -1
for i in range(len(tree.children)):
n_child = tree.children[i]
i_val = minimax(n_child, remainingTurns, -currentPlayer,)
if (abs(currentPlayer * maxsize - i_val) <= abs(currentPlayer * maxsize - bestValue)):
bestValue = i_val
bestChoice = i
print(bestChoice)
print(board)
#choice = minimax(tree, remainingTurns, 1)
board[bestChoice] = 1
print(board)
if checkWin(board, winConditions, True) == True:
completion(1)
else:
playerTurn(board, remainingTurns - 1)
def completion(state):
if state == 1:
print('The computer has won this game.')
choice = str(input('press y if you would like to play another game; Press n if you would not \n'))
if choice == 'y' or choice == 'Y':
playGame()
else:
sys.exit()
if state == 0:
print('you win!')
choice = str(input('press y if you would like to play another game; Press n if you would not \n'))
if choice == 'y' or choice == 'Y':
playGame()
else:
sys.exit()
if state == 2:
print('you drew')
choice = str(input('press y if you would like to play another game; Press n if you would not \n'))
if choice == 'y' or choice == 'Y':
playGame()
else:
sys.exit()
def playGame():
global board
board = [0,0,0,0,0,0,0,0,0]
global winConditions
winConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]
global remainingTurns
remainingTurns = 9
playerFirst = random.choice([True, False])
if playerFirst == True:
playerTurn(board, remainingTurns)
else:
aiTurn(board, remainingTurns)
if __name__ == '__main__':
playGame()
Dies ist die Ausgabe des obigen Code ist
[1, 0, 0, 0, 0, 0, 0, 0, 0]
[1, -1, 0, 0, 0, 0, 0, 0, 0]
[1, -1, 1, 0, 0, 0, 0, 0, 0]
[1, -1, 1, -1, 0, 0, 0, 0, 0]
[1, -1, 1, -1, 1, 0, 0, 0, 0]
[1, -1, 1, -1, 1, -1, 0, 0, 0]
[1, -1, 1, -1, 1, -1, 1, 0, 0]
[1, -1, 1, -1, 1, -1, 1, -1, 0]
[1, -1, 1, -1, 1, -1, 1, -1, 1]
[1, -1, 1, -1, 1, -1, 1, -1, -1]
[1, -1, 1, -1, 1, -1, 1, 1, -1]
[1, -1, 1, -1, 1, -1, 1, 1, 1]
[1, -1, 1, -1, 1, -1, -1, 1, 1]
[1, -1, 1, -1, 1, -1, -1, -1, 1]
[1, -1, 1, -1, 1, -1, -1, -1, -1
[1, -1, 1, -1, 1, 1, -1, -1, -1]
[1, -1, 1, -1, 1, 1, 1, -1, -1]
[1, -1, 1, -1, 1, 1, 1, 1, -1]
[1, -1, 1, -1, 1, 1, 1, 1, 1]
[1, -1, 1, -1, -1, 1, 1, 1, 1]
[1, -1, 1, -1, -1, -1, 1, 1, 1]
[1, -1, 1, -1, -1, -1, -1, 1, 1]
[1, -1, 1, -1, -1, -1, -1, -1, 1
[1, -1, 1, -1, -1, -1, -1, -1, -
[1, -1, 1, 1, -1, -1, -1, -1, -1
[1, -1, 1, 1, 1, -1, -1, -1, -1]
[1, -1, 1, 1, 1, 1, -1, -1, -1]
[1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, -1, 1, 1, 1, 1, 1, 1, -1]
[1, -1, 1, 1, 1, 1, 1, 1, 1]
[1, -1, -1, 1, 1, 1, 1, 1, 1]
[1, -1, -1, -1, 1, 1, 1, 1, 1]
[1, -1, -1, -1, -1, 1, 1, 1, 1]
[1, -1, -1, -1, -1, -1, 1, 1, 1]
[1, -1, -1, -1, -1, -1, -1, 1, 1
[1, -1, -1, -1, -1, -1, -1, -1,
[1, -1, -1, -1, -1, -1, -1, -1,
[1, 1, -1, -1, -1, -1, -1, -1, -
[1, 1, 1, -1, -1, -1, -1, -1, -1
[1, 1, 1, 1, -1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1]
8
[1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1]
The computer has won this game.
Irgendwelche Vorschläge?