Fixed Bomb Spawning

This commit is contained in:
2025-12-19 17:18:18 +08:00
parent 73db75d40a
commit e2409106d4
4 changed files with 20 additions and 35 deletions

View File

@@ -19,7 +19,7 @@ namespace Services
private Vector2Int lastSwapFrom; private Vector2Int lastSwapFrom;
private Vector2Int lastSwapTo; private Vector2Int lastSwapTo;
private BombSpawnRequest? pendingBombSpawn; private List<BombSpawnRequest> pendingBombSpawns = new List<BombSpawnRequest>();
public BombService(GameVariables gameVariables, IGameBoard gameBoard) { public BombService(GameVariables gameVariables, IGameBoard gameBoard) {
this.gameVariables = gameVariables; this.gameVariables = gameVariables;
@@ -51,10 +51,8 @@ namespace Services
public List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem) { public List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem) {
List<Vector2Int> positions = new List<Vector2Int>(); List<Vector2Int> positions = new List<Vector2Int>();
BombSpawnRequest? bombSpawnRequest = this.pendingBombSpawn;
if (bombSpawnRequest != null) { foreach (BombSpawnRequest bombRequest in this.pendingBombSpawns) {
BombSpawnRequest bombRequest = this.pendingBombSpawn.GetValueOrDefault();
positions.Add(bombRequest.Position); positions.Add(bombRequest.Position);
spawnGem(bombRequest.Position, bombRequest.Color, true); spawnGem(bombRequest.Position, bombRequest.Color, true);
} }
@@ -89,10 +87,10 @@ namespace Services
return; return;
// Prevent duplicates for the same cell. // Prevent duplicates for the same cell.
if (this.pendingBombSpawn.GetValueOrDefault().Position == pivot) if (this.pendingBombSpawns.Any(b => b.Position == pivot))
return; return;
this.pendingBombSpawn = new BombSpawnRequest(pivot, pivotGem.MatchColor); this.pendingBombSpawns.Add(new BombSpawnRequest(pivot, pivotGem.MatchColor));
} }
private bool IsEligibleForBomb(Vector2Int pivot, GemType color) { private bool IsEligibleForBomb(Vector2Int pivot, GemType color) {
@@ -115,8 +113,7 @@ namespace Services
public async UniTask DetonateChainAsync( public async UniTask DetonateChainAsync(
IReadOnlyList<Vector2Int> initialBombs, IReadOnlyList<Vector2Int> initialBombs,
Func<Vector2Int, UniTask> destroyAtAsync, Func<Vector2Int, UniTask> destroyAtAsync)
IGameBoard gameBoard)
{ {
if (initialBombs == null || initialBombs.Count == 0) if (initialBombs == null || initialBombs.Count == 0)
return; return;
@@ -127,8 +124,8 @@ namespace Services
Queue<Vector2Int> waveQueue = new Queue<Vector2Int>(); Queue<Vector2Int> waveQueue = new Queue<Vector2Int>();
foreach (Vector2Int position in initialBombs) { foreach (Vector2Int position in initialBombs) {
if (GemUtils.IsInBounds(position, gameBoard)) { if (GemUtils.IsInBounds(position, this.gameBoard)) {
Gem gem = gameBoard.GetGemAt(position); Gem gem = this.gameBoard.GetGemAt(position);
if(gem is { Type: GemType.Bomb }) if(gem is { Type: GemType.Bomb })
waveQueue.Enqueue(position); waveQueue.Enqueue(position);
} }
@@ -141,10 +138,10 @@ namespace Services
if (processedBombs.Contains(bombPos)) if (processedBombs.Contains(bombPos))
continue; continue;
if (!GemUtils.IsInBounds(bombPos, gameBoard)) if (!GemUtils.IsInBounds(bombPos, this.gameBoard))
continue; continue;
Gem g = gameBoard.GetGemAt(bombPos); Gem g = this.gameBoard.GetGemAt(bombPos);
if (g is not { Type: GemType.Bomb }) if (g is not { Type: GemType.Bomb })
continue; continue;
@@ -159,13 +156,13 @@ namespace Services
foreach (Vector2Int position in DiamondAreaInclusive(bombPos, this.gameVariables.bombRadius)) foreach (Vector2Int position in DiamondAreaInclusive(bombPos, this.gameVariables.bombRadius))
{ {
if (!GemUtils.IsInBounds(position, gameBoard)) if (!GemUtils.IsInBounds(position, this.gameBoard))
continue; continue;
if (position == bombPos) if (position == bombPos)
continue; continue;
Gem cellGem = gameBoard.GetGemAt(position); Gem cellGem = this.gameBoard.GetGemAt(position);
if (cellGem == null) if (cellGem == null)
continue; continue;
@@ -201,16 +198,6 @@ namespace Services
} }
} }
private int GetLongestMatchedLineThroughPivot(Vector2Int pivot, GemType color) {
int horizontal = 1 + CountSameColorInDirection(pivot, Vector2Int.left, color)
+ CountSameColorInDirection(pivot, Vector2Int.right, color);
int vertical = 1 + CountSameColorInDirection(pivot, Vector2Int.up, color)
+ CountSameColorInDirection(pivot, Vector2Int.down, color);
return Mathf.Max(horizontal, vertical);
}
private int CountSameColorInDirection(Vector2Int start, Vector2Int direction, GemType color) { private int CountSameColorInDirection(Vector2Int start, Vector2Int direction, GemType color) {
int count = 0; int count = 0;
Vector2Int pivot = start + direction; Vector2Int pivot = start + direction;
@@ -228,7 +215,7 @@ namespace Services
} }
private void ClearPendingBombs() { private void ClearPendingBombs() {
this.pendingBombSpawn = null; this.pendingBombSpawns.Clear();
} }
} }
} }

