Почему моя функция check_if_t ie () не работает в TicTacToe? - PullRequest
0 голосов
/ 25 мая 2020

Итак, у меня есть код Python для моего TicTacToe. Все работает нормально, за исключением случаев, когда победителя нет, программа должна возвращать 'T ie', а вместо этого просто продолжает запрашивать X и O, даже если доска уже заполнена. Я предполагаю, что проблема в функции check_if_t ie (), но я не могу ее понять.

# -------Global variables--------

# If game is still going
game_still_going = True


# Who won? Or tie
winner = None
# Whose turn it is
current_player = 'X'

# The board displaying function
board = [' '] * 10


def display_board():
    print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
    print('---+-'   '--+---  ')
    print(' ' + board[3] + ' | ' + board[4] + ' | ' + board[5])
    print('---+-'   '--+---  ')
    print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])

# Checks if game is over


def check_if_game_over():
    check_if_tie()
    check_if_win()


# Checks if there is a winner


def check_if_win():
    global winner

    if check_row():
        winner = check_row()
    elif check_columns():
        winner = check_columns()
    elif check_diagonals():
        winner = check_columns()
    else:
        winner = None
    return


def check_row():
    global game_still_going
    row1 = board[6] == board[7] == board[8] != " "
    row2 = board[3] == board[4] == board[5] != " "
    row3 = board[0] == board[1] == board[2] != " "
    if row1 or row2 or row3:
        game_still_going = False
    if row1:
        return board[6]
    elif row2:
        return board[3]
    elif row3:
        return board[0]

    return


def check_columns():
    global game_still_going
    column1 = board[6] == board[3] == board[0] != " "
    column2 = board[7] == board[4] == board[1] != " "
    column3 = board[8] == board[5] == board[2] != " "
    if column1 or column2 or column3:
        game_still_going = False
    if column1:
        return board[6]
    elif column2:
        return board[7]
    elif column3:
        return board[8]
    return


def check_diagonals():
    global game_still_going
    diagonal1 = board[6] == board[4] == board[2] != " "
    diagonal2 = board[0] == board[4] == board[8] != " "
    if diagonal1 or diagonal2:
        game_still_going = False
    elif diagonal1:
        return board[6]
    elif diagonal2:
        return board[0]
    return


def check_if_tie():
    global game_still_going
    if ' ' not in board:
        game_still_going = False
    return


def flip_player():
    global current_player
    if current_player == 'X':
        current_player = 'O'
    elif current_player == 'O':
        current_player = 'X'
    return


# Whose turn it is to play


def handle_turn(player):
    print(player + "'s turn")
    position = int(input('Please write your position from 1 - 9: ')) - 1
    if position not in [0,1,2,3,4,5,6,7,8,9]:
        return input('Invalid position. Please write 1-9: ')
    board[position] = player
    display_board()


# Main gameplay function
def play_game():
    global winner
    # Displays initial board
    display_board()
    # Loop running the game
    while game_still_going:

        handle_turn(current_player)
        flip_player()
        check_if_game_over()

    if winner == 'X' or winner == 'O':
        print(winner + ' won.')
    elif winner:
        print('Tie')


play_game()

Ответы [ 2 ]

3 голосов
/ 25 мая 2020

У вас довольно много проблем в этом коде, и большей части проблемы можно избежать, отказавшись от использования глобальных переменных.

Когда вы используете глобальные переменные, вы меняете глобальное состояние, которое затрудняет понять, что происходит. У вас есть функции, которые не возвращают ничего, кроме изменения состояния, которое приведет к завершению игры или нет.

Одно простое изменение будет заключаться в том, чтобы метод check_ возвращал фактическое логическое значение и использовал это значение в l oop чтобы проверить, набрали ли вы ie или выигрыш.

Если вы не набрали ie или выигрыш, это означает, что игра не закончена. Таким образом, вам не нужно хранить глобальное значение и, конечно, не нужно изменять состояние is at ie или выигрыш где-либо еще.

Сохраняйте ваши функции как можно проще. Я часто говорю это, но подумайте, как вы на самом деле играете в игру.

В игре у вас есть 2 игрока и 1 доска, на которой вы устанавливаете значения где угодно.

Каждый ход добавляет фишку, пока игра заканчивается на ie или выигрышем.

Каждый раз, когда вы добавляете фишку, вы можете проверить состояние игры. Если это не закончено, вы можете переключить текущего игрока, ввести новую фигуру и повторить.

