I am a new programmer and i started learning python and wanted to learn to code a tic tac toe game.
The game goes on but the winning conditions and computer field selection do not work properly: it doesn't know when to stop playing and sometimes the computer selects an already selected field, thus overriding my choice (if i try to do the same, i get a ValueError).
For the win algorithm, i didn't want to go through all options by hand, so i used sets. I created a set with all winning conditions. While iterating on each subset (rows, cols and diagonals) i check if this is a subset of player/computer positions.
Problem is: it doesn't work. If i try to do anything i get a ValueError: list.remove(x) x not in list. I get this error sometimes on the line where the playerChoice gets removed, or the one from the computer. Another problem as stated above is that the computer can override my choice.
I think the problem lies on removing elements from one set and adding them to the other, but i can't find a way to get around this
Here is the code:
import random
board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
playerSymbol = ""
playerPosition = []
aiSymbol = ""
aiPosition = []
possiblePositions = [0, 1, 2, 3, 4, 5, 6, 7, 8]
turn = 0
def drawBoard():
print(board[0] + " | " + board[1] + " | " + board[2])
print("___" + "___" + "___")
print(board[3] + " | " + board[4] + " | " + board[5])
print("___" + "___" + "___")
print(board[6] + " | " + board[7] + " | " + board[8])
def choice():
global playerSymbol
global aiSymbol
answer = input("What do you want to play as? (type x or o) ")
if answer.upper() == "X":
playerSymbol = "X"
aiSymbol = "O"
else:
playerSymbol = "O"
aiSymbol = "X"
def won():
winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}]
for position in winningPositions:
if position.issubset(playerPosition):
print("Player Wins :)")
return True
elif position.issubset(aiPosition):
print("AI wins :(")
return True
else:
return False
def play():
global turn
choice()
while not won():
if turn % 2 == 0:
pos = int(input("Where would you like to play? (0-8) "))
possiblePositions.remove(pos)
playerPosition.append(pos)
board[pos] = playerSymbol
turn += 1
drawBoard()
else:
aiTurn = random.randint(0, len(possiblePositions) - 1)
possiblePositions.remove(possiblePositions[aiTurn])
aiPosition.append(aiTurn)
board[aiTurn] = aiSymbol
turn += 1
print("\n")
print("\n")
drawBoard()
else:
print("Thanks for playing :)")
play()
I am open to all sorts of suggestions and ways to improve my code. Thanks in advance and stay healthy, Kristi
Two things:
Change these lines:
aiTurn = random.randint(0, len(possiblePositions) - 1)
possiblePositions.remove(possiblePositions[aiTurn])
to
aiTurn = random.choice(possiblePositions)
possiblePositions.remove(aiTurn)
won()
, you need to iterate over every possible combination until a comparision eveluates to True
. However, you return either true or false after just the first comparision. Move the return False
outside the loop:Change
for position in winningPositions:
if position.issubset(playerPosition):
print("Player Wins :)")
return True
elif position.issubset(aiPosition):
print("AI wins :(")
return True
else:
return False
to
for position in winningPositions:
if position.issubset(playerPosition):
print("Player Wins :)")
return True
elif position.issubset(aiPosition):
print("AI wins :(")
return True
return False