游戏场景与算法概述
《植物大战僵尸》是一款经典的塔防游戏,玩家需要在五条水平路径上种植各种植物,抵御从右侧不断涌来的僵尸。本文将用Java实现该游戏的核心算法:基于难度曲线的波次生成算法、利用贪心策略的行优先防御部署,以及阳光资源的最优分配策略。
核心算法一:波次生成算法
波次生成需要根据当前关卡进度动态调整僵尸的种类、数量和出现间隔。我们使用难度曲线函数来平滑控制游戏节奏:前期以普通僵尸为主,间隔较长;中期引入强化僵尸,间隔缩短;后期出现高威胁僵尸,间隔密集。
import java.util.*;
public class WaveGenerator {
private int currentWave = 0;
private Random random = new Random();
public enum ZombieType {
NORMAL(1, 1.0), CONEHEAD(2, 2.0), BUCKETHEAD(3, 3.5),
DANCER(4, 5.0), GARGANTUAR(5, 8.0);
final int tier;
final double threat;
ZombieType(int tier, double threat) { this.tier = tier; this.threat = threat; }
}
public static class ZombieSpawn {
public int lane, delay;
public ZombieType type;
public ZombieSpawn(int lane, int delay, ZombieType type) {
this.lane = lane; this.delay = delay; this.type = type;
}
}
// 难度曲线:随着波次增加,僵尸强度和密度上升
public List<ZombieSpawn> generateWave(int waveNumber) {
List<ZombieSpawn> spawns = new ArrayList<>();
currentWave = waveNumber;
int baseCount = 3 + waveNumber / 2 + random.nextInt(3);
double difficulty = Math.log1p(waveNumber) * 0.8 + 0.5;
for (int i = 0; i < baseCount; i++) {
int lane = random.nextInt(5);
int delay = i * Math.max(60, 120 - waveNumber * 3);
spawns.add(new ZombieSpawn(lane, delay, selectZombieType(difficulty)));
}
return spawns;
}
private ZombieType selectZombieType(double difficulty) {
double roll = random.nextDouble() * difficulty;
if (roll > 4.5) return ZombieType.GARGANTUAR;
if (roll > 3.5) return ZombieType.DANCER;
if (roll > 2.5) return ZombieType.BUCKETHEAD;
if (roll > 1.5) return ZombieType.CONEHEAD;
return ZombieType.NORMAL;
}
}
核心算法二:行优先防御部署
当阳光资源有限时,采用贪心策略优先保护威胁最大的行:
- 行威胁评估:计算每行当前僵尸的总威胁值(类型权重 × 数量 × 距离倒数)
- 优先级排序:威胁值越高的行越需要优先部署防御
- 植物选择:根据威胁类型选择最优植物
public class DefenseDeployer {
private static final int LANES = 5;
private static final int COLUMNS = 9;
public enum PlantType {
SUNFLOWER(50, 0), PEASHOOTER(100, 2.0),
SNOW_PEA(150, 2.5), REPEATER(175, 4.0);
final int cost; final double dps;
PlantType(int cost, double dps) { this.cost = cost; this.dps = dps; }
}
public static class PlantAction {
public int lane, col;
public PlantType type;
public PlantAction(int lane, int col, PlantType type) {
this.lane = lane; this.col = col; this.type = type;
}
}
// 贪心策略:优先在威胁最大的行部署防御
public PlantAction decideNextPlant(List<Zombie> zombies, int sunPoints, PlantType[][] grid) {
double[] laneThreat = new double[LANES];
for (Zombie z : zombies) {
double distanceFactor = 1.0 / (z.x + 1);
laneThreat[z.lane] += z.threatLevel * distanceFactor;
}
Integer[] lanes = new Integer[LANES];
for (int i = 0; i < LANES; i++) lanes[i] = i;
Arrays.sort(lanes, (a, b) -> Double.compare(laneThreat[b], laneThreat[a]));
for (int lane : lanes) {
if (laneThreat[lane] < 0.5) continue;
int bestCol = findBestColumn(lane, grid);
PlantType bestPlant = selectOptimalPlant(laneThreat[lane], sunPoints);
if (bestPlant != null && bestPlant.cost <= sunPoints) {
return new PlantAction(lane, bestCol, bestPlant);
}
}
return null;
}
private int findBestColumn(int lane, PlantType[][] grid) {
for (int col = 1; col < COLUMNS; col++) {
if (grid[lane][col] == null) return col;
}
return -1;
}
private PlantType selectOptimalPlant(double threat, int sunPoints) {
if (sunPoints >= 175 && threat > 5.0) return PlantType.REPEATER;
if (sunPoints >= 150 && threat > 3.0) return PlantType.SNOW_PEA;
if (sunPoints >= 100) return PlantType.PEASHOOTER;
if (sunPoints >= 50) return PlantType.SUNFLOWER;
return null;
}
}
核心算法三:阳光资源最优分配
采用动态优先级策略管理阳光使用:早期建立经济基础,中期平衡攻防,后期全力防御。
public class SunlightManager {
private int totalSun = 50;
public static class Allocation {
public int economy, attack, reserve;
public Allocation(int e, int a, int r) { economy = e; attack = a; reserve = r; }
}
public Allocation allocateSun(int waveNumber, double maxLaneThreat) {
double economyRatio, attackRatio, reserveRatio;
if (waveNumber <= 3) {
economyRatio = 0.70; attackRatio = 0.20; reserveRatio = 0.10;
} else if (waveNumber <= 8) {
economyRatio = 0.30; attackRatio = 0.50; reserveRatio = 0.20;
} else {
economyRatio = 0.10; attackRatio = 0.60; reserveRatio = 0.30;
}
if (maxLaneThreat > 8.0) {
reserveRatio = 0.0; attackRatio += 0.30;
}
return new Allocation(
(int)(totalSun * economyRatio),
(int)(totalSun * attackRatio),
(int)(totalSun * reserveRatio)
);
}
}
复杂度分析
| 算法模块 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 波次生成 | O(n) | O(n) |
| 行威胁评估 | O(m) | O(1) |
| 防御部署决策 | O(L log L) | O(L) |
| 阳光分配 | O(1) | O(1) |
总结
本文通过波次生成算法实现动态难度平衡,利用行优先贪心策略高效部署防御,结合分阶段阳光分配完成资源优化。读者可在此基础上扩展更多植物与僵尸AI,深入理解贪心算法在塔防游戏中的应用。