BFS Deadlock Prevention
The Problem: Players Can Accidentally Trap Enemies
If a player places a tower that blocks every possible exit for an enemy currently on the map, that enemy can never reach the target — the game breaks. This situation must be prevented.
The Dual Validation Requirement
When a player attempts to place a tower, the system must simultaneously confirm 2 conditions:
- At least 1 valid path still exists from every spawn point to the target (A*)
- Every active enemy on the map can still reach the target (BFS)
The BFS Deadlock Check Algorithm
Instead of running A* for every individual enemy (prohibitively expensive), the system runs a single reverse BFS from the target tile, counting the total number of reachable enemies:
// PlacementService.cs
private bool CheckDeadlockEnemy(int totalActiveEnemies)
{
int reachableEnemiesCount = 0;
Queue<HexTile> frontier = new Queue<HexTile>();
HashSet<HexTile> visited = new HashSet<HexTile>();
// BFS outward from the Target tile
frontier.Enqueue(_map.TargetTile);
visited.Add(_map.TargetTile);
while (frontier.Count > 0)
{
var current = frontier.Dequeue();
reachableEnemiesCount += current.EnemyCount; // Count enemies standing on this tile
foreach (var neighbor in _map.GetNeighbors(current))
{
if (neighbor.IsWalkable() && !visited.Contains(neighbor))
{
visited.Add(neighbor);
frontier.Enqueue(neighbor);
}
}
}
// If enemies found < total active enemies → at least one is trapped
return reachableEnemiesCount == totalActiveEnemies;
}
The Complete Tower Placement Flow
TryPlaceCrystal(tile)
├── [1] Validate tile (not Spawn/Target, tile is empty)
├── [2] Set tile to HexState.Tower (temporarily)
├── [3] Run A* for all SpawnTiles → CheckPlace()
├── [4] Run BFS → CheckDeadlockEnemy()
├── If OK: update LaneService, fire OnMapChanged
└── If FAIL: restore tile to previous state, reject placement
Design Efficiency
A single BFS from one target tile is far cheaper than running A* for every active enemy. On a hex map of roughly 100–200 tiles, the entire validation process completes in microseconds — no lag when the player places a tower.