Reputation: 143
In my tic tac toe game, after 4 turns, it declares X (the first player) to be the winner even if not. I don't know what im missing and it was working when just checking columns but now with rows it doesn't. I have a feeling it's a problem when I am calling the function with the letter but I'm not entirely sure.
moves = [["1", "2", "3"],
["1", "2", "3"],
["1", "2", "3"]]
def win(letter):
if(moves[0][0] == letter and
moves[1][0] == letter and
moves[2][0] == letter):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
elif(moves[0][1] == letter and
moves[1][1] == letter and
moves[2][1] == letter):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
elif(moves[0][2] == letter and
moves[1][2] == letter and
moves[2][2] == letter ):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
elif(moves[0][0] == letter and
moves[0][1] == letter and
moves[0][2]):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
elif(moves[1][0] == letter and
moves[1][1] == letter and
moves[1][2]):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
elif(moves[2][0] == letter and
moves[2][1] == letter and
moves[2][2]):
print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
quit()
def playerInput():
player1 = input("Where do you want to place your X, player 1? (row number, space, number)")
moves[int(player1[0]) - 1][int(player1[2]) - 1] = "X"
player2 = input("Where do you want to place your O, player 2? (row number, space, number)")
moves[int(player2[0]) - 1][int(player2[2]) - 1] = "O"
boardDraw()
def boardDraw():
print("1| "+moves[0][0]+" | "+moves[0][1]+" | "+moves[0][2]+" |")
print(" |---+---+---|")
print("2| "+moves[1][0]+" | "+moves[1][1]+" | "+moves[1][2]+" |")
print(" |---+---+---|")
print("3| "+moves[2][0]+" | "+moves[2][1]+" | "+moves[2][2]+" |")
win("X")
win("O")
playerInput()
print("OK SO....\nPlayer 1 is X\nPlayer 2 is O\nGOOOOO!!")
boardDraw()
Upvotes: 0
Views: 94
Reputation: 23508
You're clearly missing 2 winning cases:
moves[0][0] == moves[1][1] == moves[2][2]
and:
moves[0][2] == moves[1][1] == moves[2][0]
I'd rather rewrite your winning detection function as:
def win(letter) :
for i in range(3) : # rows
if set(moves[i]) == set([letter]) :
print( 'WIN' )
quit()
for x in zip(moves[0], moves[1], moves[2]) : # columns
if set(x) == set([letter]) :
print( 'WIN' )
quit()
# you have completely missed the part below...
if set(moves[i][i] for i in range(3)) == set([letter]) : # one diagonal
print( 'WIN' )
quit()
if set(moves[i][3-i] for i in range(3)) == set([letter]) : # another diagonal
print( 'WIN' )
quit()
or even more compact:
def win(letter) :
possible_wins = [ set(moves[i]) for i in rage(3) ] + # rows
[ set(x) for x in zip(moves[0], moves[1], moves[2]) ] + # columns
[ set(moves[i][i] for i in range(3)) ] + # diagonal
[ set(moves[i][3-i] for i in range(3)) ] # another diagonal
if any( p == set([letter]) for p in possible_wins ) :
print( 'WIN' )
quit()
Upvotes: 2
Reputation: 230
I'm assuming part of your problem has to do with the fact that in some of your if
cluases, you check the first two squares or equal to letter
, but not the third. Most objects in Python, except for things like None
or 0
will be evaluated to True
. So If there's a non-zero number in your array, or a character, it will be evaluated to True
. This causes the program to think the player won when a line of only two things are formed.
Also, you six specific win conditions, and there are definitely more than the ones you specified to win in Tic Tac Toe. I would suggest a more logical (and readable) approach of consolidating the win scenarios together. For example, you can check all the horizontal and vertical win conditions in one loop:
for i in range(3):
if ((moves[i][0] == moves[i][1] == moves[i][2] == letter) or
(moves[0][i] == moves[1][i] == moves[2][i] == letter):
# do win-condition stuff here
Finally, I would recommend checking for invalid moves, since your current code would just let the user over-write existing moves.
Upvotes: 2