如何创建一个公式来检查谁赢得了一个没有很多if语句的tictactoe游戏?

2024-04-20 11:35:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的代码,觉得它可以更有效。这意味着这是3x3板,可以手动完成,但如果它是一个30x30板或更大?你知道吗

x = [[1, 2, 0],[2, 1, 0],[2, 1, 0]]

for y in range (3):
    if ((x[0][0] == x[1][0] == x[2][0] == y) or

    (x[0][1] == x[1][1] == x[2][1] == y) or

    (x[0][2] == x[1][2] == x[2][2] == y) or

    (x[0][0] == x[0][1] == x[0][2] == y) or

    (x[1][0] == x[1][1] == x[1][2] == y) or

    (x[2][0] == x[2][1] == x[2][2] == y) or

    (x[0][0] == x[1][1] == x[2][2] == y) or

    (x[0][2] == x[1][1] == x[2][0] == y)):

        if y==1:
            print('Player 1 won!!!')
        if y==2:
            print('Player 2 won!!!')
        if y==0:
            print('Nobody won')

有没有办法让状况更好?你知道吗


Tags: or代码inforifrange手动player
2条回答

如果您不介意导入numpy,这将适用于任何正方形网格和任意数量的播放器:

import numpy as np

def check(arr):
    def check_one_dim(arr):
        for player in np.arange(Nplayer)+1:
        # instead of Nplayer you could write arr.max()
            arrtest = arr == player
            s = arrtest.astype(int).prod(axis=0)
            t = arrtest.diagonal().astype(int).prod()
            if (s == 1).any() or t == 1:
                return player
        else:
            return 0
    return max(check_one_dim(arr), check_one_dim(arr[::-1].T))

Nplayer = 2
x = np.array([[1, 2, 0],[2, 1, 0],[2, 1, 0]])
winner = check(x)
if winner > 0:
    print("Player {}").format(winner)
else:
    print("No winner")

我不确定它是否更快,但“如果”更少:

你可以使用这样的函数生成器:

def cell_owner(player):
    """returns a function which can check if a cell belongs to provided player"""
    def wrapped(cell):
        return player == cell
    return wrapped

所以您可以调用cell_owner(1)来获得一个函数,该函数接受一个值并检查它是否为1。 这似乎没用,但使用这样的函数,您可以使用allmap检查一行中的整个单元格组:

# will return True if each cell in <cells_group> belong to <player>
all(map(cell_owner(<player>), <cells_group>)

在此之前,您可以准备一个可获胜的单元格组列表,然后对每个组应用all/map函数迭代该列表,以确定是否有玩家获胜。你知道吗

下面是一个完整的示例,其中包含一些用于测试pupose的额外函数:

import random


def gen_random_grid(size):
    """just for test purpose: generate a randomly filled grid"""
    return [[random.randint(0, 2) for col in range(size)] for row in range(size)]

def print_grid(grid):
    """just for test purpose: prints the grid"""
    size = len(grid)
    row_sep = "+{}+".format("+".join([" -"] * size))
    row_fmt = "|{}|".format("|".join([" {} "] * size))
    print(row_sep)
    for row in grid:
        print(row_fmt.format(*row))
        print(row_sep)

def cell_owner(player):
    """returns a function which can check is a cell belongs to provided player"""
    def wrapped(cell):
        return player == cell
    return wrapped

def get_winner(grid):
    """determines if there is a winner"""
    size = len(grid)

    # prepare list of potentially winning cells groups
    cells_groups_to_check = grid[:]  # rows
    cells_groups_to_check += [[grid[row][col] for row in range(size)]
                              for col in range(size)] #cols
    cells_groups_to_check.append(
        [grid[index][index] for index in range(size)])  # diag 1
    cells_groups_to_check.append(
        [grid[index][size - 1 - index] for index in range(size)])  # diag 2

    winner = 0
    for y in range(1, 3):  # 0 is not a player, no need to test it
        # for each player...
        for group in cells_groups_to_check:
            # ... check if a cells group is complete
            if (all(map(cell_owner(y), group))):
                winner = y
                break
        if winner: break
    return winner

# generate some random grids of different sizes
TEST_GRIDS = [gen_random_grid(3) for _ in range(3)]
TEST_GRIDS += [gen_random_grid(2) for _ in range(3)]
TEST_GRIDS += [gen_random_grid(4) for _ in range(3)]

# demonstration
for grid in TEST_GRIDS:
    print_grid(grid)
    print("Winner is {}".format(get_winner(grid)))

注意:此代码适用于任何大小的正方形网格。你知道吗

相关问题 更多 >