首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tic-Tac-Toe游戏

Tic-Tac-Toe游戏
EN

Code Review用户
提问于 2016-10-05 14:49:07
回答 2查看 858关注 0票数 10

这里是我为在python2.7中运行而创建的游戏。我仍然在学习,并且觉得400+代码行对于这么小的应用程序来说有点长。然而,试图得到一些反馈,我可以把游戏放在一起更好(和更短),同时仍然保留完整的功能。

欢迎任何和所有的反馈。请注意,我只使用Python了几个星期,所以任何太高级的东西,我可能都无法理解。

代码语言:javascript
复制
# Game of Tic-Tac-Toe
import os
import sys

def Start():
    # Variables
    a1 = "1"
    a2 = "2"
    a3 = "3"
    a4 = "4"
    a5 = "5"
    a6 = "6"
    a7 = "7"
    a8 = "8"
    a9 = "9"
    location = "0"

    # Splash Screen
    os.system('cls' if os.name == 'nt' else 'clear')
    print "Welcome to Tic-Tac-Toe!"
    print """

       |   |
    ---|---|---
       |   |
    ---|---|---
       |   |

    You may press CTRL+C at any time to quit this game.
    Beware that progress is not saved.

    Who shall go first, X or O?
    """
    start = raw_input("Please enter \"X\" or \"O\" when ready> ")

    if start == "X" or start == "x":
        Turn_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)
    elif start == "O" or start == "o":
        Turn_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)
    else:
        Start(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Turn_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    os.system('cls' if os.name == 'nt' else 'clear')
    print """

     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    # Ask for play
    print "It is Player X\'s turn"
    location = raw_input("Please enter a location to play (1-9)> ")
    Place_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Place_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    if location == a1:
        a1 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a2:
        a2 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a3:
        a3 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a4:
        a4 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a5:
        a5 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a6:
        a6 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a7:
        a7 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a8:
        a8 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a9:
        a9 = "X"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    else:
        Bad_Entry_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

    Win_Check_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Bad_Entry_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    os.system('cls' if os.name == 'nt' else 'clear')
    print """

     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    # Ask for play
    print "Player X chose %s." % location
    print "This is an invalid location."
    location = raw_input("Please enter a location for Player X to play (1-   9)> ")
    Place_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Win_Check_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    # Win checks
    if (a1 == "X" and a2 == "X" and a3 == "X"):
        a1 = "-"
        a2 = "-"
        a3 = "-"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a4 == "X" and a5 == "X" and a6 == "X"):
        a4 = "-"
        a5 = "-"
        a6 = "-"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a7 == "X" and a8 == "X" and a9 == "X"):
        a7 = "-"
        a8 = "-"
        a9 = "-"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a1 == "X" and a4 == "X" and a7 == "X"):
        a1 = "|"
        a4 = "|"
        a7 = "|"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a2 == "X" and a5 == "X" and a8 == "X"):
        a2 = "|"
        a5 = "|"
        a8 = "|"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a3 == "X" and a6 == "X" and a9 == "X"):
        a3 = "|"
        a6 = "|"
        a9 = "|"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a1 == "X" and a5 == "X" and a9 == "X"):
        a1 = "\\"
        a5 = "\\"
        a9 = "\\"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a3 == "X" and a5 == "X" and a7 == "X"):
        a3 = "/"
        a5 = "/"
        a7 = "/"
        Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    else:
        if a1 != "1" and a2 != "2" and a3 != "3" and a4 != "4" and a5 != "5" and a6 != "6" and a7 != "7" and a8 != "8" and a9 != "9":
            Win_T(a1, a2, a3, a4, a5, a6, a7, a8, a9)
        else:
            Turn_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Turn_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    os.system('cls' if os.name == 'nt' else 'clear')
    print """

     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    # Ask for play
    print "It is Player O\'s turn"
    location = raw_input("Please enter a location to play (1-9)> ")
    Place_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Place_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    if location == a1:
        a1 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a2:
        a2 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a3:
        a3 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a4:
        a4 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a5:
        a5 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a6:
        a6 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a7:
        a7 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a8:
        a8 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    elif location == a9:
        a9 = "O"
        print """

         %s | %s | %s
        ---|---|---
         %s | %s | %s
        ---|---|---
         %s | %s | %s

        """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    else:
        Bad_Entry_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

    Win_Check_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Bad_Entry_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    os.system('cls' if os.name == 'nt' else 'clear')
    print """

     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    # Ask for play
    print "Player O chose %s." % location
    print "This is an invalid location."
    location = raw_input("Please enter a location for Player O to play (1-9)> ")
    Place_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Win_Check_O(a1, a2, a3, a4, a5, a6, a7, a8, a9, location):
    # Win checks
    if (a1 == "O" and a2 == "O" and a3 == "O"):
        a1 = "-"
        a2 = "-"
        a3 = "-"
    Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a4 == "O" and a5 == "O" and a6 == "O"):
        a4 = "-"
        a5 = "-"
        a6 = "-"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a7 == "O" and a8 == "O" and a9 == "O"):
        a7 = "-"
        a8 = "-"
        a9 = "-"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a1 == "O" and a4 == "O" and a7 == "O"):
        a1 = "|"
        a4 = "|"
        a7 = "|"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a2 == "O" and a5 == "O" and a8 == "O"):
        a2 = "|"
        a5 = "|"
        a8 = "|"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a3 == "O" and a6 == "O" and a9 == "O"):
        a3 = "|"
        a6 = "|"
        a9 = "|"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a1 == "O" and a5 == "O" and a9 == "O"):
        a1 = "\\"
        a5 = "\\"
        a9 = "\\"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    if (a3 == "O" and a5 == "O" and a7 == "O"):
        a3 = "/"
        a5 = "/"
        a7 = "/"
        Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9)
    else:
        if a1 != "1" and a2 != "2" and a3 != "3" and a4 != "4" and a5 != "5" and a6 != "6" and a7 != "7" and a8 != "8" and a9 != "9":
            Win_T(a1, a2, a3, a4, a5, a6, a7, a8, a9)
        else:
            Turn_X(a1, a2, a3, a4, a5, a6, a7, a8, a9, location)

