【问题标题】:Tic Tac Toe isn't showing winner correctly with listsTic Tac Toe 未通过列表正确显示获胜者
【发布时间】:2019-11-05 03:44:08
【问题描述】:

在我的井字游戏中,4 回合后,即使不是,它也会宣布 X(第一个玩家)成为赢家。我不知道我错过了什么,它在检查列时有效,但现在用行却没有。当我用字母调用函数时,我感觉这是一个问题,但我不完全确定。

moves = [["1", "2", "3"],
         ["1", "2", "3"],
         ["1", "2", "3"]]

def win(letter):
  if(moves[0][0] == letter and
     moves[1][0] == letter and
     moves[2][0] == letter):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
  elif(moves[0][1] == letter and
       moves[1][1] == letter and
       moves[2][1] == letter):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
  elif(moves[0][2] == letter and
       moves[1][2] == letter and
       moves[2][2] == letter ):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
  elif(moves[0][0] == letter and
       moves[0][1] == letter and
       moves[0][2]):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
  elif(moves[1][0] == letter and
       moves[1][1] == letter and
       moves[1][2]):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
  elif(moves[2][0] == letter and
       moves[2][1] == letter and
       moves[2][2]):
    print("~~~ " + letter + " WON!!! CONGRATS!!!! ~~~")
    quit()
def playerInput():
  player1 = input("Where do you want to place your X, player 1? (row number, space, number)")
  moves[int(player1[0]) - 1][int(player1[2]) - 1] = "X"
  player2 = input("Where do you want to place your O, player 2? (row number, space, number)")
  moves[int(player2[0]) - 1][int(player2[2]) - 1] = "O"
  boardDraw()
def boardDraw():
  print("1| "+moves[0][0]+" | "+moves[0][1]+" | "+moves[0][2]+" |")
  print(" |---+---+---|")
  print("2| "+moves[1][0]+" | "+moves[1][1]+" | "+moves[1][2]+" |")
  print(" |---+---+---|")
  print("3| "+moves[2][0]+" | "+moves[2][1]+" | "+moves[2][2]+" |")
  win("X")
  win("O")
  playerInput()

print("OK SO....\nPlayer 1 is X\nPlayer 2 is O\nGOOOOO!!")

boardDraw()

【问题讨论】:

  • 提示:比较前三个if的形式和后三个的形式。
  • 顺便说一句,关于实现井字游戏的问题通常会很快进入“需要更多关注”或“基于意见”的领域,因为有很多编写方法,例如获胜检测算法和相当大的争论空间。
  • 真的很有意思,不知道stack-overflow井字游戏社区有这么多争吵!

标签: python


【解决方案1】:

我假设您的部分问题与以下事实有关:在您的某些 if 子句中,您检查前两个正方形或等于 letter,但不检查第三个。 Python 中的大多数对象,除了None0 之类的对象,都将被评估为True。所以如果你的数组中有一个非零数字或一个字符,它将被评估为True。这会导致程序认为玩家在只有两个东西组成的一行时赢了。

另外,你有六个特定的获胜条件,而且肯定比你指定的在井字游戏中获胜的条件要多。我会建议一种更合乎逻辑(和可读性)的方法将获胜场景整合在一起。例如,您可以在一个循环中检查所有水平和垂直获胜条件:

for i in range(3):
    if ((moves[i][0] == moves[i][1] == moves[i][2] == letter) or
         (moves[0][i] == moves[1][i] == moves[2][i] == letter):
        # do win-condition stuff here

最后,我建议检查无效的动作,因为您当前的代码只会让用户覆盖现有的动作。

【讨论】:

  • 谢谢,它的可读性很强。我需要更多地习惯 for 循环,哈哈。现在肯定在做无效动作!
【解决方案2】:

您显然遗漏了 2 个获胜案例:

moves[0][0] == moves[1][1] == moves[2][2]

和:

moves[0][2] == moves[1][1] == moves[2][0]

我宁愿将你的获胜检测函数重写为:

def win(letter) :
    for i in range(3) :  # rows
        if set(moves[i]) == set([letter]) :
            print( 'WIN' )
            quit()
    for x in zip(moves[0], moves[1], moves[2]) :  # columns
        if set(x) == set([letter]) :
            print( 'WIN' )
            quit()

    # you have completely missed the part below...
    if set(moves[i][i] for i in range(3)) == set([letter]) : # one diagonal
        print( 'WIN' )
        quit()
    if set(moves[i][3-i] for i in range(3)) == set([letter]) : # another diagonal
        print( 'WIN' )
        quit()

甚至更紧凑:

def win(letter) :
    possible_wins = [ set(moves[i]) for i in rage(3) ] +  # rows
        [ set(x) for x in zip(moves[0], moves[1], moves[2]) ] +  # columns
        [ set(moves[i][i] for i in range(3)) ] +  # diagonal
        [ set(moves[i][3-i] for i in range(3)) ]  # another diagonal
    if any( p == set([letter]) for p in possible_wins ) :
        print( 'WIN' )
        quit()

【讨论】:

  • set([letter]) 更简洁地写成{letter}
  • @KarlKnechtel 同意,只是不想混淆 OP
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多