InternBootcamp/internbootcamp/libs/starbattle/get_grid.py
2025-05-23 15:27:15 +08:00

128 lines
No EOL
5.1 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random
def generate_star_battle_grid(size):
"""
生成星战谜题的测试用例网格。
参数:
size -- 网格的大小 (假设是正方形网格size 表示边长)
num_regions -- 区域的数量(等于星星数量)
返回:
grid -- 生成的网格每个区域由不同的数字表示0 表示尚未分配区域的空位
star_positions -- 星星的位置列表
"""
num_regions = size
# 初始化网格和可用单元格列表
grid = [[0 for _ in range(size)] for _ in range(size)]
available_cells = [(r, c) for r in range(size) for c in range(size)]
available_cells_for_star = available_cells.copy()
star_positions = []
def is_safe_to_place_star(row, col, star_positions):
"""检查在给定位置放置星星是否安全"""
for r, c in star_positions:
if row == r or col == c or abs(row - r) == abs(col - c):
return False
return True
while True:
try:
# 随机确定所有星星的位置
while len(star_positions) < num_regions:
pos = random.choice(available_cells_for_star)
star_positions.append(pos)
available_cells_for_star.remove(pos)
available_cells.remove(pos)
# pos周围一层也从available_cells_for_star移除
for r in range(pos[0] - 1, pos[0] ):
for c in range(pos[1] - 1, pos[1] ):
if (r, c) in available_cells_for_star:
available_cells_for_star.remove((r, c))
# pos 同行同列从available_cells_for_star移除
for c in range(num_regions):
if (pos[0], c) in available_cells_for_star:
available_cells_for_star.remove((pos[0], c))
for r in range(num_regions):
if (r, pos[1]) in available_cells_for_star:
available_cells_for_star.remove((r, pos[1]))
break
except:
available_cells = [(r, c) for r in range(size) for c in range(size)]
available_cells_for_star = available_cells.copy()
star_positions = []
pass
remaining_cells = list(available_cells)
# 为每个星星创建一个区域
regions = []
for i, star_pos in enumerate(star_positions, start=1):
region_id = chr(ord('A') + i - 1)
cur_region,remaining_cells = expand_region_by_1_step(grid, star_pos, remaining_cells, region_id)
regions.append(cur_region)
# 继续扩展
for i,region in enumerate(regions, start=1):
region_id = chr(ord('A') + i - 1)
remaining_cells = expand_region_from_star(grid, region, remaining_cells, region_id)
# 将最后剩余空位随机融合到附近的区域
def find_nearest_region(grid, x, y):
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
random.shuffle(directions) # 随机化扩展顺序
for dx, dy in directions:
nx, ny = x + dx, y + dy
try:
if grid[nx][ny] != 0 and nx >= 0 and ny >= 0:
return grid[nx][ny]
except IndexError:
continue
return None
while remaining_cells:
x, y = random.choice(remaining_cells)
region_id = find_nearest_region(grid, x, y)
if region_id is not None:
grid[x][y] = region_id
remaining_cells.remove((x, y))
return grid, star_positions
def expand_region_by_1_step(grid,star_pos,available_cells, region_id):
"""从星星位置随机扩散出一个区域"""
region = [star_pos]
grid[star_pos[0]][star_pos[1]] = region_id
# 定义可能的移动方向
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
random.shuffle(directions) # 随机化扩展顺序
for direction in directions:
new_pos = (star_pos[0] + direction[0], star_pos[1] + direction[1])
if new_pos in available_cells:
available_cells.remove(new_pos)
region.append(new_pos)
grid[new_pos[0]][new_pos[1]] = region_id
break
return region,available_cells
def expand_region_from_star(grid, region, available_cells, region_id):
# 继续尝试扩展直到达到合理大小或没有更多可用单元格
max_region_size = random.randint(1 ,len(available_cells) // len(grid))
retry = 0
while available_cells and len(region) < max_region_size and retry < len(grid) ** 2:
next_cell = random.choice(available_cells)
if any(abs(next_cell[0] - cell[0]) + abs(next_cell[1] - cell[1]) <= 1 for cell in region):
available_cells.remove(next_cell)
region.append(next_cell)
grid[next_cell[0]][next_cell[1]] = region_id
retry += 1
return available_cells
# 示例使用:
if __name__ == "__main__":
size = 5 # 网格大小
grid, star_positions = generate_star_battle_grid(size)
print("生成的网格:")
for row in grid:
print(row)
print("星星的位置:", star_positions)