aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-07-24 17:28:44 -0400
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:30 +0200
commit3bb2b4479ee2a7064f28887f3c83f15f50fc9537 (patch)
tree6c9a1ef6b552456216822c78431db5424076917e
parent416fcf05a161ae3cfe248896dfe1327dccc0d892 (diff)
downloadmuhqs-game-3bb2b4479ee2a7064f28887f3c83f15f50fc9537.tar.gz
muhqs-game-3bb2b4479ee2a7064f28887f3c83f15f50fc9537.zip
fix AI if no paths or full action targets are available
-rw-r--r--go/game/ai.go13
-rw-r--r--go/game/ai_test.go50
2 files changed, 61 insertions, 2 deletions
diff --git a/go/game/ai.go b/go/game/ai.go
index faf8f11b..f630b41b 100644
--- a/go/game/ai.go
+++ b/go/game/ai.go
@@ -399,6 +399,9 @@ func moveTowardsNearestEnemyUnit(ai *UnitAI) Action {
}
paths := findPathsToUnits(graph, ai.s.Map(), ai.u, enemyUnits)
+ if len(paths) == 0 {
+ return nil
+ }
return actionFromPaths(ai, graph, paths)
}
@@ -410,6 +413,9 @@ func moveTowardsNearestTargetOption(ai *UnitAI, options []any) Action {
graph := ai.s.Map().generateMapGraphFor(ai.u)
paths := findPathsToInterface(graph, ai.s.Map(), ai.u, options)
+ if len(paths) == 0 {
+ return nil
+ }
return actionFromPaths(ai, graph, paths)
}
@@ -433,6 +439,7 @@ func fullAction(ai *UnitAI) Action {
if a.Targets() != nil && a.Targets().RequireSelection() {
err := selectRandomTargets(ai.s.Rand, a.Targets())
if err != nil {
+ log.Println("ai full action error:", err)
return nil
}
}
@@ -493,8 +500,10 @@ out:
}
}
if !inEnemyAttackRange && ai.u.HasFullAction() {
- ai.actions <- fullAction(ai)
- return
+ if a := fullAction(ai); a != nil {
+ ai.actions <- a
+ return
+ }
}
// 2.
diff --git a/go/game/ai_test.go b/go/game/ai_test.go
index 9c90c729..8c3ba0f9 100644
--- a/go/game/ai_test.go
+++ b/go/game/ai_test.go
@@ -315,3 +315,53 @@ symbols:
t.Fatal("AI did not finish after issuing a FullAction")
}
}
+
+func TestBlockedPathUnitAI(t *testing.T) {
+ mapDef := `map: |1-
+ WSW
+ WSW
+ WSW
+ SSS
+symbols:
+ T: tower
+ H: house
+ F: farm
+ S: street
+ W: deep water
+`
+ s := NewLocalState()
+
+ m, _ := readMap(strings.NewReader(mapDef))
+ s.SetMap(m)
+
+ p := s.AddNewPlayer("p", NewDeck())
+ o := s.AddNewPlayer("o", NewDeck())
+
+ s.addNewUnit(NewCard("base/archer"), Position{1, 3}, p)
+ f1 := s.addNewUnit(NewCard("base/fighter"), Position{1, 1}, o)
+ f2 := s.addNewUnit(NewCard("base/fighter"), Position{1, 0}, o)
+
+ // Move f1
+ ai := NewUnitAI(s, f1)
+ if ai == nil {
+ t.Fatal("ai is nil")
+ }
+ ai.promptAction()
+ a, _ := ai.NextAction()
+ if a == nil {
+ t.Fatal("Nil action received from aggressive AI")
+ }
+ s.ResolveAction(a)
+
+ // Move f2
+ ai = NewUnitAI(s, f2)
+ if ai == nil {
+ t.Fatal("ai is nil")
+ }
+ ai.promptAction()
+ a, _ = ai.NextAction()
+ if a == nil {
+ t.Fatal("Nil action received from aggressive AI")
+ }
+ s.ResolveAction(a)
+}