【问题标题】:tictactoe iteration issue. Function errortictactoe 迭代问题。函数错误
【发布时间】:2015-08-03 21:31:33
【问题描述】:

我是编程新手(自学大约 2 个月)。我正在尝试创建一个井字游戏,并以此为契机练习使用函数和传递参数。

我已经完成了我想要工作的大部分工作(现在我将添加 AI 和计算机对手),但是当其中一个人类玩家获胜时,会调用 endgame() 函数,但它没有按预期工作。它以某种方式调用自己,您必须在程序终止之前说 N 结束游戏三次。我看不到这棵树的木头,因此我们将不胜感激。

我知道我的一些编码不会很好,所以请不要拖钓。

谢谢

肖恩

def start():

    choices = [" "," "," "," "," "," "," "," "," "]
    while checkwin(choices)==False:
        board(choices)
        getchoice(choices)

def board(choices):

    print("+---+---+---+")
    print("+ "+choices[0]+" + "+choices[1]+" + "+choices[2]+" +")
    print("+---+---+---+")
    print("+ "+choices[3]+" + "+choices[4]+" + "+choices[5]+" +")
    print("+---+---+---+")
    print("+ "+choices[6]+" + "+choices[7]+" + "+choices[8]+" +")
    print("+---+---+---+")

def endgame(winner):

    print("The winner is "+ winner)
    playagain=input("Another game? Y/N")
    playagain = playagain.upper()
    if playagain == "N":
        print("Thanks, hope to see you again soon.")
    else:
        start()


def getchoice(choices):

    userchoice = int(input ("Where would you like to put your X?"))
    index = userchoice-1
    while choices[index]!=" ":
        userchoice = int(input ("That space is taken. Where would you like to put your X?"))
        index = userchoice-1

    choices[index]="X"
    board(choices)
    if checkwin(choices)==False:
        userchoice = int(input ("Where would you like to put your O?"))
        index = userchoice-1
        while choices[index]!=" ":
            userchoice = int(input ("That space is taken. Where would you like to put your O?"))
            index = userchoice-1

        choices[index]="O"
    checkwin(choices)
    return choices

def checkwin (c):

    if checkwin1(c)==False:
        if checkwin2 (c)==False:
            return False
        else:
            endgame("Player 2")
    else:
        endgame("Player 1")

def checkwin1(c):   

    return ((c[0]=="X" and c[1]=="X" and c[2]=="X") or
(c[3]=="X"and c[4]=="X" and c[5] =="X") or
(c[6]=="X"and c[7]=="X" and c[8] =="X") or
(c[0]=="X"and c[3]=="X" and c[6] =="X" )or
(c[1]=="X"and c[4]=="X" and c[7] =="X") or
(c[2]=="X"and c[5]=="X" and c[8] =="X") or
(c[0]=="X"and c[4]=="X" and c[8] =="X") or
(c[6]=="X"and c[4]=="X" and c[2] =="X"))

def checkwin2(c):   

    return ((c[0]=="O" and c[1]=="O" and c[2]=="O") or
(c[3]=="O"and c[4]=="O" and c[5] =="O") or
(c[6]=="O"and c[7]=="O" and c[8] =="O") or
(c[0]=="O"and c[3]=="O" and c[6] =="O" )or
(c[1]=="O"and c[4]=="O" and c[7] =="O") or
(c[2]=="O"and c[5]=="O" and c[8] =="O") or
(c[0]=="O"and c[4]=="O" and c[8] =="O") or
(c[6]=="O"and c[4]=="O" and c[2] =="O"))

start()   

【问题讨论】:

  • endgame() 在输入“N”时不会调用自己,甚至不会间接调用。相反——其他一些代码不止一次调用endgame()
  • 与问题无关:您可能想考虑一下在没有玩家获胜的情况下如何终止游戏的情况。

标签: function python-3.x parameters


【解决方案1】:

让我们假设 X 赢了 3 次(因为这可能是导致它“结束”的原因)。

然后您在getchoice() 内到达if checkwin(choices)==False:, 'checkwin()' 愉快地调用endgame()endgame() 返回,然后getchoice() 继续执行。

getchoice() 结束时,再次调用checkwin(),结果相同。

getchoice() 返回后,我们在start() 中返回while checkwin(choices)==False:,再次得到相同的结果。

另请注意,如果您实际上连续玩了多个游戏,您会看到这种情况发生的次数更多。

也尝试让 O 获胜,我认为在这种情况下您只需对提示说两次不。