Ничего из этого не требует глобального состояния, и вы всегда можете передать игровое поле своим методам ...

В вашем случае это было бы так же просто, как сделать это:

def is_tie():
    return ' ' not in board

def is_win():
    ... is_win logic
    return result


while not is_tie() or not is_win():
    ... game logic

To go на шаг дальше, вместо того, чтобы иметь глобальные переменные, вам нужно было бы передать состояние игры как следующее:

def is_tie(game):
    return ' ' not in game.board

И на go следующий шаг, ввод новой фигуры на доске вернет новое состояние. Таким образом, вместо изменения текущего состояния у вас будет основной l oop, который выглядит следующим образом:

game = Game()

while True:
    position = game.prompt_choice()
    if not game.position_available(position)
        # loop again to select a new position
        continue

    game = game.execute_turn(position)

    if game.is_done()
        break
    else:
        # if game not done switch player and move to next turn
        game = game.switch_player()

# current game player is winner
game.print_winner()

Замечательно то, что если вы хотите «воспроизвести» игру, вы просто необходимо сохранить состояние игры непосредственно перед повторением цикла. каждая возвращаемая «игра» является модифицированной версией предыдущего игрового объекта, поэтому вы никогда не изменяете реальный объект.

0 голосов
/ 25 мая 2020

Самым простым предложением, которое я могу придумать, было бы иметь переменную, которая хранит количество оставшихся доступных квадратов и уменьшает его после каждого хода. Как только он достигает 0, если выигрыша нет, то должно быть ie.

# -------Global variables--------

# If game is still going
game_still_going = True


# Who won? Or tie
winner = None
# Whose turn it is
current_player = 'X'

# The board displaying function
board = [' '] * 10

#board spaces
board_spaces = 9

def display_board():
    print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
    print('---+-'   '--+---  ')
    print(' ' + board[3] + ' | ' + board[4] + ' | ' + board[5])
    print('---+-'   '--+---  ')
    print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])

# Checks if game is over


def check_if_game_over():
    check_if_win()
    check_if_tie()


# Checks if there is a winner


def check_if_win():
    global winner

    if check_row():
        winner = check_row()
    elif check_columns():
        winner = check_columns()
    elif check_diagonals():
        winner = check_columns()
    else:
        winner = None
    return


def check_row():
    global game_still_going
    row1 = board[6] == board[7] == board[8] != " "
    row2 = board[3] == board[4] == board[5] != " "
    row3 = board[0] == board[1] == board[2] != " "
    if row1 or row2 or row3:
        game_still_going = False
    if row1:
        return board[6]
    elif row2:
        return board[3]
    elif row3:
        return board[0]

    return


def check_columns():
    global game_still_going
    column1 = board[6] == board[3] == board[0] != " "
    column2 = board[7] == board[4] == board[1] != " "
    column3 = board[8] == board[5] == board[2] != " "
    if column1 or column2 or column3:
        game_still_going = False
    if column1:
        return board[6]
    elif column2:
        return board[7]
    elif column3:
        return board[8]
    return


def check_diagonals():
    global game_still_going
    diagonal1 = board[6] == board[4] == board[2] != " "
    diagonal2 = board[0] == board[4] == board[8] != " "
    if diagonal1 or diagonal2:
        game_still_going = False
    elif diagonal1:
        return board[6]
    elif diagonal2:
        return board[0]
    return


def check_if_tie():
    global game_still_going
    global winner
    global board_spaces
    if winner == None and board_spaces == 0:
        game_still_going = False
    return


def flip_player():
    global current_player
    if current_player == 'X':
        current_player = 'O'
    elif current_player == 'O':
        current_player = 'X'
    return


# Whose turn it is to play


def handle_turn(player):
    print(player + "'s turn")
    position = int(input('Please write your position from 1 - 9: ')) - 1
    if position not in [0,1,2,3,4,5,6,7,8,9]:
        return input('Invalid position. Please write 1-9: ')
    board[position] = player
    display_board()
    board_spaces -= 1


# Main gameplay function
def play_game():
    global winner
    # Displays initial board
    display_board()
    # Loop running the game
    while game_still_going:

        handle_turn(current_player)
        flip_player()
        check_if_game_over()

    if winner == 'X' or winner == 'O':
        print(winner + ' won.')
    elif winner:
        print('Tie')


play_game()
...