You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pygame平台游戏关卡列表中均匀分散敌人

解决Pygame平台游戏中敌人均匀分散放置的问题

原代码问题分析

你当前的实现逻辑存在两个核心问题:

  1. 按顺序遍历空格并通过累加计数放置敌人,很容易在连续空格区域集中生成敌人,导致集群现象。
  2. 没有加入敌人之间的间距约束,仅靠随机调整间隔参数无法保证分散效果。

下面提供两种高效的解决方案,满足敌人均匀分散且绝不靠近的需求:


方案一:拒绝采样法(贴近你的分子分布思路)

通过随机选点+间距校验的方式,模拟"分子分散"的效果,确保每个敌人之间的距离不小于设定值。

import random

def shuffle_map(self, difficulty):
    empty_level_map = [
        '6--------------------------------------------------------------7',
        'LXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXI',
        '9______________________________________________________________8',
        'M                                                              O',
        'M                                                              O',
        'M      P                                                       O',
        'M                                                              O',
        'M                                                              O',
        '6--------------------------------------------------------------7',
        'LXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXI',
        '9______________________________________________________________8']
    
    # 1. 收集所有可放置敌人的空格坐标(列x,行y)
    available_positions = []
    for y, line in enumerate(empty_level_map):
        for x, char in enumerate(line):
            if char.isspace():
                available_positions.append((x, y))
    
    # 2. 根据难度动态设置敌人数量,同时限制最大数量避免位置不足
    max_enemies = len(available_positions) // 3  # 预留足够间距空间
    target_enemies = {1:8, 2:16, 3:24}.get(difficulty, 12)
    target_enemies = min(target_enemies, max_enemies)
    
    # 3. 设置敌人之间的最小间距(按格子数计算,此处设为5格)
    min_distance_sq = 5 ** 2  # 用平方距离避免开根号,提升计算效率
    enemy_positions = []
    
    # 4. 拒绝采样:随机选点并校验间距
    while len(enemy_positions) < target_enemies and available_positions:
        # 随机挑选一个候选位置
        idx = random.randint(0, len(available_positions)-1)
        candidate_x, candidate_y = available_positions[idx]
        
        # 检查与已放置敌人的距离是否符合要求
        is_valid = True
        for (enemy_x, enemy_y) in enemy_positions:
            dx = candidate_x - enemy_x
            dy = candidate_y - enemy_y
            if dx*dx + dy*dy < min_distance_sq:
                is_valid = False
                break
        
        if is_valid:
            enemy_positions.append((candidate_x, candidate_y))
            del available_positions[idx]  # 移除已用位置,避免重复放置
    
    # 5. 将敌人位置写入关卡地图
    self.level_data = []
    for y, line in enumerate(empty_level_map):
        line_list = list(line)
        for (x, enemy_y) in enemy_positions:
            if enemy_y == y:
                line_list[x] = "E"
        self.level_data.append("".join(line_list))

关键逻辑说明

  • 先收集所有可放置位置,避免重复遍历地图
  • 用平方距离判断间距,比计算平方根更高效
  • 拒绝不符合间距要求的候选点,确保敌人分散
  • 动态限制敌人数量,避免因位置不足导致死循环

方案二:网格划分法(高效且均匀)

将可放置区域划分为固定大小的网格,每个网格最多放置一个敌人,天然保证间距,生成速度更快。

import random
from collections import defaultdict

def shuffle_map(self, difficulty):
    empty_level_map = [
        '6--------------------------------------------------------------7',
        'LXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXI',
        '9______________________________________________________________8',
        'M                                                              O',
        'M                                                              O',
        'M      P                                                       O',
        'M                                                              O',
        'M                                                              O',
        '6--------------------------------------------------------------7',
        'LXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXI',
        '9______________________________________________________________8']
    
    # 1. 按网格划分可放置位置,每个网格大小为5x5格子
    grid_size = 5
    grid = defaultdict(list)
    for y, line in enumerate(empty_level_map):
        for x, char in enumerate(line):
            if char.isspace():
                grid_key = (x // grid_size, y // grid_size)
                grid[grid_key].append((x, y))
    
    # 2. 根据难度设置敌人数量,每个网格最多一个敌人
    max_enemies = len(grid)
    target_enemies = {1:8, 2:16, 3:24}.get(difficulty, 12)
    target_enemies = min(target_enemies, max_enemies)
    
    # 3. 随机选择网格并在其中选一个位置放敌人
    selected_grids = random.sample(list(grid.keys()), target_enemies)
    enemy_positions = [random.choice(grid[key]) for key in selected_grids]
    
    # 4. 写入关卡地图
    self.level_data = []
    for y, line in enumerate(empty_level_map):
        line_list = list(line)
        for (x, enemy_y) in enemy_positions:
            if enemy_y == y:
                line_list[x] = "E"
        self.level_data.append("".join(line_list))

关键逻辑说明

  • 网格划分确保敌人之间的最小间距等于网格大小
  • 生成速度远快于拒绝采样,适合大地图场景
  • 敌人分布均匀,不会出现局部集群现象

内容的提问来源于stack exchange,提问作者Yasser Machkour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:47:33