如何避免多个`elif`语句?

Hei*_*erg 5 python python-3.x

所以,我试图用 python 制作一个基本的 Tic-Tac-Toe 游戏,我创建了一个运行良好的游戏,但我的代码不是那么好,因为它有很多用于检查列表索引的代码(Winner Of游戏),这有点困扰我。那么,我如何避免使用左索引来检查游戏的获胜者?

我的代码:

board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']


def show_board():# for showing the tic-tac-toe board
    print(' | ' + str(board[0]) + ' | ' +
          str(board[1]) + ' | ' + str(board[2]) + ' | ')
    print(' | ' + str(board[3]) + ' | ' +
          str(board[4]) + ' | ' + str(board[5]) + ' | ')
    print(' | ' + str(board[6]) + ' | ' +
          str(board[7]) + ' | ' + str(board[8]) + ' | ')


def main():
    one = 1
    flag = 1

    show_board()
    while one == 1:
        if flag == 1:
            x_o = 'X'
        if flag == 2:
            x_o = 'O'
        pos = int(input('Player "' + x_o + '" Turn: '))

        if x_o == 'o':
            x_o = 'O'
        if x_o == 'x':
            x_o = 'X'
        if board[pos - 1] == 'O' or board[pos - 1] == 'O':
            print('That Place Is Already Filled By Player "0"')

        if board[pos - 1] == 'X' or board[pos - 1] == 'X':
            print('That Place Is Already Filled By Player "X"')

        else:
            try:
                board[pos - 1] = x_o
            except IndexError:
                print('Type Numbers Between Only 1 And 9')

            if flag == 1:
                flag = 2
            elif flag == 2:
                flag = 1

            show_board()

            # Checking The Winner Of The Game

            # for horizontal X
            if board[0] == board[1] == board[2] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            elif board[3] == board[4] == board[5] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            elif board[6] == board[7] == board[8] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            # for Daigonal X
            elif board[0] == board[4] == board[8] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            elif board[2] == board[4] == board[6] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            # for Vertical X
            elif board[1] == board[4] == board[7] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            elif board[2] == board[5] == board[8] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            elif board[0] == board[3] == board[6] == 'X':
                one = 2
                print('The Winner Is Player "X"!')

            # for horizontal O
            elif board[0] == board[1] == board[2] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[3] == board[4] == board[5] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[6] == board[7] == board[8] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            # for Diagonal O
            elif board[0] == board[4] == board[8] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[2] == board[4] == board[6] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            # for Vertical 0
            elif board[1] == board[4] == board[7] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[2] == board[5] == board[8] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[0] == board[3] == board[6] == 'O':
                one = 2
                print('The Winner Is Player "O"!')

            elif board[0] != ' ' and board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[6] != ' ' and board[7] != ' ' and board[8] != ' ':
                print('The Match Is A Tie!')
                one = 2


main()
Run Code Online (Sandbox Code Playgroud)

所以,正如你所看到的,我使用了很多 if 语句来检查游戏的获胜者。我怎样才能避免这种情况并在更少的行中做到这一点。

nor*_*ok2 3

您可以用一些循环替换它们,例如:

board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']


def show_board():# for showing the tic-tac-toe board
    print(' | ' + str(board[0]) + ' | ' +
          str(board[1]) + ' | ' + str(board[2]) + ' | ')
    print(' | ' + str(board[3]) + ' | ' +
          str(board[4]) + ' | ' + str(board[5]) + ' | ')
    print(' | ' + str(board[6]) + ' | ' +
          str(board[7]) + ' | ' + str(board[8]) + ' | ')


def main():
    one = 1
    flag = 1

    show_board()
    while one == 1:
        if flag == 1:
            x_o = 'X'
        if flag == 2:
            x_o = 'O'
        pos = int(input('Player "' + x_o + '" Turn: '))

        if x_o == 'o':
            x_o = 'O'
        if x_o == 'x':
            x_o = 'X'
        if board[pos - 1] == 'O' or board[pos - 1] == 'O':
            print('That Place Is Already Filled By Player "0"')

        if board[pos - 1] == 'X' or board[pos - 1] == 'X':
            print('That Place Is Already Filled By Player "X"')

        else:
            try:
                board[pos - 1] = x_o
            except IndexError:
                print('Type Numbers Between Only 1 And 9')

            if flag == 1:
                flag = 2
            elif flag == 2:
                flag = 1

            show_board()

            # Checking The Winner Of The Game
            won = False
            for turn in ('X', 'O'):
                # horizontal
                if not won:
                    for i in (0, 3, 6):
                        if all(board[i + k] == turn for k in range(3)):
                            won = True
                            break
                # vertical
                if not won:       
                    for i in range(3):
                        if all(board[i + k] == turn for k in (0, 3, 6)):
                            won = True
                            break
                # diagonal
                if not won:
                    if all(board[k] == turn for k in (0, 4, 8)) or \
                            all(board[k] == turn for k in (2, 4, 6)):
                        won = True
                # handle winning
                if won:
                    one = 2
                    print(f'The Winner Is Player "{turn}"!')
                    break
            # handle a tie
            if not won and all(square != ' ' for square in board):
                one = 2
                print('The Match Is A Tie!')


