【问题标题】:TicTacToe Nobody wins AND overriding player's choicesTicTacToe 没有人会赢并且压倒玩家的选择
【发布时间】:2020-04-27 00:02:39
【问题描述】:

我是一名新程序员,我开始学习 python 并想学习编写井字游戏代码。

游戏继续,但获胜条件和计算机字段选择无法正常工作:它不知道何时停止游戏,有时计算机会选择已经选择的字段,从而覆盖我的选择(如果我尝试执行同样,我得到一个ValueError)。

对于获胜算法,我不想手动遍历所有选项,所以我使用了集合。我创建了一个包含所有获胜条件的集合。在迭代每个子集(行、列和对角线)时,我检查这是否是玩家/计算机位置的子集。

问题是:它不起作用。如果我尝试做任何事情,我会得到一个 ValueError: list.remove(x) x not in list。我有时会在删除 playerChoice 的行或计算机上的行上收到此错误。 如上所述的另一个问题是计算机可以覆盖我的选择。

我认为问题在于从一组中删除元素并将它们添加到另一组,但我找不到解决此问题的方法

代码如下:

import random

board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
playerSymbol = ""
playerPosition = []
aiSymbol = ""
aiPosition = []
possiblePositions = [0, 1, 2, 3, 4, 5, 6, 7, 8]
turn = 0


def drawBoard():
    print(board[0] + " | " + board[1] + " | " + board[2])
    print("___" + "___" + "___")
    print(board[3] + " | " + board[4] + " | " + board[5])
    print("___" + "___" + "___")
    print(board[6] + " | " + board[7] + " | " + board[8])


def choice():
    global playerSymbol
    global aiSymbol

    answer = input("What do you want to play as? (type x or o) ")

    if answer.upper() == "X":
        playerSymbol = "X"
        aiSymbol = "O"
    else:
        playerSymbol = "O"
        aiSymbol = "X"


def won():
    winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}]

    for position in winningPositions:
        if position.issubset(playerPosition):
            print("Player Wins :)")
            return True
        elif position.issubset(aiPosition):
            print("AI wins :(")
            return True
        else:
            return False


def play():
    global turn
    choice()

    while not won():
        if turn % 2 == 0:
            pos = int(input("Where would you like to play? (0-8) "))
            possiblePositions.remove(pos)
            playerPosition.append(pos)
            board[pos] = playerSymbol
            turn += 1
            drawBoard()
        else:
            aiTurn = random.randint(0, len(possiblePositions) - 1)
            possiblePositions.remove(possiblePositions[aiTurn])
            aiPosition.append(aiTurn)
            board[aiTurn] = aiSymbol
            turn += 1
            print("\n")
            print("\n")
            drawBoard()
    else:
        print("Thanks for playing :)")


play()

我愿意接受各种改进我的代码的建议和方法。 提前感谢并保持健康, 克里斯蒂

【问题讨论】:

    标签: python tic-tac-toe


    【解决方案1】:

    两件事:

    1. 轮到 AI 时,您正在生成“最多可用位置的长度”。您需要生成“可用职位之一”。

    更改这些行:

        aiTurn = random.randint(0, len(possiblePositions) - 1)
        possiblePositions.remove(possiblePositions[aiTurn])
    

        aiTurn = random.choice(possiblePositions)
        possiblePositions.remove(aiTurn)
    
    1. won() 中,您需要遍历所有可能的组合,直到与True 进行比较。但是,您在第一次比较之后返回 true 或 false。将return False 移到循环外:

    改变

        for position in winningPositions:
            if position.issubset(playerPosition):
                print("Player Wins :)")
                return True
            elif position.issubset(aiPosition):
                print("AI wins :(")
                return True
            else:
                return False
    

        for position in winningPositions:
            if position.issubset(playerPosition):
                print("Player Wins :)")
                return True
            elif position.issubset(aiPosition):
                print("AI wins :(")
                return True
    
        return False
    

    【讨论】:

    • 我实现了它,它工作了谢谢 :) 如果我知道 .choice 函数,我会更早使用它
    【解决方案2】:

    首先,最好打印整个临时字段和带有输入数字的字段,因为从 0-8 中选择框不舒服。做成这样,真的很容易理解(例如):

    [ ][ ][X]    [1][2][3]
    [ ][ ][0]    [4][5][6]
    [X][0][X]    [7][8][9]
    Choose you box.
    

    其次,你必须检查这一行

    aiTurn = random.randint(0, len(possiblePositions) - 1)
    

    您不检查随机值,但可以稍后移动。因为这个ai可以选择不为空的字段。像这样:

    #for example
    if aiTurn in PosiblePositions:
        make_move()
    else:
        generate_new_move()
    

    第三,当你试图删除一个不在列表中的值时,它会导致 ValueEror:

    a = [1, 2, 3]
    a.remove(4)
    
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ValueError: list.remove(x): x not in list
    

    【讨论】:

      【解决方案3】:

      有几件事可以尝试:

      • play() 中,aiTurnpossiblePositions 中棋盘位置的索引,因此您应该执行pos = possiblePositions[aiTurn]、THEN possiblePositions.remove(pos)aiPosition.append(pos)board[pos] = aiSymbol 之类的操作。现在你正在混合棋盘位置和索引。

      • 不过,这可能是一种令人困惑的编码方式,恕我直言,最好只维护棋盘(没有玩家/ai 位置列表),并以此为基础win()。例如,初始化board = [0,0,0,0,0,0,0,0,0],然后为X 设置board[pos] = 1,为O 设置board[pos] = -1。然后您的win() 可以检查行/列/诊断的总和为 3 或 -3 的任何内容。

      • 如果你这样做,将需要更多的工作来让计算机移动,比如pos = random.choice([i for i,p in enumerate(board) if p==0]) .. 但它会节省你在其他地方的工作

      • 你需要一些逻辑来解释平局/猫游戏

      • 我认为这里没有必要使用global,这些变量已经具有全局范围并且应该可以在每个函数中访问。

      希望有帮助!

      【讨论】:

      • 确实如此 :) 我之前没有想过这种编码,但我想它可能会在让它看起来更好的时候派上用场
      • 顺便问一下:你对平局有什么建议?我尝试了整个场地被占用的情况(len(possiblePositions)== 0),但如果我在最后一步获胜,这无济于事,因为它仍然显示平局......请帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 2020-07-16
      • 1970-01-01
      相关资源
      最近更新 更多