1
\$\begingroup\$

I'm just getting started with Python and was hoping for some feedback on a simple Tic-Tac-Toe game I wrote. Specifically, is there a simpler way to check the win conditions for the game, and to break the loops at the end without repeating the code twice, and just generally how to shorten this to achieve a similar effect?

print("Player 1 is 'X' and Player 2 is 'O'.\nEnter a number (0-8) to choose a \
space on the board.\nTake turns entering values until someone wins.\n\n[0, 1, 2] \
\n[3, 4, 5]\n[6, 7, 8]")

class Player:
    def __init__(self,num,XO):
        self.num = num
        self.XO = XO

p1 = Player(1,'X') #odd
p2 = Player(2,'O') #even

plist = [p1,p2]

b = [['0','1','2'], ['3','4','5'], ['6','7','8']]
i = 0

while True:
    for plyr in plist:
        while True:
            try:
                p = int(input(f'Player {plyr.num}, enter a number: '))
                row = int(p/3)
                cel = p%3
                if b[row][cel] is not 'X' and b[row][cel] is not 'O':
                    b[row][cel] = plyr.XO
                    break
                else:
                    print(f"Space already taken by {b[row][cel]}")
            except ValueError:
                print("That's not a valid number. Try again and choose 0-8.")

        bf = f"{b[0]}\n{b[1]}\n{b[2]}"
        print(bf)

        i+=1
        def CheckWin(b):
            if b[0][0]==b[0][1]==b[0][2]==plyr.XO or b[0][0]==b[1][0]==b[2][0]==plyr.XO or \
            b[0][0]==b[1][1]==b[2][2]==plyr.XO or b[0][1]==b[1][1]==b[2][1]==plyr.XO or \
            b[1][0]==b[1][1]==b[1][2]==plyr.XO or b[2][0]==b[2][1]==b[2][2]==plyr.XO or \
            b[0][2]==b[1][2]==b[2][2]==plyr.XO:
                print(f"Player {plyr.num} ('{plyr.XO}') wins!")
                return 1
            else:
                pass

        win = CheckWin(b)
        if not win and i<9:
            pass
        elif not win and i==9:
            print('The match is a tie.')
            break
        else:
            break
    if not win and i<9:
        pass
    elif not win and i==9:
        break
    else:
        break
\$\endgroup\$
1
\$\begingroup\$

First off, I see no reason to define p1 and p2, then put them into the playerlist, it would be more concise to simply define them inside plist's definition.

eg.

plist = [Player(1,'X'), Player(2, 'O')]

As for the repetition of the if statements, you could set a global variable "gameOver" that gets set true upon a game ending event.

eg.

#Before loops
gameOver = False

...

    #In for loop
        if not win and i<9:
            pass
        elif not win and i==9:
            gameOver = True
            print('The match is a tie.')
            break
        else:
            gameOver = True
            break
    #In first while loop
    if gameOver:
        break
    else:
        pass

This last part is just personal opinion, but I feel like asking the user for row and column would be more intuitive than cell number.

Edit: I just realized you could just do while not gameOver, no need for the if else.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.