View File

@@ -296,8 +296,7 @@ namespace Services {
if (initialBombs.Count > 0) { if (initialBombs.Count > 0) {
await this.bombService.DetonateChainAsync( await this.bombService.DetonateChainAsync(
initialBombs, initialBombs,
DestroyAtAsync, DestroyAtAsync);
this.gameBoard);
foreach (Vector2Int p in matchPositions) foreach (Vector2Int p in matchPositions)
await DestroyAtAsync(p); await DestroyAtAsync(p);

View File

@@ -38,7 +38,9 @@ namespace Services.Interfaces
/// <param name="bombCandidates"> /// <param name="bombCandidates">
/// Possible bombs. /// Possible bombs.
/// </param> /// </param>
/// <returns></returns> /// <returns>
/// List of Bombs.
/// </returns>
UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, HashSet<Vector2Int> bombCandidates); UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, HashSet<Vector2Int> bombCandidates);
/// <summary> /// <summary>
@@ -50,13 +52,8 @@ namespace Services.Interfaces
/// <param name="destroyAtAsync"> /// <param name="destroyAtAsync">
/// Destroy function reference. /// Destroy function reference.
/// </param> /// </param>
/// <param name="gameBoard">
/// Gameboard reference.
/// </param>
/// <returns></returns>
UniTask DetonateChainAsync( UniTask DetonateChainAsync(
IReadOnlyList<Vector2Int> initialBombs, IReadOnlyList<Vector2Int> initialBombs,
Func<Vector2Int, UniTask> destroyAtAsync, Func<Vector2Int, UniTask> destroyAtAsync);
IGameBoard gameBoard);
} }
} }

View File

@@ -12,7 +12,9 @@ namespace Services.Interfaces {
/// <param name="protectedPositions"> /// <param name="protectedPositions">
/// Protected positions, bombs that we don't want to destroy. /// Protected positions, bombs that we don't want to destroy.
/// </param> /// </param>
/// <returns></returns> /// <returns>
/// HashSet of unprotected matches.
/// </returns>
UniTask<HashSet<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions); UniTask<HashSet<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions);
/// <summary> /// <summary>