0

I am currently learning python and trying to build a tic tac toe game. I wrote a program to prevent the user repeating the same input but when I repeat the same number two times, the program starts looping continuously without stopping. Could someone give me advice on how to rectify this issue? see below the code:

from tabulate import tabulate

# define the board
board = ["_", "_", "_",
         "_", "_", "_",
         "_", "_", "_"]
# Current player
current_player = "X"
winner = None

game_still_on = True


def play_game():
    while game_still_on:
        position()
        board_display()
        handle_player()
        winner_check()
        winner_check2()


def handle_player():
    global current_player
    if current_player == "X":
        current_player = "O"
    elif current_player == "O":
        current_player = "X"


def board_display():
    board_row1 = [board[0], board[1], board[2]]
    board_row2 = [board[3], board[4], board[5]]
    board_row3 = [board[6], board[7], board[8]]

    com_board = [board_row1,
                 board_row2,
                 board_row3]
    print(tabulate(com_board, tablefmt="grid"))


# position input
def position():
    global board
    print(current_player+"'s turn")
    positions = input("enter 1-9")
    valid = False
    while not valid:
        while int(positions) >= 10 or 0 >= int(positions):
            positions = input("Choose a position from 1 -9")
        positions = int(positions)
        if board[positions-1] == "_":
            valid = True
        else:
            print("Choose another")
    board[positions - 1] = current_player

def winner_check():
    if board[0] == board[1] == board[2] != "_":
        return board[0]
    elif board[3] == board[4] == board[5] != "_":
        return board[3]
    elif board[6] == board[7] == board[8] != "_":
        return board[6]
    elif board[0] == board[3] == board[6] != "_":
        return board[0]
    elif board[1] == board[4] == board[7] != "_":
        return board[1]
    elif board[2] == board[5] == board[8] != "_":
        return board[2]
    elif board[0] == board[4] == board[8] != "_":
        return board[0]
    elif board[2] == board[4] == board[6] != "_":
        return board[1]
    else:
        return None

def winner_check2():
    row_winner = winner_check()
    if row_winner:
        global game_still_on
        global winner
        winner = row_winner
        print((winner+ " won"))
        game_still_on = False

play_game()
quamrana
  • 37,849
  • 12
  • 53
  • 71
  • btw you call `winner_check()` in `play_game()` and discard the result. You don't need to call it here at all since it is called in `winner_check2()` – quamrana Nov 18 '19 at 20:15

1 Answers1

0

Let's look at this function:

# position input
def position():
    global board
    print(current_player+"'s turn")
    positions = input("enter 1-9")
    valid = False
    while not valid:
        while int(positions) >= 10 or 0 >= int(positions):
            positions = input("Choose a position from 1 -9")
        positions = int(positions)
        if board[positions-1] == "_":
            valid = True
        else:
            print("Choose another")
    board[positions - 1] = current_player

This has nested validation loops. The inner one checks the range of the input integer (if it is an integer -- otherwise it throws an exception) and requests input until it's in range. That's fine.

Then in the outer validation loop, it checks if the requested space is unoccupied. If so, fine. If not, it prompts the user to choose another. But the input call is before the outer loop, so it just tries again to validate the same input that already failed.

Try moving the input into the outer loop:

# position input
def position():
    global board
    print(current_player+"'s turn")
    valid = False
    while not valid:
        positions = input("enter 1-9")
        while int(positions) >= 10 or 0 >= int(positions):
            positions = input("Choose a position from 1 -9")
        positions = int(positions)
        if board[positions-1] == "_":
            valid = True
        else:
            print("Choose another")
    board[positions - 1] = current_player

I'd probably also change the inner loop to be just an if with a continue and make the handling of non-integer input more robust.

Fred Larson
  • 60,987
  • 18
  • 112
  • 174
  • Thank you very much for the replies and it solved the issue. Much appreciated. I'm also trying figure out a code to prevent entering wrong inputs other than numbers 1 -9. such letters and various symbols (ex- a@#+!%-). Could someone guide me on this please? – Udayana Gamage Nov 19 '19 at 17:36
  • That sounds like another question. But do look around at other questions before you ask your own, as there are likely already answers. – Fred Larson Nov 19 '19 at 18:09
  • Check out this one: https://stackoverflow.com/q/5424716/10077 – Fred Larson Nov 19 '19 at 18:14