mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
147 lines
No EOL
5.5 KiB
Python
Executable file
147 lines
No EOL
5.5 KiB
Python
Executable file
import os
|
|
import random
|
|
import time
|
|
import json
|
|
from .masyu_solver import check_valid_masyu
|
|
|
|
|
|
class MasyuGenerator:
|
|
def __init__(self):
|
|
self.npuzzles = 0
|
|
|
|
def generate_puzzle(self, rows, cols, black_pearls, white_pearls, max_attempts=10000):
|
|
"""
|
|
生成一个 Masyu 谜题,简化了生成和验证过程
|
|
"""
|
|
# print(f"Generating {rows}x{cols} puzzle with {black_pearls} black and {white_pearls} white pearls...")
|
|
|
|
for attempt in range(max_attempts):
|
|
if attempt % 100 == 0:
|
|
# print(f"Attempt {attempt}/{max_attempts}...")
|
|
pass
|
|
|
|
# 创建空网格
|
|
grid = [[' ' for _ in range(cols)] for _ in range(rows)]
|
|
|
|
# 随机放置珠子
|
|
if not self._place_random_pearls(grid, rows, cols, black_pearls, white_pearls):
|
|
continue
|
|
|
|
# 检查谜题是否有唯一解
|
|
if check_valid_masyu(grid):
|
|
# print(f"Found valid puzzle after {attempt + 1} attempts")
|
|
return grid
|
|
|
|
# print(f"Failed to generate puzzle after {max_attempts} attempts")
|
|
return None
|
|
|
|
def _place_random_pearls(self, grid, rows, cols, black_pearls, white_pearls):
|
|
"""随机放置珠子,考虑珠子之间的规则性"""
|
|
total_pearls = black_pearls + white_pearls
|
|
|
|
# 检查是否有足够的单元格
|
|
if total_pearls > rows * cols:
|
|
return False
|
|
|
|
# 获取所有可用单元格
|
|
available_cells = [(r, c) for r in range(rows) for c in range(cols)]
|
|
random.shuffle(available_cells)
|
|
|
|
# 放置黑珠和白珠时,确保不会互相冲突
|
|
for i in range(black_pearls):
|
|
if i < len(available_cells):
|
|
r, c = available_cells[i]
|
|
grid[r][c] = 'B' # 放置黑珠
|
|
|
|
for i in range(black_pearls, black_pearls + white_pearls):
|
|
if i < len(available_cells):
|
|
r, c = available_cells[i]
|
|
grid[r][c] = 'W' # 放置白珠
|
|
|
|
# 只进行最基本的验证,放宽规则
|
|
return True
|
|
|
|
def print_puzzle(self, grid):
|
|
"""打印谜题"""
|
|
if grid is None:
|
|
# print("No puzzle to display")
|
|
return
|
|
|
|
nrows = len(grid)
|
|
ncols = len(grid[0]) if nrows > 0 else 0
|
|
|
|
# print("Puzzle:")
|
|
for r in range(nrows):
|
|
line = ""
|
|
for c in range(ncols):
|
|
if grid[r][c] == 'B':
|
|
line += "● "
|
|
elif grid[r][c] == 'W':
|
|
line += "○ "
|
|
else:
|
|
line += " "
|
|
# print(line)
|
|
|
|
def batch_generate_puzzles(self, count, min_rows, max_rows, min_cols, max_cols, min_black_pearls, max_black_pearls,
|
|
min_white_pearls, max_white_pearls, output_dir="generated_puzzles", max_attempts=1000):
|
|
"""
|
|
批量生成 Masyu 谜题,并保存为 JSON 文件
|
|
增加了随机生成参数的功能
|
|
"""
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
valid_puzzles = [] # 用于存储生成的有效谜题
|
|
|
|
for i in range(count):
|
|
# print(f"\nGenerating puzzle {i + 1}/{count}...")
|
|
|
|
# 随机设置谜题的行数、列数、黑珠和白珠数目,减少珠子数量,避免过多的约束
|
|
rows = random.randint(min_rows, max_rows)
|
|
cols = random.randint(min_cols, max_cols)
|
|
black_pearls = random.randint(min_black_pearls, max_black_pearls)
|
|
white_pearls = random.randint(min_white_pearls, max_white_pearls)
|
|
|
|
# 尝试生成一个有效的谜题
|
|
puzzle = self.generate_puzzle(rows, cols, black_pearls, white_pearls, max_attempts)
|
|
if puzzle:
|
|
puzzle_data = {
|
|
"id": f"masyu_puzzle_{i + 1}",
|
|
"rows": rows,
|
|
"cols": cols,
|
|
"puzzle": puzzle
|
|
}
|
|
valid_puzzles.append(puzzle_data)
|
|
|
|
# 保存单个谜题到 JSON 文件
|
|
puzzle_file = os.path.join(output_dir, f"masyu_puzzle_{i + 1}.json")
|
|
with open(puzzle_file, "w") as f:
|
|
json.dump(puzzle_data, f, indent=2)
|
|
# print(f"Saved puzzle {i + 1} to {puzzle_file}")
|
|
else:
|
|
# print(f"Failed to generate puzzle {i + 1}")
|
|
pass
|
|
|
|
# 将所有有效谜题保存到一个大文件中
|
|
dataset_file = os.path.join(output_dir, "masyu_dataset.json")
|
|
with open(dataset_file, "w") as f:
|
|
json.dump(valid_puzzles, f, indent=2)
|
|
# print(f"Saved all generated puzzles to {dataset_file}")
|
|
|
|
|
|
def main():
|
|
# 设置生成谜题的参数
|
|
generator = MasyuGenerator()
|
|
|
|
# 设置随机范围,生成 1000 个谜题
|
|
generator.batch_generate_puzzles(
|
|
count=50, # 生成谜题个数
|
|
min_rows=4, max_rows=6, # 随机生成 4x4 到 6x6 大小的谜题
|
|
min_cols=4, max_cols=6, # 随机生成 4x4 到 6x6 大小的谜题
|
|
min_black_pearls=2, max_black_pearls=3, # 随机生成 2 到 3 个黑珠
|
|
min_white_pearls=2, max_white_pearls=3, # 随机生成 2 到 3 个白珠
|
|
output_dir="generated_puzzles", # 保存到当前目录下的 generated_puzzles 文件夹
|
|
max_attempts=1000 # 每个谜题的最大尝试次数
|
|
)
|
|
|
|
if __name__ == "__main__":
|
|
main() |