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()
Asked By: Hirnz

||

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] == ....

Answered By: scatter

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)

Answered By: Mr. Techie
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.