feat: fix racewars game to work with ecs

master
Mark Beck 2026-01-12 14:21:52 +01:00 committed by Mark Beck
parent e9602140e9
commit 4970cf040e
8 changed files with 55 additions and 82 deletions

View File

@ -1,7 +1,12 @@
package com.example.components;
import com.example.ecs.Component;
import com.example.ecs.Entity;
public record BattleWin( public record BattleWin(
Entity winningSquad, Entity winningSquad,
Entity loosingSquad, Entity loosingSquad,
boolean draw, boolean draw
) { ) implements Component {
} }

View File

@ -1,5 +1,6 @@
package com.example.components; package com.example.components;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.example.ecs.Component; import com.example.ecs.Component;
@ -8,17 +9,17 @@ import com.example.ecs.Entity;
public class Squad implements Component { public class Squad implements Component {
private String name; private String name;
private List<Entity> activeUnits; private List<Entity> activeUnits;
private List<Entity> deadUnits; private List<Entity> deadUnits = new ArrayList();
public Squad(String name, List<Entity> units) { public Squad(String name, List<Entity> units) {
this.name = name; this.name = name;
this.units = units; this.activeUnits = units;
} }
public void killUnit(Entity entity) { public void killUnit(Entity entity) {
if (activeUnits.contains(entity)) { if (activeUnits.contains(entity)) {
activeUnits.remove(entity); activeUnits.remove(entity);
deadUnits.add(unit); deadUnits.add(entity);
} }
} }
@ -35,6 +36,6 @@ public class Squad implements Component {
} }
public boolean isActive() { public boolean isActive() {
return !activeUnits.empty() return !activeUnits.isEmpty();
} }
} }

View File

@ -3,6 +3,7 @@ package com.example.controller;
import com.example.components.Attack; import com.example.components.Attack;
import com.example.components.Battle; import com.example.components.Battle;
import com.example.components.BattleWin;
import com.example.components.CombatLog; import com.example.components.CombatLog;
import com.example.components.Health; import com.example.components.Health;
import com.example.components.Hero; import com.example.components.Hero;
@ -19,6 +20,7 @@ import com.example.systems.CombatSystem;
import com.example.systems.DamageSystem; import com.example.systems.DamageSystem;
import com.example.systems.RenderSystem; import com.example.systems.RenderSystem;
import com.example.systems.SquadGenerationSystem; import com.example.systems.SquadGenerationSystem;
import com.example.systems.WinSystem;
public class GameController { public class GameController {
@ -28,6 +30,7 @@ public class GameController {
System damageSystem; System damageSystem;
System renderSystem; System renderSystem;
CleanupSystem cleanupSystem; CleanupSystem cleanupSystem;
WinSystem winSystem;
public GameController() { public GameController() {
registry.registerComponentType(Attack.class); registry.registerComponentType(Attack.class);
@ -39,6 +42,7 @@ public class GameController {
registry.registerComponentType(Investment.class); registry.registerComponentType(Investment.class);
registry.registerComponentType(Squad.class); registry.registerComponentType(Squad.class);
registry.registerComponentType(Stats.class); registry.registerComponentType(Stats.class);
registry.registerComponentType(BattleWin.class);
squadGenerationSystem = new SquadGenerationSystem(registry); squadGenerationSystem = new SquadGenerationSystem(registry);
@ -46,6 +50,8 @@ public class GameController {
damageSystem = new DamageSystem(registry); damageSystem = new DamageSystem(registry);
renderSystem = new RenderSystem(registry); renderSystem = new RenderSystem(registry);
cleanupSystem = new CleanupSystem(registry); cleanupSystem = new CleanupSystem(registry);
winSystem = new WinSystem(registry);
Entity squad1 = new Entity(); Entity squad1 = new Entity();
Entity squad2 = new Entity(); Entity squad2 = new Entity();
@ -65,6 +71,7 @@ public class GameController {
damageSystem.run(); damageSystem.run();
renderSystem.run(); renderSystem.run();
cleanupSystem.run(); cleanupSystem.run();
winSystem.run();
} }
} }
} }

View File

@ -29,21 +29,8 @@ public class CleanupSystem extends System {
var squads = registry.getWithComponents(Squad.class); var squads = registry.getWithComponents(Squad.class);
for (var squadEntity : squads) { for (var squadEntity : squads) {
var squad = registry.getComponent(squadEntity, Squad.class); var squad = registry.getComponent(squadEntity, Squad.class);
squad.removeUnit(unit); squad.killUnit(unit);
} }
registry.remove(unit);
}
}
var battles = registry.getWithComponents(Battle.class);
for (var battleEntity : battles) {
var battle = registry.getComponent(battleEntity, Battle.class);
var squad1 = registry.getComponent(battle.squad1(), Squad.class);
var squad2 = registry.getComponent(battle.squad2(), Squad.class);
if (squad1.units().isEmpty() || squad2.units().isEmpty()) {
registry.remove(battleEntity);
registry.remove(battle.squad1());
registry.remove(battle.squad2());
} }
} }