def Win_X(a1, a2, a3, a4, a5, a6, a7, a8, a9):
    os.system('cls' if os.name == 'nt' else 'clear')
    print "Player X Wins"
    print """
     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    Replay()

def Win_O(a1, a2, a3, a4, a5, a6, a7, a8, a9):
    os.system('cls' if os.name == 'nt' else 'clear')
    print "Player O Wins"
    print """
     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    Replay()

def Win_T(a1, a2, a3, a4, a5, a6, a7, a8, a9):
    os.system('cls' if os.name == 'nt' else 'clear')
    print "The game is a tied game."
    print "Congratulations! Noone has lost."
    print """
     %s | %s | %s
    ---|---|---
     %s | %s | %s
    ---|---|---
     %s | %s | %s

    """ % (a1, a2, a3, a4, a5, a6, a7, a8, a9)
    Replay()

def Replay():
    over = raw_input("Would you like to play again? (Y / N) ")
    if over == "Y" or over == "y":
        Start()
    elif over == "N" or over == "n":
        exit(0)
    else:
        Replay()

Start()
#Winning combos-
# (1 2 3)
# (4 5 6)
# (7 8 9)
# (1 4 7)
# (2 5 8)
# (3 6 9)
# (1 5 9)
# (3 5 7)
EN

回答 2

Code Review用户

回答已采纳

发布于 2016-10-05 16:56:49

努力保持同样的一般做法,但改进执行:

  1. 您可以在单独的变量中定义所有数字,并将这些变量单独传递。在列表中定义它们会更容易。
  2. 您可以使用range生成数字列表,而不是手动创建数字。它们不需要是字符串,python在打印时会将它们转换为字符串。若要使其跨python版本可移植,请使用list(range())
  3. 可以使用int将整数的字符串版本转换为数字。因此,ind = int(location)-1将直接将用户的数字输入转换到列表中的某个位置,因此您不需要比较列表中的元素,更不用说单个变量了。
  4. 可以使用索引在列表中设置位置,因此可以使用board[ind] = 'x'
  5. 您可以使用in来匹配多个值,例如if start in 'xY'if start == "X"start == "x":。但是,由于您只想进行不区分大小写的匹配,所以可以通过start.upper() == 'X'start转换为大写值,然后只匹配大写版本。或者更好的是,只需从一开始就做raw_input('foo').upper(),使其大写。
  6. 您有单独的函数来处理xo移动。如果有一个函数可以接受播放器作为参数,那就更简单了。
  7. 可以使用.format(*board)将列表board中的所有值展开为format的单个参数。
  8. 与手动检查特定组合不同,您可以检查与"win“相对应的特定索引组合,并检查这些组合是否都有相同的部分。
  9. 您可以使用set来确定游戏是否结束。set有点像一个列表,但它只允许每个值中的一个,而不保存。因此,如果你做set(board) == {'X', 'O'},它将是真实的当且仅当没有剩下的数字在板上(也就是说,游戏结束)。
  10. 您多次使用相同的代码创建板。将其划分为自己的功能会更容易一些。这可能包括清除输出。
  11. 以这种方式将start()行包装成if __name__ == '__main__':,只有当代码用作函数时才能运行。
  12. 您应该使用from __future__ import print_functionprint()。这将使您的代码可以跨Python2和Python3移植,还可以使用sep参数更容易地打印您的板。
  13. 您可以递归地运行代码。也就是说,函数A调用函数B,后者调用函数C,后者再次调用函数A。使用循环可以更容易地跟踪代码流。然后,您可以在循环中每次切换播放机。
  14. 在python中,您可以为函数参数定义默认值。因此,如果没有提供数字,您可以让纸板打印函数打印为空板,或者,如果提供了另一个参数,则可以让它打印额外的文本。
  15. 你不需要检查某个特定的董事会位置是否已经被占据。
  16. 不要使用exit(0)。让脚本正常退出一个函数即可。
  17. Python3将raw_input重命名为input。如果存在,可以通过将raw_input重命名为input来使代码python 3兼容。
  18. pep8为python代码定义了正常的样式。这包括大写,空格等。你不需要遵循它,但这是一个普遍的惯例。

