Brandon Li
Brandon Li

Reputation: 181

Tic-tac-toe game logic problems

[Edited] To make things simple, I am going to include the whole file here:

choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
Is_Current_One = True
won = False
wrongEntryPlayer1 = False
wrongEntryPlayer2 = False
while not won:
    if not wrongEntryPlayer1 and not wrongEntryPlayer2:
        print('\n')
        print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|')
        print('----------')
        print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|')
        print('----------')
        print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|')
    # above code is to print board layouts
    if Is_Current_One:
        print("Player 1's turn.\nChoose a number to put an X there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer1 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer1 = True
            continue
    else:
        print("Player 2's turn.\nChoose a number to put an O there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer2 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer2 = True
            continue

    if Is_Current_One:
        if choices[choice - 1] == int:
            try:
                choices[choice - 1] = 'X'
                wrongEntryPlayer1 = False
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer1 = True
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer1 = True
    else:
        if choices[choice - 1] == int:
            try:
                choices[choice - 1] = 'O'
                wrongEntryPlayer2 = False
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer2 = True
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer2 = True
    # code to toggle between True and False
    Is_Current_One = not Is_Current_One

    for pos_x in range(0, 3):
        pos_y = pos_x * 3

        # for row condition:
        if (choices[pos_y] == choices[(pos_y + 1)]) and (
                choices[pos_y] == choices[(pos_y + 2)]):
            won = True

        # column condition:
        if (choices[pos_x] == choices[(pos_x + 3)]) and (
                choices[pos_x] == choices[(pos_x + 6)]):
            won = True
    if ((choices[0] == choices[4] and choices[0] == choices[8])
            or (choices[2] == choices[4] and choices[4] == choices[6])):
        won = True

print("Player " + str(int(Is_Current_One + 1)) + " won, Congratulations!")

If you really read the code, you will see that I am making a tic-tac-toe game. I have declared two boolean variables: wrongEntryPlayer1 and wrongEntryPlayer2 which are default set to False at first, as the game had just started. When playing this game, players need to enter an integer, which is indicated in the game board, to put an X or O there. If players did not enter an integer, the program will crash, and I don't want that. Instead, I used the try statement and print a user-friendly message when they did not enter an integer. When this happens, I do not want Python to print the game board all over again, so when the player entered a wrong value, I set the respective wrongEntryPlayer variable to True. That way, if either player entered a wrong value, I will totally skip printing the game board.

However, when I tried to run it and entered a wrong value on the first turn, and then entered the correct value, the game board would still not show up. Even when it is player 2's turn, the game board is still not printed.

When the player enter the correct value(an integer), the game board still does not show up.

Also, when the player enters the value which is already occupied by another player, the program should prompt the player to enter again. Instead, it just skips the player's turn.

I am a python beginner, so some of the code may seem silly. Can anyone help me and explain to me how to fix this please? Thanks! Thanks to Sanetro, my original problem was fixed. Now a whole other error occurred. Detailed question is posted in comment section of Sanetro's answer. I am here to include my detailed edited code.

choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
Is_Current_One = True
won = False
wrongEntryPlayer1 = False
wrongEntryPlayer2 = False
while not won:
    if not wrongEntryPlayer1 and not wrongEntryPlayer2:
        print('\n')
        print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|')
        print('----------')
        print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|')
        print('----------')
        print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|')
    # above code is to print board layouts
    if Is_Current_One:
        print("Player 1's turn.\nChoose a number to put an X there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer1 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer1 = True
            continue
        except IndexError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer1 = True
            continue
    else:
        print("Player 2's turn.\nChoose a number to put an O there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer2 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer2 = True
            continue
        except IndexError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer2 = True
            continue
    if Is_Current_One:
        if choices[choice - 1].isnumeric():
            try:
                choices[choice - 1] = 'X'
                wrongEntryPlayer1 = False
            except ValueError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer1 = True
                continue
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer1 = True
                continue
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer1 = True
    else:
        if choices[choice - 1].isnumeric():
            try:
                choices[choice - 1] = 'O'
                wrongEntryPlayer2 = False
            except ValueError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer2 = True
                continue
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer2 = True
                continue
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer2 = True

    # code to toggle between True and False
    if wrongEntryPlayer1 == False and wrongEntryPlayer2 == False:
        Is_Current_One = not Is_Current_One

    for pos_x in range(0, 3):
        pos_y = pos_x * 3

        # for row condition:
        if (choices[pos_y] == choices[(pos_y + 1)]) and (
                choices[pos_y] == choices[(pos_y + 2)]):
            won = True

        # column condition:
        if (choices[pos_x] == choices[(pos_x + 3)]) and (
                choices[pos_x] == choices[(pos_x + 6)]):
            won = True
    if ((choices[0] == choices[4] and choices[0] == choices[8])
            or (choices[2] == choices[4] and choices[4] == choices[6])):
        won = True

print("Player " + str(int(Is_Current_One + 1)) + " won, Congratulations!")

[Edit 2] Okay, Sanetro, that's actually not the final edit. I was working on making an exit command. When the player types > exit, the program exits. I originally thought this would be really simple. You make a while loop, breaks the loop when player types exit, and then that's it! Well, its not simple (for me at least). As the choice = input(.....) is in the loop, I cannot put it outside the loop(or before the choice variable is declared), which is bad. I created a new variable at the top: exitTrigger and put new lines in the while loop. And it now does not work. When the player types exit, it just says please only enter valid fields. It is probably because the except statement still works, and I want to add a condition to trigger the except statement, and I only want the except statement when exitTrigger is True. Can I do that? Thanks.

choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']
Is_Current_One = True
won = False
wrongEntryPlayer1 = False
wrongEntryPlayer2 = False
exitTrigger = False
while not won and not exitTrigger:
    if not wrongEntryPlayer1 and not wrongEntryPlayer2:
        print("Type exit to quit game")
        print('\n')
        print('|' + choices[0] + ' |' + choices[1] + ' |' + choices[2] + ' |' + choices[3] + ' |')
        print('-------------')
        print('|' + choices[4] + ' |' + choices[5] + ' |' + choices[6] + ' |' + choices[7] + ' |')
        print('-------------')
        print('|' + choices[8] + ' |' + choices[9] + '|' + choices[10] + '|' + choices[11] + '|')
        print('-------------')
        print('|' + choices[12] + '|' + choices[13] + '|' + choices[14] + '|' + choices[15] + '|')
    # above code is to print board layouts
    if Is_Current_One:
        print("Player 1's turn.\nChoose a number to put an X there.")
        try:
            choice = int(input("> ").strip())
            if choice == "exit":
                exitTrigger = True
            else:
                wrongEntryPlayer1 = False
        except ValueError:
            if not exitTrigger:
                print("Please enter only valid fields from board (1-16)")
                wrongEntryPlayer1 = True
                continue
        except IndexError:
            if not exitTrigger:
                print("Please enter only valid fields from board (1-16)")
                wrongEntryPlayer1 = True
                continue
    else:
        print("Player 2's turn.\nChoose a number to put an O there.")
        try:
            choice = int(input("> ").strip())
            if choice == "exit":
                exitTrigger = True
            else:
                wrongEntryPlayer2 = False
        except ValueError:
            print("Please enter only valid fields from board (1-16)")
            wrongEntryPlayer2 = True
            continue
        except IndexError:
            if not exitTrigger:
                print("Please enter only valid fields from board (1-16)")
                wrongEntryPlayer2 = True
                continue

    if not exitTrigger:
        if Is_Current_One:
            try:  # <============ HERE
                if choices[choice - 1].isnumeric():
                    try:
                        choices[choice - 1] = 'X'
                        wrongEntryPlayer1 = False
                    except ValueError:
                        print("Please enter only valid fields from board (1-16)")
                        wrongEntryPlayer1 = True
                        continue
                    except IndexError:
                        print("Please enter only valid fields from board (1-16)")
                        wrongEntryPlayer1 = True
                        continue
                else:
                    print("Please choose a number that is empty.")
                    wrongEntryPlayer1 = True
            except:  # <============ HERE
                print("Please enter only valid fields from board (1-16)")
                wrongEntryPlayer1 = True
                continue
        else:
            try:  # <============ HERE
                if choices[choice - 1].isnumeric():
                    try:
                        choices[choice - 1] = 'O'
                        wrongEntryPlayer2 = False
                    except ValueError:
                        print("Please enter only valid fields from board (1-16)")
                        wrongEntryPlayer2 = True
                        continue
                    except IndexError:
                        print("Please enter only valid fields from board (1-16)")
                        wrongEntryPlayer2 = True
                        continue
                else:
                    print("Please choose a number that is empty.")
                    wrongEntryPlayer2 = True
            except:  # <============ HERE
                print("Please enter only valid fields from board (1-16)")
                wrongEntryPlayer2 = True
                continue

    # code to toggle between True and False
    if not exitTrigger:
        if wrongEntryPlayer1 == False and wrongEntryPlayer2 == False:
            Is_Current_One = not Is_Current_One

        for pos_x in range(0, 4):
            pos_y = pos_x * 4

            # for row condition:
            if (choices[pos_y] == choices[(pos_y + 1)]) and (
                    choices[pos_y] == choices[(pos_y + 2)]) and (
                    choices[pos_y] == choices[(pos_y + 3)]):
                won = True

            # column condition:
            if (choices[pos_x] == choices[(pos_x + 4)]) and (
                    choices[pos_x] == choices[(pos_x + 8)]) and (
                    choices[pos_x] == choices[(pos_x + 12)]):
                won = True
        if ((choices[0] == choices[5] and choices[0] == choices[10] and choices[0] == choices[15])
                or (choices[3] == choices[6] and choices[3] == choices[9] and choices[3] == choices[12])):
            won = True
if won:
    print('\n')
    print('|' + choices[0] + ' |' + choices[1] + ' |' + choices[2] + ' |' + choices[3] + ' |')
    print('-------------')
    print('|' + choices[4] + ' |' + choices[5] + ' |' + choices[6] + ' |' + choices[7] + ' |')
    print('-------------')
    print('|' + choices[8] + ' |' + choices[9] + '|' + choices[10] + '|' + choices[11] + '|')
    print('-------------')
    print('|' + choices[12] + '|' + choices[13] + '|' + choices[14] + '|' + choices[15] + '|')
    # above code is to print board layouts
    print("Player " + str(int(Is_Current_One + 1)) + " won, Congratulations!")
if exitTrigger:
    print("Game quited")

Btw the game board is now 4*4 :D

Upvotes: 1

Views: 220

Answers (3)

Sanetro
Sanetro

Reputation: 48

[edited] I made some fixes, and it's works ok.

choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
Is_Current_One = True
won = False
wrongEntryPlayer1 = False
wrongEntryPlayer2 = False
while not won:
    if not wrongEntryPlayer1 and not wrongEntryPlayer2:
        print('\n')
        print('|' + choices[0] + '|' + choices[1] + '|' + choices[2] + '|')
        print('----------')
        print('|' + choices[3] + '|' + choices[4] + '|' + choices[5] + '|')
        print('----------')
        print('|' + choices[6] + '|' + choices[7] + '|' + choices[8] + '|')
    # above code is to print board layouts
    if Is_Current_One:
        print("Player 1's turn.\nChoose a number to put an X there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer1 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer1 = True
            continue
    else:
        print("Player 2's turn.\nChoose a number to put an O there.")
        try:
            choice = int(input("> ").strip())
            wrongEntryPlayer2 = False
        except ValueError:
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer2 = True
            continue

    if Is_Current_One:
        if choices[choice - 1].isnumeric():
            try:
                choices[choice - 1] = 'X'
                wrongEntryPlayer1 = False
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer1 = True
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer1 = True
    else:
        if choices[choice - 1].isnumeric():
            try:
                choices[choice - 1] = 'O'
                wrongEntryPlayer2 = False
            except IndexError:
                print("Please enter only valid fields from board (0-8)")
                wrongEntryPlayer2 = True
        else:
            print("Please choose a number that is empty.")
            wrongEntryPlayer2 = True

    # code to toggle between True and False
    if wrongEntryPlayer1 == False and wrongEntryPlayer2 == False:
        Is_Current_One = not Is_Current_One

    for pos_x in range(0, 3):
        pos_y = pos_x * 3

        # for row condition:
        if (choices[pos_y] == choices[(pos_y + 1)]) and (
                choices[pos_y] == choices[(pos_y + 2)]):
            won = True

        # column condition:
        if (choices[pos_x] == choices[(pos_x + 3)]) and (
                choices[pos_x] == choices[(pos_x + 6)]):
            won = True
    if ((choices[0] == choices[4] and choices[0] == choices[8])
            or (choices[2] == choices[4] and choices[4] == choices[6])):
        won = True

print("Player " + str(int(Is_Current_One + 1)) + " won, Congratulations!")

So, I would like to apologise for some mistakes. And I found solution in internet. At line 35 if choices[choice - 1] == int: you must change like this if choices[choice - 1].isnumeric():, most of variables are treat like a object. If you would like to try with type() you will get an error. Next I deleted my choices_closed these things '='. It was completely unnecessary. Your idea was better then I made. I'm talking about condition if it's different then intiger it's fill'. I didn't see these lines of code:

    # code to toggle between True and False
    Is_Current_One = not Is_Current_One

I immediatly wrote that:

    # code to toggle between True and False
    if wrongEntryPlayer1 == False and wrongEntryPlayer2 == False:
        Is_Current_One = not Is_Current_One

I thought that you have been sleepy as me and you don't notice this. I must say this was my mistake

[Edit] I added some of exceptions here:

    if Is_Current_One:
        try: # <============ HERE
            if choices[choice - 1].isnumeric():
                try:
                    choices[choice - 1] = 'X'
                    wrongEntryPlayer1 = False
                except ValueError:
                    print("Please enter only valid fields from board (0-8)")
                    wrongEntryPlayer1 = True
                    continue
                except IndexError:
                    print("Please enter only valid fields from board (0-8)")
                    wrongEntryPlayer1 = True
                    continue
            else:
                print("Please choose a number that is empty.")
                wrongEntryPlayer1 = True
        except: # <============ HERE
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer1 = True
            continue
    else:
        try: # <============ HERE
            if choices[choice - 1].isnumeric():
                try:
                    choices[choice - 1] = 'O'
                    wrongEntryPlayer2 = False
                except ValueError:
                    print("Please enter only valid fields from board (0-8)")
                    wrongEntryPlayer2 = True
                    continue
                except IndexError:
                    print("Please enter only valid fields from board (0-8)")
                    wrongEntryPlayer2 = True
                    continue
            else:
                print("Please choose a number that is empty.")
                wrongEntryPlayer2 = True
        except: # <============ HERE
            print("Please enter only valid fields from board (0-8)")
            wrongEntryPlayer2 = True
            continue

Maybe it's final edit :P When you find something more I'll try to help.

Upvotes: 1

William Bradley
William Bradley

Reputation: 365

There are actually two problems with your code— first, your problem for which you asked for help is caused by toggling the flag Is_Current_One even when a player enters "bad" input. In other words, when Player One enters "asdf", we want them to have the chance to enter "good" input again, rather than immediately switching over to Player Two. Put an if block over that line that reads if not wrongEntryPlayer1 and not wrongEntryPlayer2:.

The second, much larger problem is your type checking for whether the player's input is an int doesn't work. First off, choices[choice - 1] == int is comparing a value in an array to a type, which will always be False. Second, even the function isinstance(choices[choice-1], int) doesn't work because every member of choices is a string type. You should therefore use the string method choices[choice-1].isnumeric(), which will determine if the string in the array is a number. (Alternatively, you could just test for it not being an x or an o, but this is more Pythonic.)

I tested these changes, and they seem to work. pastebin

Upvotes: 2

Julio Suaya
Julio Suaya

Reputation: 33

I think instead of using

 if not wrongEntryPlayer1 and not wrongEntryPlayer2:

You should use:

if wrongEntryPlayer1 or wrongEntryPlayer2:

That will fix the part of printing the board.

Upvotes: 0

Related Questions