Python 生成糖果粉碎类游戏的初始游戏板
我需要实现一个功能, 返回满足以下要求的6乘6矩阵: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
- 棋盘上的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]]
不必太担心学术时间/空间的复杂性。更多地关注工程的观点。有什么好主意吗
这应该行得通。请注意,此解决方案只生成一个随机板,检查条件是否成立,如果不成立,则生成另一个,因此不是最优雅的解决方案 代码:
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的近似值,因此,对于这种情况,这似乎是可以接受的。