main()
Run Code Online (Sandbox Code Playgroud)

(您或许还可以对其余代码进行相当多的完善/简化)


编辑

这是一些类似的代码简化/完善/扩展为:

  • 处理任意尺寸的板
  • 正确处理非数字输入
  • 使用更多功能
  • 去掉多余的变量
NUM_ROWS = 3
NUM_COLS = 3
NUM_WIN = 3
BOARD_SIZE = NUM_ROWS * NUM_COLS

EMPTY = ' '
BOARD = [EMPTY] * BOARD_SIZE
TURNS = 'X', 'O'


def show_board(board):
    """Show the tic-tac-toe board."""
    for i in range(0, BOARD_SIZE, NUM_COLS):
        print(' | ' + ' | '.join(board[i:i + NUM_COLS]) + ' | ')


def ij(i, j):
    """Convert (row, col) to board index."""
    return i + NUM_COLS * j


def check_winner(board, turn):
    """Check if there is a winner."""
    # horizontal
    for i in range(NUM_ROWS):
        for j in range(NUM_COLS - NUM_WIN + 1):
            if all(board[ij(i, j + k)] == turn for k in range(NUM_WIN)):
                return True
    # vertical
    for i in range(NUM_ROWS - NUM_WIN + 1):
        for j in range(NUM_COLS):
            if all(board[ij(i + k, j)] == turn for k in range(NUM_WIN)):
                return True
    # diagonal
    for i in range(NUM_ROWS - NUM_WIN + 1):
        for j in range(NUM_COLS - NUM_WIN + 1):
            K = NUM_WIN
            if all(board[ij(i + k, j + k)] == turn for k in range(NUM_WIN)):
                return True
            if all(board[ij(i + NUM_WIN - k - 1, j + k)] == turn
                   for k in range(NUM_WIN)):
                return True


def check_tie(board):
    """Check if tie."""
    return all(square != EMPTY for square in board)


def next_turn(turn):
    """Advance to next turn."""
    return TURNS[(TURNS.index(turn) + 1) % 2]


def main():
    """Tic-tac-toe game."""
    turn = TURNS[0]
    show_board(BOARD)
    while True:
        valid_input = False
        while not valid_input:
            try:
                choice = int(input(f'Player `{turn}` turn: '))
                valid_input = (1 <= choice <= BOARD_SIZE)
                if not valid_input:
                    raise ValueError
            except ValueError:
                print(f'Type numbers between 1 and {BOARD_SIZE} only.')
            else:
                idx = choice - 1
                if BOARD[idx] != EMPTY:
                    print(f'Position `{idx}` already taken by `{BOARD[idx]}`')
                else:
                    BOARD[idx] = turn

        show_board(BOARD)
        won = check_winner(BOARD, turn)
        if won:
            print(f'The winner is player `{turn}`!')
            break
        # handle a tie
        if not won and check_tie(BOARD):
            print('The match is a tie!')
            break
        turn = next_turn(turn)


if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

请检查mnk-game源代码以获取使用 NumPy 和类(尤其是 )的类似实现Board.py。免责声明:我是该包的作者。


编辑2

请注意,仅对于tic-tac-toe,可以使用类似于 @rusu_ro1提议的check_winner()方法来缩短:

WIN_CASES = [
    [0, 1, 2], [3, 4, 5], [6, 7, 8],  # horizontal
    [0, 3, 6], [1, 4, 7], [2, 5, 8],  # vertical
    [0, 4, 8], [2, 4, 6],  # diagonal
]


def check_winner(board, turn, win_cases=WIN_CASES):
    """Check if there is a winner."""
    for win_case in win_cases:
        if all(board[i] == turn for i in win_case):
            return True
Run Code Online (Sandbox Code Playgroud)