这是我的代码版本。如果你有任何问题,可以问:

代码语言:javascript
复制
"""Game of Tic-Tac-Toe"""

from __future__ import print_function

import os

# Make code work with Python 2 and Python 3
try:
    input = raw_input
except NameError:
    pass


WINS = [(0, 1, 2),
        (3, 4, 5),
        (6, 7, 8),
        (0, 3, 6),
        (1, 4, 7),
        (2, 5, 8),
        (0, 4, 8),
        (2, 4, 6)]


def start():
    board = list(range(1, 10))

    print_board(header="Welcome to Tic-Tac-Toe!")
    print('You may press CTRL+C at any time to quit this game.')
    print('Beware that progress is not saved.')
    print('')

    while True:
        rawplayer = input("Who shall go first \"X\" or \"O\"? > ")
        player = rawplayer.upper()
        if player in 'XO':
            break
        print('Invalid player', rawplayer)

    while set(board) != {'X', 'O'}:
        print_board(board, 'Player {} turn'.format(player))
        turn(board, player)
        if iswin(board, player):
            print_board(board, 'Player {} wins!'.format(player))
            return
        player = 'X' if player == 'O' else 'O'

    print_board(board, 'Game Over!')


def multirun():
    start()
    while True:
        over = input("Would you like to play again? (Y / N) ")
        if over.upper() == "Y":
            start()
        elif over.upper() == "N":
            return
        else:
            print('Invalid input', over)


def print_board(board=None, header=None):
    os.system('cls' if os.name == 'nt' else 'clear')
    if board is None:
        board = [' ']*9
    if header:
        print(header)
    print("""

     {} | {} | {}
    ---|---|---
     {} | {} | {}
    ---|---|---
     {} | {} | {}

    """.format(*board))


def turn(board, player):
    while True:
        location = input("Please enter a location to play (1-9) > ")
        try:
            ind = int(location)-1
        except ValueError:
            print('Invalid input', location)
            continue
        if ind < 0 or ind > 8:
            print('Location', location, 'out of range (1-9)')
            continue
        if board[ind] in ('X', 'O'):
            print('Location', location, 'already occupied')
            continue
        break
    board[ind] = player


def iswin(board, player):
    for win in WINS:
        if all(board[ind] == player for ind in win):
            return True


if __name__ == '__main__':
    multirun()
票数 8
EN

Code Review用户

发布于 2016-10-05 18:03:11

长话短说,

当你感觉自己在重复自己的时候,你就走上了正轨,因为那时你知道有一个更好的解决方案。这就是编程的诡计,让语言为你工作。

在您的例子中,这涉及到if语句,不需要这样的语句。你觉得你能用一个if语句来做吗?当然。要做到这一点,您需要某种循环。由于您在原则上知道需要处理多少值,因此建议您使用for循环。如果你不知道你需要使用多少个值,它建议你应该同时循环。

但是,到目前为止,这在您的代码中是行不通的!因为现在你的每个坐标都是特定于一个变量的。你没有什么可重复的。

当您有许多要处理的值,并且它们对您来说可能是相同的类型时,您应该将它们压缩到某种容器中,这也给您提供了一些可以迭代的东西!将它们放入列表、数据集、集合中,这取决于您所拥有的值类型以及您想要对它们做什么。

我建议您继续使用您的代码,拆卸它,重新组装它,使它越来越短。

错误的线索会把你带到那里。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/143321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档