I'm making a tic tac toe game and I need a way to check winning conditions. I made an
if statement
to check if X has 3 in a row, but for some reason I can't reach a winning condition. I can have this X| |X but when I try to fill in the blank it tells me that I can't do that.
tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
tiles_str = ("1", "2", "3", "4", "5", "6", "7", "8", "9")
global turn_count
turn_count = 0
def board():
divider = "-----"
play_board = str(tiles[0]) "|" str(tiles[1]) "|" str(tiles[2])
play_board_1 = str(tiles[3]) "|" str(tiles[4]) "|" str(tiles[5])
play_board_2 = str(tiles[6]) "|" str(tiles[7]) "|" str(tiles[8])
print(play_board)
print(divider)
print(play_board_1)
print(divider)
print(play_board_2)
while True:
def Turn_X():
board()
x_turn = input("X take your turn: ")
if x_turn in tiles_str:
x_turn = int(x_turn)
if x_turn in tiles:
if isinstance(tiles[x_turn], int):
global turn_count
turn_count = turn_count 1
tiles[x_turn -1] = "X"
if turn_count < 9:
Turn_O()
else:
print("Not an option")
Turn_X()
else:
print("Not an option")
Turn_X()
else:
print("Not an option")
Turn_X()
def Turn_O():
board()
o_turn = input("O take your turn: ")
if o_turn in tiles_str:
o_turn = int(o_turn)
if o_turn in tiles:
if isinstance(tiles[o_turn], int):
global turn_count
turn_count = turn_count 1
tiles[o_turn -1] = "O"
print(turn_count)
Turn_X()
else:
print("Not an option")
Turn_O()
else:
print("Not an option")
Turn_O()
else:
print("Not an option")
Turn_O()
if turn_count >= 9:
board()
print("\nDraw")
break
if tiles[0] == "X" and tiles[1] == "X" and tiles[2] == "X":
print("X wins")
break
Turn_X()
This is what I have for my game so far. I don't know if it's interfering with something else because I didn't have this issue before hand.
CodePudding user response:
x_turn = int(x_turn)
if x_turn in tiles:
if isinstance(tiles[x_turn], int):
Python lists are zero-indexed. If the player entered 3, you're checking tiles[3]
which is actually the fourth square.
CodePudding user response:
Your architecture has some issues. Don't define functions inside a while loop; prepare all your functions at the front, then USE them.
Don't use recursion for retrying an input. That's wasteful. Instead, use a while loop.
Note that the X and O functions are practically identical. Just use the same code and pass the letter.
Your code only checked for a top line. There's no reason to check X and O separately; just check whether the set of three are identical to each other.
This works:
def board():
divider = "-----"
play_board = f"{tiles[0]}|{tiles[1]}|{tiles[2]}"
play_board_1 = f"{tiles[3]}|{tiles[4]}|{tiles[5]}"
play_board_2 = f"{tiles[6]}|{tiles[7]}|{tiles[8]}"
print(play_board)
print(divider)
print(play_board_1)
print(divider)
print(play_board_2)
def Turn(xo):
board()
while True:
turn = input(xo " take your turn: ")
if not "1" <= turn <= "9":
print( "Not an option." )
continue
turn = int(turn)-1
if isinstance(tiles[turn], int):
tiles[turn] = xo
if turn_count < 9:
return
print("Not an option")
def checkdraw(tiles):
return not any(isinstance(i,int) for i in tiles)
def checkwin(tiles):
if tiles[0] == tiles[1] == tiles[2]:
return tiles[0]
if tiles[3] == tiles[4] == tiles[5]:
return tiles[3]
if tiles[6] == tiles[7] == tiles[8]:
return tiles[6]
if tiles[0] == tiles[3] == tiles[6]:
return tiles[0]
if tiles[1] == tiles[4] == tiles[7]:
return tiles[1]
if tiles[2] == tiles[5] == tiles[8]:
return tiles[2]
if tiles[0] == tiles[4] == tiles[8]:
return tiles[4]
if tiles[2] == tiles[4] == tiles[6]:
return tiles[4]
return False
tiles = [1, 2, 3, 4, 5, 6, 7, 8, 9]
turn_count = 0
while True:
Turn('X')
turn_count = turn_count 1
if checkdraw(tiles):
print("Draw")
board()
break
if checkwin(tiles):
print("X wins!")
board()
break
Turn('O')
turn_count = turn_count 1
if checkdraw(tiles):
print("Draw")
board()
break
if checkwin(tiles):
print("O wins!")
board()
break
One cute optimization:
def checkwin(tiles):
for l in (
(0,1,2),(3,4,5),(6,7,8),
(0,3,6),(1,4,7),(2,5,8),
(0,4,8),(2,4,6)
):
if tiles[l[0]] == tiles[l[1]] == tiles[l[2]]:
return tiles[l[0]]
return False
CodePudding user response:
Sorry but there is too much wrong to fix it without changing everything. You only check if x won when you have set all 9 fields. Check it before you call turn_o or turn_x.
Look for try: and except: and custom error class instead of the 3 if statements. You can print a break line with \n so you have one variable instead of 4 to print your field and you can do this for example: field = f"{str(tiles[0])}|" And you have much code duplication which you could fix when you use functions with parameters