View File

@ -9,9 +9,8 @@ import com.example.components.Squad;
import com.example.components.Stats; import com.example.components.Stats;
import com.example.ecs.Entity; import com.example.ecs.Entity;
import com.example.ecs.Registry; import com.example.ecs.Registry;
import com.example.ecs.System;
public class CombatSystem extends System { public class CombatSystem extends com.example.ecs.System {
public CombatSystem(Registry registry) { public CombatSystem(Registry registry) {
super(registry); super(registry);
@ -32,11 +31,17 @@ public class CombatSystem extends System {
} }
private void attack(Squad attacker, Squad defender) { private void attack(Squad attacker, Squad defender) {
for (var entity : attacker.units()) { for (var entity : attacker.activeUnits()) {
var unitData = registry.getComponent(entity, Stats.class); var unitData = registry.getComponent(entity, Stats.class);
boolean isHero = registry.hasComponent(entity, Hero.class); boolean isHero = registry.hasComponent(entity, Hero.class);
var target = defender.units().get(rng.nextInt(defender.units().size())); if (unitData == null) {
System.out.println("No unitData for");
System.out.println("Entity: " + entity);
continue;
}
var target = defender.activeUnits().get(rng.nextInt(defender.activeUnits().size()));
double damageDealt = unitData.dmg() * unitData.speed(); double damageDealt = unitData.dmg() * unitData.speed();
if (isHero) { if (isHero) {
var heroData = registry.getComponent(entity, Hero.class); var heroData = registry.getComponent(entity, Hero.class);

View File

@ -1,15 +1,15 @@
package com.example.systems; package com.example.systems;
import com.example.components.BattleWin;
import com.example.components.CombatLog; import com.example.components.CombatLog;
import com.example.components.Health; import com.example.components.Health;
import com.example.components.Hero; import com.example.components.Hero;
import com.example.components.Squad; import com.example.components.Squad;
import com.example.ecs.Entity; import com.example.ecs.Entity;
import com.example.ecs.Registry; import com.example.ecs.Registry;
import com.example.ecs.System;
import com.example.components.Stats; import com.example.components.Stats;
public class RenderSystem extends System { public class RenderSystem extends com.example.ecs.System {
public RenderSystem(Registry registry) { public RenderSystem(Registry registry) {
super(registry); super(registry);
@ -19,11 +19,22 @@ public class RenderSystem extends System {
renderCombat(); renderCombat();
var squads = registry.getWithComponents(Squad.class); var squads = registry.getWithComponents(Squad.class);
for (var squad : squads) { for (var squad : squads) {
var squadData = registry.getComponent(squad, Squad.class); var squadData = registry.getComponent(squad, Squad.class);
renderSquad(squadData); renderSquad(squadData);
} }
var battleWins = registry.getWithComponents(BattleWin.class);
for (var battleWin : battleWins) {
var battleWinData = registry.getComponent(battleWin, BattleWin.class);
var squad1 = registry.getComponent(battleWinData.winningSquad(), Squad.class);
var squad2 = registry.getComponent(battleWinData.loosingSquad(), Squad.class);
if (battleWinData.draw()) {
System.out.println("\n---------------------\n Draw between " + squad1.name() + " and " + squad2.name() + "\n------------------------");
} else {
System.out.println("\n---------------------\n" + squad1.name() + " won against " + squad2.name() + "\n------------------------");
}
}
} }
private String generateName(Entity entity) { private String generateName(Entity entity) {
@ -48,7 +59,7 @@ public class RenderSystem extends System {
private void renderSquad(Squad squad) { private void renderSquad(Squad squad) {
IO.println("Squad " + squad.name()); IO.println("Squad " + squad.name());
for (var unit : squad.units()) { for (var unit : squad.activeUnits()) {
var health = registry.getComponent(unit, Health.class); var health = registry.getComponent(unit, Health.class);
IO.println(generateName(unit) + " [" + health.hp() + "/" + health.maxHp() + "]"); IO.println(generateName(unit) + " [" + health.hp() + "/" + health.maxHp() + "]");

View File

@ -1,44 +0,0 @@
package com.example.systems;
import java.util.Random;
import com.example.components.Attack;
import com.example.components.Battle;
import com.example.components.Hero;
import com.example.components.Squad;
import com.example.components.Stats;
import com.example.ecs.Entity;
import com.example.ecs.Registry;
import com.example.ecs.System;
public class SquadUpdateSystem extends System {
public UnitKillerSystem(Registry registry) {
super(registry);
}
public void run() {
for (var battleEntity : registry.getWithComponents(Battle.class)) {
var battle = registry.getComponent(battleEntity, Battle.class);
var squad1 = registry.getComponent(battle.squad1(), Squad.class);
var squad2 = registry.getComponent(battle.squad2(), Squad.class);
Entity battleWinEntity = new Entity();
if (squad1.isActive() && squad2.isActive()) {
BattleWin battleWin(battle.squad1(), battle.squad2(), true);
registry.add(battleWinEntity, battleWin);
} else if (squad1.isActive) {
BattleWin battleWin(battle.squad2(), battle.squad1(), false);
registry.add(battleWinEntity, battleWin);
} else if (squad2.isActive()) {
BattleWin battleWin(battle.squad1(), battle.squad2(), false);
registry.add(battleWinEntity, battleWin);
}
if (squad1.isActive() || squad2.isActive()) {
registry.remove(battleEntity);
}
}
}
}

View File

@ -4,6 +4,7 @@ import java.util.Random;
import com.example.components.Attack; import com.example.components.Attack;
import com.example.components.Battle; import com.example.components.Battle;
import com.example.components.BattleWin;
import com.example.components.Hero; import com.example.components.Hero;
import com.example.components.Squad; import com.example.components.Squad;
import com.example.components.Stats; import com.example.components.Stats;
@ -25,18 +26,18 @@ public class WinSystem extends System {
var squad2 = registry.getComponent(battle.squad2(), Squad.class); var squad2 = registry.getComponent(battle.squad2(), Squad.class);
Entity battleWinEntity = new Entity(); Entity battleWinEntity = new Entity();
if (squad1.isActive() && squad2.isActive()) { if (!squad1.isActive() && !squad2.isActive()) {
BattleWin battleWin(battle.squad1(), battle.squad2(), true); BattleWin battleWin = new BattleWin(battle.squad1(), battle.squad2(), true);
registry.add(battleWinEntity, battleWin); registry.addComponent(battleWinEntity, battleWin);
} else if (squad1.isActive) { } else if (!squad1.isActive()) {
BattleWin battleWin(battle.squad2(), battle.squad1(), false); BattleWin battleWin = new BattleWin(battle.squad2(), battle.squad1(), false);
registry.add(battleWinEntity, battleWin); registry.addComponent(battleWinEntity, battleWin);
} else if (squad2.isActive()) { } else if (!squad2.isActive()) {
BattleWin battleWin(battle.squad1(), battle.squad2(), false); BattleWin battleWin = new BattleWin(battle.squad1(), battle.squad2(), false);
registry.add(battleWinEntity, battleWin); registry.addComponent(battleWinEntity, battleWin);
} }
if (squad1.isActive() || squad2.isActive()) { if (!squad1.isActive() || !squad2.isActive()) {
registry.remove(battleEntity); registry.remove(battleEntity);
} }
} }