本文目录导读:

这是一个非常经典的面向对象设计问题,也是很多游戏(如《火焰之纹章》《皇室战争》)的核心逻辑。
针对你问的“阵型克制关系有规律吗?”——有规律,但规律通常不是数学公式,而是“索引映射”或“循环链表”逻辑。
下面我提供一个综合 Java 案例,包含完整代码和三种常见的建模方式,并解释其规律。
核心规律总结(先看结论)
阵型克制的“规律”通常分三种:
- 三角循环(石头剪刀布):A克B,B克C,C克A。
- 规律:使用
(攻方.ordinal() + 1) % 3 == 守方.ordinal()
- 规律:使用
- 线性链(火影查克拉属性):火 → 风 → 雷 → 土 → 水 → 火。
- 规律:使用
Map存储直接后继关系,查表即可。
- 规律:使用
- 属性双克(宝可梦):数值加减,存在免疫和抵抗。
- 规律:使用二维数组矩阵
int[attacker][defender],值代表倍率(0.5,1,2,0)。
- 规律:使用二维数组矩阵
综合案例代码(包含枚举 + 工厂模式)
我们设计一个“光明与黑暗”主题的阵型系统。
阵型枚举:PHALANX(枪阵),CAVALRY(骑兵),ARCHER(弓兵)。
克制规律:骑兵克弓兵,弓兵克枪兵,枪兵克骑兵(三角循环)。
完整可运行代码
import java.util.HashMap;
import java.util.Map;
/**
* 综合案例:阵型克制系统
* 展示了三种建模方式(Map、二维数组、循环取模),并集成策略模式。
*/
public class FormationSystem {
// ---------- 1. 枚举定义(附带克制逻辑) ----------
enum Formation {
PHALANX("枪阵"), CAVALRY("骑兵"), ARCHER("弓兵");
private final String displayName;
Formation(String displayName) {
this.displayName = displayName;
}
// 方式一:循环取模规律 (防御方是否被当前攻击方克制)
public boolean counters(Formation defender) {
// 规律:攻方ordinal值 + 1 取模3 == 守方ordinal值
return (this.ordinal() + 1) % 3 == defender.ordinal();
}
public String getDisplayName() {
return displayName;
}
}
// ---------- 2. 核心业务类:BattleEngine ----------
static class BattleEngine {
private static final Map<String, Boolean> cache = new HashMap<>();
// 方式二:使用 Map 存储克制关系(显式,也最灵活)
private static final Map<Formation, Formation> counterMap = new HashMap<>();
static {
counterMap.put(Formation.PHALANX, Formation.CAVALRY); // 枪克骑
counterMap.put(Formation.CAVALRY, Formation.ARCHER); // 骑克弓
counterMap.put(Formation.ARCHER, Formation.PHALANX); // 弓克枪
}
// 方式三:经典二维数组矩阵 (倍率)
private static final double[][] MATRIX = {
// 攻击方 \ 防御方 PHALANX, CAVALRY, ARCHER
/* PHALANX */ {1.0, 1.5, 0.5},
/* CAVALRY */ {0.5, 1.0, 1.5},
/* ARCHER */ {1.5, 0.5, 1.0}
};
/**
* 使用Map判断是否克制(最直观,适合业务扩展)
*/
public static boolean isCounterByMap(Formation attacker, Formation defender) {
return counterMap.get(attacker) == defender;
}
/**
* 使用取模公式判断(最简洁,符合数学规律)
*/
public static boolean isCounterByMath(Formation attacker, Formation defender) {
return (attacker.ordinal() + 1) % 3 == defender.ordinal();
}
/**
* 使用矩阵计算伤害倍率(最强大,可以拓展至RPG)
*/
public static double getDamageMultiplier(Formation attacker, Formation defender) {
return MATRIX[attacker.ordinal()][defender.ordinal()];
}
}
// ---------- 3. 策略模式(让阵型自己决定战斗方式) ----------
interface BattleStrategy {
double execute(Formation attacker, Formation defender);
}
static class SimpleStrategy implements BattleStrategy {
@Override
public double execute(Formation attacker, Formation defender) {
if (attacker.counters(defender)) return 1.5; // 克制
if (defender.counters(attacker)) return 0.5; // 被克制
return 1.0;
}
}
static class AdvancedStrategy implements BattleStrategy {
@Override
public double execute(Formation attacker, Formation defender) {
return BattleEngine.getDamageMultiplier(attacker, defender);
}
}
// ---------- 4. 测试运行 ----------
public static void main(String[] args) {
System.out.println("=== 验证三角循环规律: 骑(1)克弓(2) 且 弓(2)克枪(0) 且 枪(0)克骑(1) ===");
BattleStrategy simple = new SimpleStrategy();
BattleStrategy advanced = new AdvancedStrategy();
// 测试全部组合
for (Formation attacker : Formation.values()) {
for (Formation defender : Formation.values()) {
double ratio = simple.execute(attacker, defender);
double matrixRatio = advanced.execute(attacker, defender);
// 打印战斗格
String effect = ratio > 1 ? "【克制】" : (ratio < 1 ? "【被克】" : "【均势】");
System.out.printf("%-8s vs %-8s -> 策略伤害: %.1f | 矩阵伤害: %.1f %s%n",
attacker.getDisplayName(), defender.getDisplayName(),
ratio, matrixRatio, effect);
}
}
// 验证数学规律与Map的结果一致性
System.out.println("\n=== 一致性校验(Math vs Map) ===");
boolean allMatch = true;
for (Formation a : Formation.values()) {
for (Formation d : Formation.values()) {
if (BattleEngine.isCounterByMap(a, d) != BattleEngine.isCounterByMath(a, d)) {
allMatch = false;
System.out.println("不一致: " + a + " vs " + d);
}
}
}
System.out.println("所有计算方式完全一致: " + allMatch);
}
}
代码运行结果分析
当你运行上述代码,控制台输出效果如下(节选):
=== 验证三角循环规律: 骑(1)克弓(2) 且 弓(2)克枪(0) 且 枪(0)克骑(1) === 枪阵 vs 枪阵 -> 策略伤害: 1.0 | 矩阵伤害: 1.0 【均势】 枪阵 vs 骑兵 -> 策略伤害: 1.5 | 矩阵伤害: 1.5 【克制】 枪阵 vs 弓兵 -> 策略伤害: 0.5 | 矩阵伤害: 0.5 【被克】 骑兵 vs 枪阵 -> 策略伤害: 0.5 | 矩阵伤害: 0.5 【被克】 骑兵 vs 骑兵 -> 策略伤害: 1.0 | 矩阵伤害: 1.0 【均势】 骑兵 vs 弓兵 -> 策略伤害: 1.5 | 矩阵伤害: 1.5 【克制】 弓兵 vs 枪阵 -> 策略伤害: 1.5 | 矩阵伤害: 1.5 【克制】 弓兵 vs 骑兵 -> 策略伤害: 0.5 | 矩阵伤害: 0.5 【被克】 弓兵 vs 弓兵 -> 策略伤害: 1.0 | 矩阵伤害: 1.0 【均势】
更复杂的规律:如何扩展到“双属性”或“五行”
如果你觉得三角循环太简单,可以借鉴 《阴阳师》/《宝可梦》 的规律,假设你有5种阵型(风、林、火、山、雷),克制关系是一个五边形循环。
规律仍然是:
(attacker.ordinal() + 1) % 5 == defender.ordinal()
如果你需要双向克制(例如火克风,但风也克火),规律会变成:
// 双向互克(胜负由数值决定)
int diff = Math.abs(attacker.ordinal() - defender.ordinal());
if (diff == 1 || diff == 4) { /* 互相克制 */ }
“阵型克制有规律吗?”
有,且主要规律是:
- 数学公式:
(attackIndex + shift) % totalTypes == defendIndex,适合循环克制。 - 表驱动(Map/Matrix):
- 查表法(
HashMap<Attack, Defense>)适合“唯一克星”; - 二维矩阵(
double[][])适合“数值倍率”和“免疫”;
- 查表法(
- 面向对象:把对抗逻辑封装在枚举的
counter()方法里,职责清晰。
推荐方案:在真实项目中,优先使用二维矩阵,因为你可以额外存储“技能特效”“属性抗性”等扩展字段,后续加新阵型时0改动(只需扩展数组长度),且性能最优(数组下标访问)。
如果你需要我进一步演示“五行互生互克”的全代码(带生克关系的复杂矩阵),可以告诉我,我给你再补一版。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播