I'm trying to run a simple tic tac toe game script in python. I use a list to track in which cell of the table there is a "X", an "Y" or nothing. to set the value you have to input the coordinate of the cell you want to play in and if the coordinate doesn't exist or it is already occupied, you get an error message and the game ask you to input again. the problem is that whenever i input a number, i get the error message and the program stop. I can't spot the error, can anyone help me? the cose is the following:
class Tris:
def __init__(self, xo = True):
self.tabella = [0, 0, 0,
0, 0, 0,
0, 0, 0] # -this is the starting table
self.xo = xo # -to check if it is "x" turn or "o" turn
self.finito = False # -to check if the game is unfinished
# -just to print grafic style of the table: ignore that
def print_tabella(self):
giocatore = "X" if self.xo else "Y"
tabella_convertita = self.tabella
for n, i in enumerate(tabella_convertita):
if i == 0:
tabella_convertita[n] = " "
elif i == 1:
tabella_convertita[n] = "X"
else:
tabella_convertita[n] = "O"
t1 = "|".join(str(i) for i in tabella_convertita[0:3])
t2 = "|".join(str(i) for i in tabella_convertita[3:6])
t3 = "|".join(str(i) for i in tabella_convertita[6:9])
spazio_casella = "-+-+-"
testo_segnaposto = """use following numbers to set X/O:
0|1|2
-+-+-
3|4|5
-+-+-
6|7|8"""
turno_di = f"turn : {giocatore}"
tab_finale = t1 + "\n" + spazio_casella + "\n" + t2 + "\n" + spazio_casella + "\n" + t3 + "\n"+ testo_segnaposto +"\n" + turno_di
return tab_finale
def controlla(self, casella):
if casella.isalpha(): # check if the input is not numerical
return False
else:
if not 0 <= int(casella) <= 8: # the value must be between 0 and 8
return False
else:
return self.tabella[int(casella)] == 0 # the cell must not be containing another symbol
def is_winner(self): # check if there is a row, a column or a diagonal with the same symbol
lista_righe = [[self.tabella[0], self.tabella[1], self.tabella[2]], [self.tabella[3], self.tabella[4], self.tabella[5]],
[self.tabella[6], self.tabella[7], self.tabella[8]]]
lista_colonne = [[self.tabella[0], self.tabella[3], self.tabella[6]], [self.tabella[1], self.tabella[4], self.tabella[7]],
[self.tabella[2], self.tabella[5], self.tabella[8]]]
lista_diagonali = [[self.tabella[0], self.tabella[4], self.tabella[8]], [self.tabella[2], self.tabella[4], self.tabella[6]], ]
lista_vincite = [lista_colonne, lista_diagonali, lista_righe]
winner = False
for i in lista_vincite:
for liste in i:
if liste[0] == liste[1] and liste[1] == liste[2] and liste[0] != 0:
winner = True
break
return winner
def gioca(self):
while self.finito == False: # check if the game is finished
if self.is_winner(): # check if there is a winner
self.finito = True
break
print(self.print_tabella()) # print the table in grafic form
inp = input("choose a number to set X/O: ")
if not self.controlla(inp): # check if the input is in valid form
print("invalid number or cell already used") # or if the chosen cell is available
else:
self.xo = not self.xo # to track if it is X turn or O turn
if self.xo:
self.tabella[int(inp)] = 1
else:
self.tabella[int(inp)] = 2
gioco_tris = Tris()
gioco_tris.gioca()
The problem is that print_tabella
mutates tabella
. When you do:
tabella_convertita = self.tabella
... you are not creating a new list, but just a synonym for self.tabella
. So whatever you do to tabella_convertita
is happening to self.tabella
: the numeric content gets replaced with characters.
Instead do:
tabella_convertita = self.tabella[:]