Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成糖果粉碎类游戏的初始游戏板_Python_Algorithm_Numpy_Matrix_Nested Lists - Fatal编程技术网

Python 生成糖果粉碎类游戏的初始游戏板

Python 生成糖果粉碎类游戏的初始游戏板,python,algorithm,numpy,matrix,nested-lists,Python,Algorithm,Numpy,Matrix,Nested Lists,我需要实现一个功能, 返回满足以下要求的6乘6矩阵: 棋盘上的36个数字必须是9个一、9个二、9个三和9个四 任何行或列不得包含3个或更多相同编号的直接邻居 函数返回值不能是常量 显然,不允许使用预先计算的答案 正确答案: [[3, 2, 4, 1, 3, 2], [2, 2, 1, 1, 4, 4], [4, 4, 1, 3, 3, 2], [4, 1, 3, 2, 2, 4], [3, 1, 2, 4, 3, 1], [3, 3, 1, 1

我需要实现一个功能, 返回满足以下要求的6乘6矩阵:

  • 棋盘上的36个数字必须是9个一、9个二、9个三和9个四
  • 任何行或列不得包含3个或更多相同编号的直接邻居
  • 函数返回值不能是常量
  • 显然,不允许使用预先计算的答案
正确答案:

    [[3, 2, 4, 1, 3, 2],
    [2, 2, 1, 1, 4, 4],
    [4, 4, 1, 3, 3, 2],
    [4, 1, 3, 2, 2, 4],
    [3, 1, 2, 4, 3, 1],
    [3, 3, 1, 1, 2, 4]]

   [[3, 3, 1, 2, 2, 4],
    [1, 1, 3, 3, 2, 4],
    [4, 4, 2, 1, 1, 3],
    [2, 2, 3, 4, 4, 1],
    [4, 4, 1, 1, 2, 2],
    [3, 1, 2, 3, 3, 4]]
错误答案:

    [[3, 3, 3, 2, 2, 4],
    [1, 1, 1, 3, 2, 4],
    [4, 4, 2, 1, 1, 3],
    [2, 2, 3, 4, 4, 1],
    [4, 4, 1, 1, 2, 2],
    [3, 1, 2, 3, 3, 4]]

   [[3, 3, 1, 2, 2, 4],
    [1, 1, 2, 3, 2, 4],
    [4, 4, 1, 1, 2, 3],
    [2, 2, 3, 4, 4, 1],
    [4, 4, 1, 1, 2, 2],
    [3, 1, 2, 3, 3, 4]]
不必太担心学术时间/空间的复杂性。更多地关注工程的观点。有什么好主意吗

  • 创建一个大小为36的数组,并用所需的值=>[1,1,1…4,4,4]填充它

  • 应用Fisher-Yates shuffle在O(n)中创建该数组的置换

  • 检查“一行3”规则并交换一个随机值(如果需要),再次检查,直到网格中没有该值


  • 这应该行得通。请注意,此解决方案只生成一个随机板,检查条件是否成立,如果不成立,则生成另一个,因此不是最优雅的解决方案

    代码:

    from random import shuffle
    
    def check_board(board):
        for row in board:
            if check_list(row):
                return False
        for i in range(len(board[0])):
            col = [row[i] for row in board]
            if check_list(col):
                return False
        return True
    
    def check_list(lst):
        return any(lst[i]==lst[i+1] and lst[i]==lst[i+2] for i in range(len(lst)-2))
    
    board = [[]]
    
    while check_board(board):
        board = [1,2,3,4]*9
        shuffle(board)
        board = [board[i:i + 6] for i in range(0, len(board), 6)]
    
    print(board)
    
    [[3, 2, 4, 3, 3, 2],
     [1, 1, 2, 3, 1, 3],
     [1, 3, 3, 2, 2, 2],
     [4, 4, 1, 4, 1, 2],
     [1, 1, 4, 4, 2, 4],
     [2, 4, 4, 3, 3, 1]]
    
    [[2, 3, 4, 1, 4, 1],
     [3, 4, 1, 1, 3, 4],
     [3, 1, 4, 1, 3, 4],
     [3, 4, 2, 4, 2, 1],
     [2, 1, 4, 2, 3, 2],
     [2, 2, 1, 3, 3, 2]]
    
    生成的示例板:

    from random import shuffle
    
    def check_board(board):
        for row in board:
            if check_list(row):
                return False
        for i in range(len(board[0])):
            col = [row[i] for row in board]
            if check_list(col):
                return False
        return True
    
    def check_list(lst):
        return any(lst[i]==lst[i+1] and lst[i]==lst[i+2] for i in range(len(lst)-2))
    
    board = [[]]
    
    while check_board(board):
        board = [1,2,3,4]*9
        shuffle(board)
        board = [board[i:i + 6] for i in range(0, len(board), 6)]
    
    print(board)
    
    [[3, 2, 4, 3, 3, 2],
     [1, 1, 2, 3, 1, 3],
     [1, 3, 3, 2, 2, 2],
     [4, 4, 1, 4, 1, 2],
     [1, 1, 4, 4, 2, 4],
     [2, 4, 4, 3, 3, 1]]
    
    [[2, 3, 4, 1, 4, 1],
     [3, 4, 1, 1, 3, 4],
     [3, 1, 4, 1, 3, 4],
     [3, 4, 2, 4, 2, 1],
     [2, 1, 4, 2, 3, 2],
     [2, 2, 1, 3, 3, 2]]
    

    回溯显然可以达到目的。另一种方法是随机生成一个,然后每三行“挤压”一次,然后重新填充剩余的,直到停止?生成一个1、2、3和4的正确分布的随机板,如果不符合行/列条件,则丢弃。只要有效的电路板是相对常见的,这应该可以很好地工作。这被称为“验收抽样”,它应该可以工作,但一些快速餐巾纸数学表明,生成无冲突的电路板的概率可能小于1%——如果按比例放大,这可能会成为一个问题,但
    timeit
    给了我每个有效生成的电路板48.6µs±3.62µs的近似值,因此,对于这种情况,这似乎是可以接受的。