Python - 确定Tic-Tac-Toe获胜者

时间:2016-10-07 17:34:57

标签: python arrays loops boolean break

我正在尝试编写一个代码来确定一个井字游戏的赢家。 (这是为了大学任务)

我写了以下函数:

  

此代码仅检查水平线,我没有添加其余的。我觉得这需要一些硬编码。

def iswinner(board, decorator):
    win = True
    for row in range(len(board)):
        for col in range(len(board)):
            if board[row][col] == decorator:
                win = True
            else:
                win = False
                break

其中“board”是大小为n ^ 2的2D数组,“decorator”是“X”或“O”值

我希望实现的是该函数循环遍历2D数组的行。然后循环遍历每行中的值。如果该元素与“装饰器”匹配,则它继续并检查下一个但如果不匹配,则它从第一个循环中断并转到下一行。它会在同一行中找到n个元素之前执行此操作。然后它会给出bool值为True,否则为False。

代码似乎没有这样做,即使我检查了下面的“板”,它给了我一个“真”的输出

check_list = [['O', 'X', 'X'],
              ['O', 'X', 'O'],
              ['O', 'X', 'X']]

非常感谢你!

最佳, 赛义德

6 个答案:

答案 0 :(得分:3)

您可以只创建一组每行,并检查其长度。如果它只包含一个元素,那么游戏就赢了。

def returnWinner(board):
    for row in board:
        if len(set(row)) == 1:
            return row[0]
    return -1

如果有一行“O”,则返回“O”,如果有一行“X”,则返回“X”,否则返回-1。

以下是完整的Tic-Tac-Toe检查器的代码,应该不难理解,但请不要犹豫:

import numpy as np

def checkRows(board):
    for row in board:
        if len(set(row)) == 1:
            return row[0]
    return 0

def checkDiagonals(board):
    if len(set([board[i][i] for i in range(len(board))])) == 1:
        return board[0][0]
    if len(set([board[i][len(board)-i-1] for i in range(len(board))])) == 1:
        return board[0][len(board)-1]
    return 0

def checkWin(board):
    #transposition to check rows, then columns
    for newBoard in [board, np.transpose(board)]:
        result = checkRows(newBoard)
        if result:
            return result
    return checkDiagonals(board)


a = [['X', 'A', 'X'],
     ['A', 'X', 'A'],
     ['A', 'X', 'A']]

print(checkWin(a))

请注意,无论您选择放置在井字游戏中的符号(“O”和“X”与“bloop”&“!”一样精细),以及任何尺寸的网格,只要它是一个正方形。

答案 1 :(得分:2)

执行此操作的一种方法是创建所有可能的索引组合的集合(生成器函数甚至更好)以检查胜利。然后遍历这些索引组合并检查它们是否都包含相同的值,如果是,那么它就是胜利。

def win_indices(n):
    # Rows
    for r in range(n):
        yield [(r, c) for c in range(n)]
    # Columns
    for c in range(n):
        yield [(r, c) for r in range(n)]
    # Diagonal top left to bottom right
    yield [(i, i) for i in range(n)]
    # Diagonal top right to bottom left
    yield [(i, n - 1 - i) for i in range(n)]


def is_winner(board, decorator):
    n = len(board)
    for indexes in win_indices(n):
        if all(board[r][c] == decorator for r, c in indexes):
            return True
    return False

答案 2 :(得分:1)

def check_winner(board,mark):
    return((board[1]==mark and board[2]== mark and board[3]==mark )or #for row1 

            (board[4]==mark and board[5]==mark and board[6]==mark )or #for row2

            (board[7]==mark and board[8]==mark and board[9]==mark )or #for row3

            (board[1]==mark and board[4]==mark and board[7]== mark )or#for Colm1 

            (board[2]==mark and board[5]==mark and board[8]==mark )or #for Colm 2

            (board[3]==mark and board[6]==mark and board[9]==mark )or #for colm 3

            (board[1]==mark and board[5]==mark and board[9]==mark )or #daignole 1

            (board[3]==mark and board[5]==mark and board[7]==mark )) #daignole 2

答案 3 :(得分:0)

