Checking for winning pattern in TicTacToe (Python)
Question:
I don’t think I quite understand how to use or/and operators in Python. In my code i want to check if 3 of my 9 squares of my TicTacToe board have the same values, which would mean someone won the game. I’ve tried playing around with the types, meaning: I’ve checked if I maybe just couldn’t get it to work because a Sting "1" isn’t the same as an Integer 1 or so on. But that didn’t seem to be the case. If there is any other way to solve this I’d be very glad but I can’t think of one.
Thanks for the help 🙂
Code:
import random
#status of game
over = False
#Signs representing players
p1 = "X"
p2 = "O"
#prints the 2-dimensional Array "Board" in a more organized way (with column partitions)
def printboard():
print(Board[0][0], "|", Board[0][1], "|", Board[0][2], "|", Board[0][3], "|")
print(Board[1][0], "|", Board[1][1], "|", Board[1][2], "|", Board[1][3], "|")
print(Board[2][0], "|", Board[2][1], "|", Board[2][2], "|", Board[2][3], "|")
print(Board[3][0], "|", Board[3][1], "|", Board[3][2], "|", Board[3][3], "|")
Board = [["#", "1", "2", "3"], ["1", "_" , "_" , "_"], ["2", "_" , "_" , "_"], ["3", "_" , "_", "_"]]
#print current board
printboard()
print("")#empty line
print("Fill a row, column or diagonal of 3 first! X begins!")
print("")#empty line
#giving all the important "squares" easier to access variables (a,b,...,i)
a = Board[1][1]
b = Board[1][2]
c = Board[1][3]
d = Board[2][1]
e = Board[2][2]
f = Board[2][3]
g = Board[3][1]
h = Board[3][2]
i = Board[3][3]
while over == False:
#X's move:
move1c = input("what column would you like to occupy? 1/2/3: ")
move1r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
#print current board
Board[int(move1c)][int(move1r)] = "X"
printboard()
#should check first row of my 9 square board
if a == b == c == p1 or a == b == c ==p2:
over = True
print("game over!")
#O's move:
move2c = input("what column would you like to occupy? 1/2/3: ")
move2r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move2c)][int(move2r)] = "O"
#print current board
printboard()
Answers:
In Python, when you assign a variable to another one, the value of the old one is assigned to the new one. A copy is made. That means when you do this:
a = Board[1][1]
Board[1][1] = "X"
print(a)
It will actually print the old value of Board[1][1]
– the value it was when it was assigned to a
. To solve this problem, you’ll have to type out the whole Board[1][1] == Board[1][2] == ...
.
It is not behaving as expected because you are assigning a,b,c....
once. So they will store the initial value in them, i.e. all of the above variables will have one value _
and it will not be modified at anytime in your program.
There are few other problems with your code like:
- you are asking for column number but assigning using it as a row. So
Board[int(move1c)][int(move1r)] = "X"
and Board[int(move2c)][int(move2r)] = "O"
will cause problems.
- you need to check for game over every time the user inputs row and column. Hence the check needs be in
#O's move:
as well.
I have tried to correct them and following is the code for that, let me know if you didn’t understand any part of the code:
import random
import sys
#status of game
over = False
#Signs representing players
p1 = "X"
p2 = "O"
#checks for any horizontal matches
def check_horizontal_match():
return Board[1][1] == Board[1][2] == Board[1][3] != "_" or Board[2][1] == Board[2][2] == Board[2][3] != "_" or Board[3][1] == Board[3][2] == Board[3][3] != "_"
#checks for any vertical matches
def check_vertical_match():
return Board[1][1] == Board[2][1] == Board[3][1] != "_" or Board[1][2] == Board[2][2] == Board[3][2] != "_" or Board[1][3] == Board[2][3] == Board[3][3] != "_"
#checks for any diagonal matches
def check_diagonal_match():
return Board[1][1] == Board[2][2] == Board[3][3] != "_" or Board[1][3] == Board[2][2] == Board[3][1] != "_"
#prints the 2-dimensional Array "Board" in a more organized way (with column partitions)
def printboard():
print(Board[0][0], "|", Board[0][1], "|", Board[0][2], "|", Board[0][3], "|")
print(Board[1][0], "|", Board[1][1], "|", Board[1][2], "|", Board[1][3], "|")
print(Board[2][0], "|", Board[2][1], "|", Board[2][2], "|", Board[2][3], "|")
print(Board[3][0], "|", Board[3][1], "|", Board[3][2], "|", Board[3][3], "|")
Board = [["#", "1", "2", "3"], ["1", "_" , "_" , "_"], ["2", "_" , "_" , "_"], ["3", "_" , "_", "_"]]
#print current board
printboard()
print("")#empty line
print("Fill a row, column or diagonal of 3 first! X begins!")
print("")#empty line
while over == False:
#X's move:
move1c = input("what column would you like to occupy? 1/2/3: ")
move1r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move1r)][int(move1c)] = "X"
#print current board
printboard()
#check for any match
if check_horizontal_match() or check_vertical_match() or check_diagonal_match():
over = True
print("game over!")
sys.exit(1)
#O's move:
move2c = input("what column would you like to occupy? 1/2/3: ")
move2r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move2r)][int(move2c)] = "O"
#print current board
printboard()
#check for any match
if check_horizontal_match() or check_vertical_match() or check_diagonal_match():
over = True
print("game over!")
sys.exit(1)
I don’t think I quite understand how to use or/and operators in Python. In my code i want to check if 3 of my 9 squares of my TicTacToe board have the same values, which would mean someone won the game. I’ve tried playing around with the types, meaning: I’ve checked if I maybe just couldn’t get it to work because a Sting "1" isn’t the same as an Integer 1 or so on. But that didn’t seem to be the case. If there is any other way to solve this I’d be very glad but I can’t think of one.
Thanks for the help 🙂
Code:
import random
#status of game
over = False
#Signs representing players
p1 = "X"
p2 = "O"
#prints the 2-dimensional Array "Board" in a more organized way (with column partitions)
def printboard():
print(Board[0][0], "|", Board[0][1], "|", Board[0][2], "|", Board[0][3], "|")
print(Board[1][0], "|", Board[1][1], "|", Board[1][2], "|", Board[1][3], "|")
print(Board[2][0], "|", Board[2][1], "|", Board[2][2], "|", Board[2][3], "|")
print(Board[3][0], "|", Board[3][1], "|", Board[3][2], "|", Board[3][3], "|")
Board = [["#", "1", "2", "3"], ["1", "_" , "_" , "_"], ["2", "_" , "_" , "_"], ["3", "_" , "_", "_"]]
#print current board
printboard()
print("")#empty line
print("Fill a row, column or diagonal of 3 first! X begins!")
print("")#empty line
#giving all the important "squares" easier to access variables (a,b,...,i)
a = Board[1][1]
b = Board[1][2]
c = Board[1][3]
d = Board[2][1]
e = Board[2][2]
f = Board[2][3]
g = Board[3][1]
h = Board[3][2]
i = Board[3][3]
while over == False:
#X's move:
move1c = input("what column would you like to occupy? 1/2/3: ")
move1r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
#print current board
Board[int(move1c)][int(move1r)] = "X"
printboard()
#should check first row of my 9 square board
if a == b == c == p1 or a == b == c ==p2:
over = True
print("game over!")
#O's move:
move2c = input("what column would you like to occupy? 1/2/3: ")
move2r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move2c)][int(move2r)] = "O"
#print current board
printboard()
In Python, when you assign a variable to another one, the value of the old one is assigned to the new one. A copy is made. That means when you do this:
a = Board[1][1]
Board[1][1] = "X"
print(a)
It will actually print the old value of Board[1][1]
– the value it was when it was assigned to a
. To solve this problem, you’ll have to type out the whole Board[1][1] == Board[1][2] == ...
.
It is not behaving as expected because you are assigning a,b,c....
once. So they will store the initial value in them, i.e. all of the above variables will have one value _
and it will not be modified at anytime in your program.
There are few other problems with your code like:
- you are asking for column number but assigning using it as a row. So
Board[int(move1c)][int(move1r)] = "X"
andBoard[int(move2c)][int(move2r)] = "O"
will cause problems. - you need to check for game over every time the user inputs row and column. Hence the check needs be in
#O's move:
as well.
I have tried to correct them and following is the code for that, let me know if you didn’t understand any part of the code:
import random
import sys
#status of game
over = False
#Signs representing players
p1 = "X"
p2 = "O"
#checks for any horizontal matches
def check_horizontal_match():
return Board[1][1] == Board[1][2] == Board[1][3] != "_" or Board[2][1] == Board[2][2] == Board[2][3] != "_" or Board[3][1] == Board[3][2] == Board[3][3] != "_"
#checks for any vertical matches
def check_vertical_match():
return Board[1][1] == Board[2][1] == Board[3][1] != "_" or Board[1][2] == Board[2][2] == Board[3][2] != "_" or Board[1][3] == Board[2][3] == Board[3][3] != "_"
#checks for any diagonal matches
def check_diagonal_match():
return Board[1][1] == Board[2][2] == Board[3][3] != "_" or Board[1][3] == Board[2][2] == Board[3][1] != "_"
#prints the 2-dimensional Array "Board" in a more organized way (with column partitions)
def printboard():
print(Board[0][0], "|", Board[0][1], "|", Board[0][2], "|", Board[0][3], "|")
print(Board[1][0], "|", Board[1][1], "|", Board[1][2], "|", Board[1][3], "|")
print(Board[2][0], "|", Board[2][1], "|", Board[2][2], "|", Board[2][3], "|")
print(Board[3][0], "|", Board[3][1], "|", Board[3][2], "|", Board[3][3], "|")
Board = [["#", "1", "2", "3"], ["1", "_" , "_" , "_"], ["2", "_" , "_" , "_"], ["3", "_" , "_", "_"]]
#print current board
printboard()
print("")#empty line
print("Fill a row, column or diagonal of 3 first! X begins!")
print("")#empty line
while over == False:
#X's move:
move1c = input("what column would you like to occupy? 1/2/3: ")
move1r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move1r)][int(move1c)] = "X"
#print current board
printboard()
#check for any match
if check_horizontal_match() or check_vertical_match() or check_diagonal_match():
over = True
print("game over!")
sys.exit(1)
#O's move:
move2c = input("what column would you like to occupy? 1/2/3: ")
move2r = input("what row would you like to occupy? 1/2/3: ")
#empty line
print("")
Board[int(move2r)][int(move2c)] = "O"
#print current board
printboard()
#check for any match
if check_horizontal_match() or check_vertical_match() or check_diagonal_match():
over = True
print("game over!")
sys.exit(1)