【问题标题】:TicTacToe code to check the state of the board not workingTicTacToe 代码检查板的状态不工作
【发布时间】:2021-08-26 08:50:27
【问题描述】:

我做了一个算法来检查是哪个玩家赢得了比赛,或者是平局还是比赛还没有结束,但它不适用于某些测试用例。

我不知道我的代码有什么问题。但它不起作用,所以我认为我的算法或代码本身有些问题。

所以我的算法基本上是:

  • 将玩家 1 和玩家 2 的动作分开
  • 如果是 return 'player1',则检查玩家 1 的走法是否在获胜走法中
  • 如果返回'player2',则检查玩家2的走法是否在获胜走法中
  • 如果没有获胜者,则检查移动数是否等于 9。如果是,则返回 'tie'
  • 否则,如果移动次数小于 9,则返回“不确定”

代码如下:

def match(a1,a2):
    a1.sort()
    for solution in a2:
        if a1 == solution:
            return True
    return False

def ticTacToeWinner(moves, n):
    # --- Variables ---
    p1 = []
    p2 = []
    winning_moves = [
        [[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]],
        [[1,0],[2,1],[3,1]],
        [[0,0],[1,1],[2,2]],
        [[0,2],[1,1],[2,0]],
    ]

    winner = None
    
    # --- Loops ---
    for i in range(1,n+1): # separate the moves for each player
        if i % 2 == 0:
            p2.append(moves[i-1])
        else:
            p1.append(moves[i-1])

    # --- Conditionals ---
    if len(p1) >= 3: # check if the player1 has more than 3 moves
        if match(p1,winning_moves) == True: # check if the moves of player1 is in the winning moves
            winner = 'player1' # winner is player 1
            return winner

    if len(p2) >= 3: # check if the player2 has more than 3 moves
        if match(p2,winning_moves) == True: # check if the moves of player 2 is in the winning moves
            winner = 'player2' # winner is player 2
            return winner

    if not winner: # there are no winners
        if n == 9: # board is full so it's draw
            return 'draw'
        elif n < 9: # board is not full
            return 'uncertain'

这段代码是我对这个问题的解决方案: https://www.codingninjas.com/codestudio/problems/tic-tac-toe-winner_1214545?topList=top-apple-coding-interview-questions

该代码仅适用于那里的 2 个测试用例,其他所有测试用例都不正确

输入输出示例:

ticTacToeWinner([[0,0],[2,2],[0,1],[1,1],[0,2]],5) -> 'player1'

因为玩家 1 的走法是:[[0,0],[0,1],[0,2]],这在棋盘顶部形成了三个 X

顶部的匹配功能是检查玩家的动作是否在获胜动作表中。

这里是不能使用代码的测试用例之一:

5
9
2 0
0 1
1 1
1 0
1 2
0 0
2 1
2 2
0 2
4
1 2
1 0
2 0
1 1
1
2 0
9
2 0
1 2
0 1
0 0
0 2
2 1
2 2
1 1
1 0
3
0 2
2 0
0 0

【问题讨论】:

  • 这是该算法的面试问题链接:codingninjas.com/codestudio/problems/…
  • 请准确说明代码出错的地方
  • 你的代码对于不知道它的人来说很难阅读,因为我们不知道变量是什么样的。请至少在函数定义上方的 cmets 中给出 a1, a2moves, n 的示例值。
  • 另外请指定不起作用的测试用例,输出是什么,以及您期望它是什么。
  • 该网站需要一个帐户,而一个帐户需要从一组封闭的大学中进行选择,所以我不会创建一个帐户。我们需要这里的所有信息来重现问题。

标签: python algorithm tic-tac-toe


【解决方案1】:

这些是一些问题:

  • winning_moves 有一个完全错误的行,其中还有一个 3 -- 这是一个无效索引。

    变化:

    [[1,0],[2,1],[3,1]],
    

    到:

    [[0,2],[1,2],[2,2]],
    
  • len(p1) 大于 3 时,您将永远找不到胜利,因为winning_moves 没有具有这种大小的条目。但很明显,有可能是一场胜利

  • 即使len(p1)等于等于 3,您仍然可能会错过一场胜利,因为移动的顺序可能与 winning_moves 中的不同。

  • 没问题,但elif n &lt; 9 可以只是else,因为n 没有其他可能的值。

您真的应该采取不同的方法:在 3x3 棋盘(2D 列表)上下棋,然后使用winning_moves 查看那些获胜位置的棋子。如果事实证明它们都是玩家 1 的 3 步棋,那么您就知道玩家 1 赢得了比赛。

所以你的函数应该是这样的:

def ticTacToeWinner(moves, n):
    winning_moves = [
        [[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]],  # was wrong
        [[0,0],[1,1],[2,2]],
        [[0,2],[1,1],[2,0]],
    ]

    # create a board:
    board = [
        [".", ".", "."],
        [".", ".", "."],
        [".", ".", "."],
    ]

    # play the moves on the board:
    for i, (row, col) in enumerate(moves):
        board[row][col] = "12"[i % 2]  # store the player's number in this cell
 
    # check who has played on the winning patterns
    for winning_line in winning_moves:
        played = [board[row][col] for row, col in winning_line]
        if played[0] != "." and played[0] == played[1] == played[2]:
            return "player" + played[0]

    if n == 9: # board is full so it's draw
        return 'draw'
    else: # board is not full
        return 'uncertain'

【讨论】:

  • 请注意,比较运算符如== 可以在python 中链接,这与几乎所有其他编程语言相反; played[1] == played[0] and played[2] == played[0] 可以缩写为 played[0] == played[1] == played[2]
  • 当然,@Stef。已更新。
【解决方案2】:

我很确定你的问题之一是你没有处理 more 超过 3 个动作的情况...... 我建议将单个“移动”的类型更改为可散列的元组。那么,你就可以使用这个优雅的match 代码了:

def match(player_moves_list: List[tuple], winning_moves:List[List[tuple]]):
    for solution in winning_moves:
        if set(solution).issubset(player_moves):
            return True
    return False

要将列表元素更改为元组元素,只需将括号变为括号:

winning_moves = [
    [(0,0),(0,1),(0,2)],
    ...,
    [(0,2),(1,1),(2,0)],
]

【讨论】:

  • 还是和以前一样还是不行
猜你喜欢
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多