一个单元格共有3种状态

  1. 0如果尚未填充(游戏有可能在5次移动中结束)
  2. 1如果填充了' X'
  3. -1如果填充了' O'
  4. 我将扩展@EfferLagan回答

    def checkRows(board):
    for row in board:
        if (len(set(row)) == 1) and (row[0] != 0):
            return row[0]
    return 999
    
    def checkDiagonals(board):
        if (len(set([board[i][i] for i in range(len(board))])) == 1) and (board[0][0] != 0):
            return board[0][0]
        if (len(set([board[i][len(board)-i-1] for i in range(len(board))])) == 1) and (board[0][0] !=0):
            return board[0][len(board)-1]
        return 999
    
    def checkWin(board):
        #transposition to check rows, then columns
        for newBoard in [board, np.transpose(board)]:
            result = checkRows(newBoard)
            if result:
                return result
        return checkDiagonals(board)
    
    randomInput=[
        [0,0,1],
        [-1,-1,1],
        [0,0,0]
    ]
    

    你有3个输出1,-1和999(这意味着既不赢)     checkWin(randomInput)

答案 4 :(得分:0)

您可以通过创建产生全部8条线(3行,3列和2条对角线)的generatorlines(),然后检查是否有任何一行仅由一条线组成来完成此操作元素,而该元素不是None

一旦你有类似的东西

board = [
    [ 'o', 'x', None], 
    [None, 'x', None], 
    [None, 'x',  'o']
]

执行以下操作:

def _lines(board):
    yield from board  # the rows
    yield [board[i][i] for i in range(len(board))]  # one of the diagonals

def lines(board):
    yield from _lines(board)
    # rotate the board 90 degrees to get the columns and the other diagonal
    yield from _lines(list(zip(*reversed(board))))

def who_won(board):
    for line in lines(board):
        if len(set(line)) == 1 and line[0] is not None:
            return line[0]
    return None  # if we got this far, there's no winner

对于我在上面给出的董事会,list(lines(board))将返回

[['o', 'x', None], 
 [None, 'x', None], 
 [None, 'x', 'o'], 
 ['o', 'x', 'o'], 
 (None, None, 'o'), 
 ('x', 'x', 'x'), 
 ('o', None, None), 
 [None, 'x', None]]
这些元素中的

3个是元组而不是列表,因为zip返回元组。您可以使用列表推导来转换它们,有关如何操作请参见this question,以及有关zip(*reversed(some_list))的操作的更多详细信息。

然后,只需将每个元素转换为set并检查该唯一元素is not None,即可检查每个元素是否只有一个唯一元素。

这适用于任何尺寸的井字游戏板,而不仅仅是3×3。

答案 5 :(得分:-1)

  def check_winer(board):
    #used to check the winner in row
    for row in range(0,3):
        if board[row][0]==board[row][1]==board[row][2] and board[row][0] != 0:
            if chance=='o':
                print("x is winner")
            elif chance=='x':
                print("o is winner")
    #used to check thw winner in column
    for col in range(0,3):
        if board[0][col]==board[1][col]==board[2][col] and board[0][col] != 0:
            if chance=='o':
                print("x is winner")
            elif chance=='x':
                print("o is winner")
    #used to check winner in one diagonal
    if board[0][0]==board[1][1]==board[2][2] and board[0][0] !=0:
        if chance=='o':
            print('x is winner')
        elif chance=='x':
            print("o is winner")
    #used to check winner in another diagonal
    if board[0][2]==board[1][1]==board[2][0] and board[0][2]!=0:
        if chance=='o':
            print("x is winner")
        elif chance=='x':
            print("o is winner")

两次在井字游戏中检查获胜者,即可使用此功能。 您必须先创建像这样的2d数组:

board=[[0,0,0],
      [0,0,0],
      [0,0,0]]

因此,当它是x时,请单击该框并相对于该框将数组中的值更改为1。 并在每次点击中将机会从x更改为o,并将机会从o更改为x。 如果是o,请相对于坐标将数组中的值更改为2。 每次单击该框以将x或o放置到位时,都必须调用此函数。

将机会从x更改为o或从o更改为x后,请确保调用此函数。 因为如果不这样做,此功能将给出错误的输出。

例如,如果此板为:

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

然后此函数将输出为:

o is the winner