Reputation: 13
I have made a Tic Tac Toe game in python and when X wins it shoes that O has won and when O wins it shows that X has won. I am pretty sure that the problem is that it changes player and after that checks if someone has won, I tried making it so it will switch be before the player switch but it still didn't work. I also tried to change player in the is_win function but that also didn't fix it. Could someone please take a look at this and help me fix this.
initial_board = [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board = initial_board
def empty_board(): #use board = empty_board() everytime you want to empty the board
board = [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
return(board)
def switch_turn(player): #use player = switch_turn(player) everytime you want to switch players
if player == 'X':
return 'O'
return 'X'
def print_board(board):
print(*board, sep = "\n")
def is_full(board):
return all('_' not in box for box in board)
def is_valid(board, row, col):
x = board[row]
if x[col] == '_':
return True
return False
def set_cell(board, row, col, player):
x = board[row]
if is_valid(board,row,col) is True:
x[col] = player
print_board(board)
else:
print("already taken")
def get_user_input():
while True:
while True:
row = int(input("Enter the row you want (0-2): "))
if row > 2 or row < 0:
print("The number you entered is not valid")
continue
break
while True:
col = int(input("Enter the column you want (0-2): "))
if col > 2 or col < 0:
print("The number you entered is not valid")
continue
break
if is_valid(board,row,col) is True:
return row,col
else:
print("This place is taken")
continue
def is_win(board,player):
row1 = board[0]
row2 = board[1]
row3 = board[2]
if row1[0] == row1[1] == row1[2] != '_':
print(player + " Has won!")
return True
elif row2[0] == row2[1] == row2[2] != '_':
print(player + " Has won!")
return True
elif row3[0] == row3[1] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[0] == row2[0] == row3[0] != '_':
print(player + " Has won!")
return True
elif row1[1] == row2[1] == row3[1] != '_':
print(player + " Has won!")
return True
elif row1[2] == row2[2] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[0] == row2[1] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[2] == row2[1] == row3[0] != '_':
print(player + " Has won!")
return True
else:
return False
def game():
player = 'X'
print_board(board)
while is_win(board, player) is False:
if is_full(board) is True and is_win(board, player) is False:
print("draw")
break
elif is_full(board) is True and is_win(board, player) is True:
print(is_win(board, player))
break
row, col = get_user_input()
set_cell(board, row, col, player)
player = switch_turn(player)
game()
Upvotes: 0
Views: 309
Reputation: 1856
Without re-writing too much of your code I would just re-arrange the code a bit. You don't have to check if it is win or draw at start of the loop since it will never be True at start of a game. This means you can ask for input, set the cell, and only then check for win/draw. This makes you write out the winner before you switch turns.
You also don't want to print anything in the is_win function. Since that is your while loop criteria it will run the function after the code is executed and make it run with the wrong player. Solve this by not printing in the is_win function, just print when the if statement is fulfilled.
Another problem is that in your elif (win) statement you check if board is_full AND is_win. This will only happen if you win on the last spot.
You don't really have to write out "is False" or "is True" either. I think it is easier to read if you remove them and use the word not for False instead.
Rough code for the game loop:
def game():
player = 'X'
print_board(board)
while not is_win(board, player):
row, col = get_user_input()
set_cell(board, row, col, player)
if is_full(board) and not is_win(board, player):
print("draw")
break
elif is_win(board, player):
print(player + " has won!")
break
player = switch_turn(player)
Upvotes: 0
Reputation: 128
I think it is because, before your game ends, the player gets switched at the of the game() function.
player = switch_turn(player)
When X makes its winning move, the player gets switched and the current player is now player 'O'. One idea could be checking is_win before the switch.
Upvotes: 1