【问题标题】:How can i make it more simple and easy to read? in my tic tac toe python project我怎样才能使它更简单易读?在我的井字游戏 python 项目中
【发布时间】:2022-01-22 12:00:56
【问题描述】:

我做了一个函数来检查我的套接字井字游戏中是否有胜利,问题是,它很难阅读。

有没有办法让它更简单?我考虑过 for 循环,但我认为在我的情况下它不会是正确的

    if board[0][0] == board[1][0] and board[1][0] == board[2][0]:
        if board[0][0] == 'X':
            client_sockets[0].send("you win")
            client_sockets[1].send("you lose")
        else:
            client_sockets[1].send("you win")
            client_sockets[0].send("you lose")
    if board[0][1] == board[1][1] and board[1][1] == board[2][1]:
        if board[0][1] == 'X':
            client_sockets[0].send("you win")
            client_sockets[1].send("you lose")
        else:
            client_sockets[1].send("you win")
            client_sockets[0].send("you lose")
    if board[0][2] == board[1][2] and board[1][2] == board[2][2]:
        if board[0][0] == 'X':
            client_sockets[0].send("you win")
            client_sockets[1].send("you lose")
        else:
            client_sockets[1].send("you win")
            client_sockets[0].send("you lose")

等等……

【问题讨论】:

标签: python tic-tac-toe python-sockets


【解决方案1】:

这是一个使用套接字的非常酷的项目 - https://github.com/Suvoo/TicTacToe-Using-Socket-Server

试试这个 sn-p sn-p:

import random


class TicTacToe:

    def __init__(self):
        self.board = []

    def create_board(self):
        for i in range(3):
            row = []
            for j in range(3):
                row.append('-')
            self.board.append(row)

    def get_random_first_player(self):
        return random.randint(0, 1)

    def fix_spot(self, row, col, player):
        self.board[row][col] = player

    def is_player_win(self, player):
        win = None

        n = len(self.board)

        # checking rows
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[i][j] != player:
                    win = False
                    break
            if win:
                return win

        # checking columns
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[j][i] != player:
                    win = False
                    break
            if win:
                return win

        # checking diagonals
        win = True
        for i in range(n):
            if self.board[i][i] != player:
                win = False
                break
        if win:
            return win

        win = True
        for i in range(n):
            if self.board[i][n - 1 - i] != player:
                win = False
                break
        if win:
            return win
        return False

        for row in self.board:
            for item in row:
                if item == '-':
                    return False
        return True

    def is_board_filled(self):
        for row in self.board:
            for item in row:
                if item == '-':
                    return False
        return True

    def swap_player_turn(self, player):
        return 'X' if player == 'O' else 'O'

    def show_board(self):
        for row in self.board:
            for item in row:
                print(item, end=" ")
            print()

    def start(self):
        self.create_board()

        player = 'X' if self.get_random_first_player() == 1 else 'O'
        while True:
            print(f"Player {player} turn")

            self.show_board()

            # taking user input
            row, col = list(
                map(int, input("Enter row and column numbers to fix spot: ").split()))
            print()

            # fixing the spot
            self.fix_spot(row - 1, col - 1, player)

            # checking whether current player is won or not
            if self.is_player_win(player):
                print(f"Player {player} wins the game!")
                break

            # checking whether the game is draw or not
            if self.is_board_filled():
                print("Match Draw!")
                break

            # swapping the turn
            player = self.swap_player_turn(player)

        # showing the final view of board
        print()
        self.show_board()


# starting the game
tic_tac_toe = TicTacToe()
tic_tac_toe.start()

more info

【讨论】:

  • 有没有办法让我自己的代码更简单?我不想在这个阶段使用类 + 我的代码正在使用套接字
【解决方案2】:

您可以将棋盘的当前状态编码为字符串而不是嵌套列表。 比如,

board = [['O', 'X', ''], ['O', 'X', ''], ['X', 'X', '']]

也可以编码为:

sboard = "OX OX XX "

(用元组替换所有列表也可以。)

接下来,你编写两个函数:

def xwins():
    client_sockets[0].send("you win")
    client_sockets[1].send("you lose")

def owins():
    client_sockets[1].send("you win")
    client_sockets[0].send("you lose")

最后,您创建了一个包含所有游戏结束板的字典。 这是可能的,因为字符串是可散列的,因此可以用作字典键。

victory = {
    "OX OX XX ": xwins,
    "OX OX OX ": ywins,
    # et cetera
}

注意我们是如何引用函数的,但不要在这里调用它们。

每次移动后,您都会根据旧字符串和用户输入创建一个新的sboard 字符串。

如果棋盘是赢棋,则通过字典调用正确的函数:

if sboard in victory:
    victory[sboard]()
    exit_game()
# else continue playing.

【讨论】:

    【解决方案3】:

    if board[0][2] == 'X'... 下的第 3 个条件存在错误,您正在检查 if board[0][0] == 'X'

    这突出了为什么所有这些代码重复都容易出错。因此,DRY 原则。

    当您重复这样的代码时,请考虑“间接”。数据结构和元数据是编写不会重复的通用代码的关键。

    例如,假设您有一个坐标三元组列表,它们对应于井字棋棋盘的 8 条“线”。您可以遍历这个列表,并且只使用坐标三元组实现一次条件:

    winCoords = [ [(0,0),(0,1),(0,2)],
                  [(1,0),(1,1),(1,2)],
                  [(2,0),(2,1),(2,2)],
                  [(0,0),(1,0),(2,0)],
                  [(0,1),(1,1),(2,1)],
                  [(0,2),(1,2),(2,2)],
                  [(0,0),(1,1),(2,2)],
                  [(0,2),(1,1),(2,0)] ]
    
    for (r0,c0),(r1,c1),(r2,c2) in winCoords:
        if board[r0][c0] == board[r1][c1] == board[r2][c2]:
            winner,loser = (1,0) if board[r0][c0] == "X" else (0,1)
            client_sockets[winner].send("you win")
            client_sockets[loser].send("you lose")
            break
    

    请注意,您的示例代码没有描述您如何处理所有 3 个值都相等但“X”和“O”都不相等的未播放行,这似乎会导致“O”的获胜条件(除非默认值都是不同的)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-03
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多