编辑:

class TicTacToeGame:
    INCOMPLETE = 0
    WINNER_PLAYER_1 = 1
    WINNER_PLAYER_2 = 2
    DRAW = 3

    SYMBOLS=["X","O"," "]

    def __init__(self,player_1, player_2):
        self.board = [[-1]*3,[-1]*3,[-1]*3]
        self.players = [player_1,player_2]
        self.current_turn = 0;

    def advance(self):
        if self.calcGameState() != TicTacToeGame.INCOMPLETE:
            return
        while True:
            x,y = self.players[self.current_turn].getMove();
            if x < 0 or x > 2 or y < 0 or y>2 :
                continue
            if self.board[y][x] == -1:
                break
        self.board[y][x] = self.current_turn
        self.current_turn += 1
        self.current_turn %= 2

    def stringify(self):
        re = ""
        fr = True
        for row in self.board:
            if fr:
                fr=False
            else:
                re+= "\n" + "---+" * 2 + "---\n"
            fe = True
            for el in row :
                if fe:
                    fe = False;
                else:
                    re += "|"
                re += " " + TicTacToeGame.SYMBOLS[el] + " "
        return re

    def calcGameState(self):
        for i in range(0,3):
            #col
            if all(self.board[i][j] == self.board[i][0] for j in range(0,3)) and self.board[i][0] != -1:
                return self.board[i][0] + 1
            #row
            if all(self.board[j][i] == self.board[0][i] for j in range(0,3)) and self.board[0][i] != -1:
                return self.board[0][i] + 1
        if all(self.board[i][i] == self.board[0][0] for i in range(0,3)) and self.board[0][0] != -1:
            return self.board[0][0] + 1
        if all(self.board[i][2-i] == self.board[0][2] for i in range(0,3)) and self.board[0][2] != -1:
            return self.board[0][2] + 1
        if all(self.board[i][j] != -1 for i in range(0,3) for j in range(0,3)):
            return TicTacToeGame.DRAW
        return TicTacToeGame.INCOMPLETE

    def stringResult(self):
        res = self.calcGameState()
        if res == TicTacToeGame.INCOMPLETE:
            return "Incomplete"
        if res == TicTacToeGame.DRAW:
            return "Draw"
        return "Player " + self.SYMBOLS[res-1] + " Won!"

class HumanPlayer:
    def __init__(self):
        self.board = None

    def setGame(self,game):
        self.game = game

    def getMove(self):
        print(self.game.stringify())
        print("Current turn is: " + self.game.SYMBOLS[self.game.current_turn])
        print("enter row for move")
        y = input()
        print("enter col for move")
        x = input()
        return int(x)-1,int(y)-1

def playAgain():
    playagain=input("Another game? Y/N\n > ")
    playagain = playagain.upper()
    if playagain == "N":
        print("Thanks, hope to see you again soon.")
        return False
    return True

while True:
    p = HumanPlayer()
    t = TicTacToeGame(p,p)
    p.setGame(t)

    while t.calcGameState() == TicTacToeGame.INCOMPLETE:
        t.advance()
    print(t.stringResult())
    if not playAgain():
        break;

【讨论】:

  • 当 O 获胜时,单回声(而不是双回声)是正确的。当我下载 OP 的代码并试图重现该错误时,我只需要说两次“N”。我注意到checkwin()getchoice() 的末尾,这似乎足以解释为什么我看到了回声,但我还没有弄清楚为什么 OP 必须这样做三遍。很好的调试工作。
  • 我已尝试根据上述信息修改我的程序,但仍达不到要求。我可以让程序每次使用 O 结束玩家,但如果我扮演玩家 X 仍然需要选择结束程序两次。如上所述,如果我玩多个游戏,我必须结束游戏更多的时间,例如如果我玩两场比赛,我必须选择三场结束比赛。还有什么想法吗?
  • 确保退出的简单方法是使用 sys.exit - docs.python.org/2/library/sys.html#sys.exit - 只要你想退出。但是,我建议您重新考虑您对这个程序的方法,并可能在此过程中学到一些东西。
  • @ShaunRogers 或者,如果您想看到一种可能会这样做的方法:repl.it/BCIO 如果您对其中发生的事情有任何疑问,请告诉我,但请尝试研究任何首先你自己还不知道的概念。 (很快也将在答案编辑中编码)。这只是一个示例,在很多方面并不完美,因此请在阅读时牢记这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
相关资源
最近更新 更多