Performance improvements
This commit is contained in:
@@ -35,7 +35,7 @@ namespace Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, List<Vector2Int> bombCandidates) {
|
public UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, List<Vector2Int> bombCandidates) {
|
||||||
List<Vector2Int> initialBombs = new List<Vector2Int>();
|
HashSet<Vector2Int> initialBombs = new HashSet<Vector2Int>();
|
||||||
foreach (Vector2Int p in bombCandidates) {
|
foreach (Vector2Int p in bombCandidates) {
|
||||||
if (!GemUtils.IsInBounds(p, this.gameBoard)) continue;
|
if (!GemUtils.IsInBounds(p, this.gameBoard)) continue;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ namespace Services
|
|||||||
initialBombs.Add(p);
|
initialBombs.Add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UniTask.FromResult(initialBombs.Distinct().ToList());
|
return UniTask.FromResult(initialBombs.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem) {
|
public List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem) {
|
||||||
@@ -64,7 +64,7 @@ namespace Services
|
|||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DetectBombSpawnFromLastSwap(List<Gem> currentMatches) {
|
public void DetectBombSpawnFromLastSwap(HashSet<Gem> currentMatches) {
|
||||||
Vector2Int from = this.lastSwapFrom;
|
Vector2Int from = this.lastSwapFrom;
|
||||||
Vector2Int to = this.lastSwapTo;
|
Vector2Int to = this.lastSwapTo;
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ namespace Services
|
|||||||
TryCreateBombSpawnAt(to, currentMatches);
|
TryCreateBombSpawnAt(to, currentMatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryCreateBombSpawnAt(Vector2Int pivot, List<Gem> currentMatches) {
|
private void TryCreateBombSpawnAt(Vector2Int pivot, HashSet<Gem> currentMatches) {
|
||||||
Gem pivotGem = this.gameBoard.GetGemAt(pivot);
|
Gem pivotGem = this.gameBoard.GetGemAt(pivot);
|
||||||
if (pivotGem == null)
|
if (pivotGem == null)
|
||||||
return;
|
return;
|
||||||
@@ -81,7 +81,7 @@ namespace Services
|
|||||||
if (pivotGem.Type == GemType.Bomb)
|
if (pivotGem.Type == GemType.Bomb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (currentMatches.All(g => g.Position != pivot))
|
if (currentMatches == null || !currentMatches.Contains(pivotGem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Only create a bomb if pivot is part of a straight 4+ line of the SAME color.
|
// Only create a bomb if pivot is part of a straight 4+ line of the SAME color.
|
||||||
@@ -108,14 +108,14 @@ namespace Services
|
|||||||
|
|
||||||
HashSet<Vector2Int> processedBombs = new HashSet<Vector2Int>();
|
HashSet<Vector2Int> processedBombs = new HashSet<Vector2Int>();
|
||||||
|
|
||||||
Queue<Vector2Int> waveQueue = new Queue<Vector2Int>(
|
Queue<Vector2Int> waveQueue = new Queue<Vector2Int>();
|
||||||
initialBombs.Where(p =>
|
foreach (Vector2Int position in initialBombs) {
|
||||||
{
|
if (GemUtils.IsInBounds(position, gameBoard)) {
|
||||||
if (!GemUtils.IsInBounds(p, gameBoard)) return false;
|
Gem gem = gameBoard.GetGemAt(position);
|
||||||
Gem g = gameBoard.GetGemAt(p);
|
if(gem is { Type: GemType.Bomb })
|
||||||
return g is { Type: GemType.Bomb };
|
waveQueue.Enqueue(position);
|
||||||
})
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
while (waveQueue.Count > 0)
|
while (waveQueue.Count > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace Services {
|
|||||||
|
|
||||||
#region Variables
|
#region Variables
|
||||||
private readonly List<GemPresenter> gemPresenters = new List<GemPresenter>();
|
private readonly List<GemPresenter> gemPresenters = new List<GemPresenter>();
|
||||||
|
private readonly Dictionary<Gem, GemView> gemToView = new Dictionary<Gem, GemView>();
|
||||||
private GameState currentState = GameState.Setup;
|
private GameState currentState = GameState.Setup;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -81,13 +82,13 @@ namespace Services {
|
|||||||
SpawnBackgroundTile(position);
|
SpawnBackgroundTile(position);
|
||||||
|
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
int gemToUse = -1;
|
GemType gemToUse;
|
||||||
do {
|
do {
|
||||||
gemToUse = RandomUtils.RandomGemTypeAsInt();
|
gemToUse = RandomUtils.RandomGemType();
|
||||||
iterations++;
|
iterations++;
|
||||||
} while (this.matchService.MatchesAt(position.ToVector2Int(), (GemType)gemToUse) && iterations < 100);
|
} while (this.matchService.MatchesAt(position.ToVector2Int(), gemToUse) && iterations < 100);
|
||||||
|
|
||||||
gemsToSpawn.Add(SetGemAt(position.ToVector2Int(), (GemType)gemToUse));
|
gemsToSpawn.Add(SetGemAt(position.ToVector2Int(), gemToUse));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnCascade(gemsToSpawn);
|
SpawnCascade(gemsToSpawn);
|
||||||
@@ -108,6 +109,7 @@ namespace Services {
|
|||||||
GemTypeValues gemValue = GemUtils.GetGemValues(gem.MatchColor, this.gameVariables.gemsPrefabs);
|
GemTypeValues gemValue = GemUtils.GetGemValues(gem.MatchColor, this.gameVariables.gemsPrefabs);
|
||||||
gemView.Bind(gem, gemValue, isBomb: isBomb);
|
gemView.Bind(gem, gemValue, isBomb: isBomb);
|
||||||
this.gemPresenters.Add(new GemPresenter(gem, gemView));
|
this.gemPresenters.Add(new GemPresenter(gem, gemView));
|
||||||
|
this.gemToView.Add(gem, gemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAndSpawnGem(Vector2Int position, GemType gemType, bool isBomb) {
|
private void SetAndSpawnGem(Vector2Int position, GemType gemType, bool isBomb) {
|
||||||
@@ -216,7 +218,10 @@ namespace Services {
|
|||||||
|
|
||||||
private async UniTask DestroyMatchesAsync(List<Vector2Int> protectedPositions) {
|
private async UniTask DestroyMatchesAsync(List<Vector2Int> protectedPositions) {
|
||||||
List<Vector2Int> matchPositions = await this.matchService.GetMatchPositionsAsync(protectedPositions);
|
List<Vector2Int> matchPositions = await this.matchService.GetMatchPositionsAsync(protectedPositions);
|
||||||
List<Vector2Int> initialBombs = await this.bombService.GetInitialBombs(protectedPositions, matchPositions.Distinct().ToList());
|
|
||||||
|
HashSet<Vector2Int> uniqueMatchPositions = new HashSet<Vector2Int>(matchPositions);
|
||||||
|
List<Vector2Int> bombCandidates = uniqueMatchPositions.ToList();
|
||||||
|
List<Vector2Int> initialBombs = await this.bombService.GetInitialBombs(protectedPositions, bombCandidates);
|
||||||
|
|
||||||
// If a bomb is part of the match, do NOT destroy matching pieces immediately.
|
// If a bomb is part of the match, do NOT destroy matching pieces immediately.
|
||||||
// Let the bomb's manhattan-distance explosion destroy them in sequence.
|
// Let the bomb's manhattan-distance explosion destroy them in sequence.
|
||||||
@@ -226,7 +231,7 @@ namespace Services {
|
|||||||
DestroyAtAsync,
|
DestroyAtAsync,
|
||||||
this.gameBoard);
|
this.gameBoard);
|
||||||
|
|
||||||
foreach (Vector2Int p in matchPositions.Distinct())
|
foreach (Vector2Int p in uniqueMatchPositions)
|
||||||
await DestroyAtAsync(p);
|
await DestroyAtAsync(p);
|
||||||
|
|
||||||
await UniTask.Delay(this.gameVariables.fillBoardDelayMs);
|
await UniTask.Delay(this.gameVariables.fillBoardDelayMs);
|
||||||
@@ -236,12 +241,19 @@ namespace Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For audio SFX
|
// For audio SFX
|
||||||
bool willBreakAnyNonBombGem = matchPositions.Select(pos => this.gameBoard.GetGemAt(pos)).Where(gem => gem != null).Any(gem => gem.Type != GemType.Bomb);
|
bool willBreakAnyNonBombGem = false;
|
||||||
|
foreach (Vector2Int pos in uniqueMatchPositions) {
|
||||||
|
Gem g = this.gameBoard.GetGemAt(pos);
|
||||||
|
if (g != null && g.Type != GemType.Bomb) {
|
||||||
|
willBreakAnyNonBombGem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (willBreakAnyNonBombGem)
|
if (willBreakAnyNonBombGem)
|
||||||
this.audioPresenter.OnMatch(this.gameVariables.matchSfx);
|
this.audioPresenter.OnMatch(this.gameVariables.matchSfx);
|
||||||
|
|
||||||
// For score counting
|
// For score counting
|
||||||
foreach (Vector2Int pos in matchPositions.Distinct().ToList()) {
|
foreach (Vector2Int pos in uniqueMatchPositions) {
|
||||||
Gem gem = this.gameBoard.GetGemAt(pos);
|
Gem gem = this.gameBoard.GetGemAt(pos);
|
||||||
if (gem == null) continue;
|
if (gem == null) continue;
|
||||||
if (gem.Type == GemType.Bomb) continue;
|
if (gem.Type == GemType.Bomb) continue;
|
||||||
@@ -267,14 +279,11 @@ namespace Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ReleaseMatchedGems(Vector2Int position) {
|
private void ReleaseMatchedGems(Vector2Int position) {
|
||||||
List<GemView> gemsViews = this.gemsHolder.GetComponentsInChildren<GemView>().ToList();
|
|
||||||
Gem currentGem = this.gameBoard.GetGemAt(position);
|
Gem currentGem = this.gameBoard.GetGemAt(position);
|
||||||
if (currentGem != null)
|
if (currentGem != null)
|
||||||
{
|
{
|
||||||
GemView gemView = gemsViews.FirstOrDefault(gv => gv.Gem == currentGem);
|
if (!this.gemToView.TryGetValue(currentGem, out GemView gemView) || gemView == null)
|
||||||
if (gemView is null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
this.objectPool.Release(gemView);
|
this.objectPool.Release(gemView);
|
||||||
RemovePresenterFor(gemView);
|
RemovePresenterFor(gemView);
|
||||||
@@ -283,11 +292,10 @@ namespace Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async UniTask MoveGemsDown() {
|
private async UniTask MoveGemsDown() {
|
||||||
while (true)
|
List<FallMove> moves = new List<FallMove>();
|
||||||
{
|
while (true) {
|
||||||
|
moves.Clear();
|
||||||
// Build moves from a snapshot of the current grid state (no mid-wave chaining)
|
// Build moves from a snapshot of the current grid state (no mid-wave chaining)
|
||||||
List<(Vector2Int from, Vector2Int to, Gem gem)> moves = new List<(Vector2Int, Vector2Int, Gem)>();
|
|
||||||
|
|
||||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||||
{
|
{
|
||||||
for (int y = 1; y < this.gameBoard.Height; y++)
|
for (int y = 1; y < this.gameBoard.Height; y++)
|
||||||
@@ -299,21 +307,21 @@ namespace Services {
|
|||||||
if (gem == null)
|
if (gem == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Gem below = this.gameBoard.GetGemAt(to);
|
if (this.gameBoard.GetGemAt(to) != null)
|
||||||
if (below != null)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
moves.Add((from, to, gem));
|
moves.Add(new FallMove {
|
||||||
|
from = from,
|
||||||
|
to = to,
|
||||||
|
gem = gem
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moves.Count == 0)
|
if (moves.Count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Apply all moves simultaneously for this wave
|
foreach (FallMove move in moves) {
|
||||||
for (int i = 0; i < moves.Count; i++)
|
|
||||||
{
|
|
||||||
(Vector2Int from, Vector2Int to, Gem gem) move = moves[i];
|
|
||||||
this.gameBoard.SetGemAt(move.to, move.gem);
|
this.gameBoard.SetGemAt(move.to, move.gem);
|
||||||
this.gameBoard.SetGemAt(move.from, null);
|
this.gameBoard.SetGemAt(move.from, null);
|
||||||
move.gem.SetPosition(move.to);
|
move.gem.SetPosition(move.to);
|
||||||
@@ -347,12 +355,12 @@ namespace Services {
|
|||||||
{
|
{
|
||||||
Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x,y));
|
Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x,y));
|
||||||
if (currentGem == null) {
|
if (currentGem == null) {
|
||||||
int gemToUse = RandomUtils.RandomGemTypeAsInt();
|
GemType gemToUse = RandomUtils.RandomGemType();
|
||||||
|
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
while (this.matchService.MatchesAt(new Vector2Int(x, y), (GemType)gemToUse) && iterations < 100)
|
while (this.matchService.MatchesAt(new Vector2Int(x, y), (GemType)gemToUse) && iterations < 100)
|
||||||
{
|
{
|
||||||
gemToUse = RandomUtils.RandomGemTypeAsInt();
|
gemToUse = RandomUtils.RandomGemType();
|
||||||
iterations++;
|
iterations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,6 +403,8 @@ namespace Services {
|
|||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
this.objectPool.Clear();
|
this.objectPool.Clear();
|
||||||
|
this.gemPresenters.Clear();
|
||||||
|
this.gemToView.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace Services.Interfaces
|
|||||||
|
|
||||||
void SetLastSwap(Vector2Int from, Vector2Int to);
|
void SetLastSwap(Vector2Int from, Vector2Int to);
|
||||||
|
|
||||||
void DetectBombSpawnFromLastSwap(List<Gem> currentMatches);
|
void DetectBombSpawnFromLastSwap(HashSet<Gem> currentMatches);
|
||||||
List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem);
|
List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem);
|
||||||
UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, List<Vector2Int> bombCandidates);
|
UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, List<Vector2Int> bombCandidates);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Structs;
|
|||||||
|
|
||||||
namespace Services.Interfaces {
|
namespace Services.Interfaces {
|
||||||
public interface IMatchService {
|
public interface IMatchService {
|
||||||
List<Gem> CurrentMatches { get; }
|
HashSet<Gem> CurrentMatches { get; }
|
||||||
UniTask<List<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions);
|
UniTask<List<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions);
|
||||||
bool MatchesAt(Vector2Int positionToCheck, GemType gemTypeToCheck);
|
bool MatchesAt(Vector2Int positionToCheck, GemType gemTypeToCheck);
|
||||||
void FindAllMatches();
|
void FindAllMatches();
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ namespace Services {
|
|||||||
public class MatchService : IMatchService {
|
public class MatchService : IMatchService {
|
||||||
private readonly IGameBoard gameBoard;
|
private readonly IGameBoard gameBoard;
|
||||||
|
|
||||||
|
private readonly HashSet<Gem> currentMatches = new HashSet<Gem>();
|
||||||
private List<Gem> currentMatches = new List<Gem>();
|
public HashSet<Gem> CurrentMatches => this.currentMatches;
|
||||||
public List<Gem> CurrentMatches => this.currentMatches;
|
|
||||||
|
|
||||||
public MatchService(IGameBoard gameBoard) {
|
public MatchService(IGameBoard gameBoard) {
|
||||||
this.gameBoard = gameBoard;
|
this.gameBoard = gameBoard;
|
||||||
@@ -52,9 +51,10 @@ namespace Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public UniTask<List<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions) {
|
public UniTask<List<Vector2Int>> GetMatchPositionsAsync(List<Vector2Int> protectedPositions) {
|
||||||
List<Vector2Int> matchPositions = new List<Vector2Int>(CurrentMatches.Count);
|
List<Vector2Int> matchPositions = new List<Vector2Int>(this.currentMatches.Count);
|
||||||
for (int i = 0; i < CurrentMatches.Count; i++) {
|
List<Gem> matches = this.currentMatches.ToList();
|
||||||
Gem match = CurrentMatches[i];
|
for (int i = 0; i < matches.Count; i++) {
|
||||||
|
Gem match = matches[i];
|
||||||
if (match == null) continue;
|
if (match == null) continue;
|
||||||
|
|
||||||
Vector2Int pos = match.Position;
|
Vector2Int pos = match.Position;
|
||||||
@@ -70,39 +70,59 @@ namespace Services {
|
|||||||
public void FindAllMatches() {
|
public void FindAllMatches() {
|
||||||
this.currentMatches.Clear();
|
this.currentMatches.Clear();
|
||||||
|
|
||||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
Gem[,] grid = this.gameBoard.GemsGrid;
|
||||||
for (int y = 0; y < this.gameBoard.Height; y++) {
|
int boardWidth = this.gameBoard.Width;
|
||||||
Gem currentGem = this.gameBoard.GemsGrid[x, y];
|
int boardHeight = this.gameBoard.Height;
|
||||||
if (currentGem == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (x > 0 && x < this.gameBoard.Width - 1) {
|
// Horizontal runs
|
||||||
Gem leftGem = this.gameBoard.GemsGrid[x - 1, y];
|
for (int y = 0; y < boardHeight; y++) {
|
||||||
Gem rightGem = this.gameBoard.GemsGrid[x + 1, y];
|
int x = 0;
|
||||||
if (leftGem != null && rightGem != null) {
|
while (x < boardWidth) {
|
||||||
if (leftGem.MatchColor == currentGem.MatchColor && rightGem.MatchColor == currentGem.MatchColor) {
|
Gem start = grid[x, y];
|
||||||
this.currentMatches.Add(currentGem);
|
if (start == null) { x++; continue; }
|
||||||
this.currentMatches.Add(leftGem);
|
|
||||||
this.currentMatches.Add(rightGem);
|
GemType color = start.MatchColor;
|
||||||
|
|
||||||
|
int runLen = 1;
|
||||||
|
while (x + runLen < boardWidth) {
|
||||||
|
Gem next = grid[x + runLen, y];
|
||||||
|
if (next == null || next.MatchColor != color) break;
|
||||||
|
runLen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (runLen >= 3) {
|
||||||
|
for (int i = 0; i < runLen; i++)
|
||||||
|
this.currentMatches.Add(grid[x + i, y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
x += runLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y > 0 && y < this.gameBoard.Height - 1) {
|
// Vertical runs
|
||||||
Gem aboveGem = this.gameBoard.GemsGrid[x, y - 1];
|
for (int x = 0; x < boardWidth; x++) {
|
||||||
Gem bellowGem = this.gameBoard.GemsGrid[x, y + 1];
|
int y = 0;
|
||||||
if (aboveGem != null && bellowGem != null) {
|
while (y < boardHeight) {
|
||||||
if (aboveGem.MatchColor == currentGem.MatchColor && bellowGem.MatchColor == currentGem.MatchColor) {
|
Gem start = grid[x, y];
|
||||||
this.currentMatches.Add(currentGem);
|
if (start == null) { y++; continue; }
|
||||||
this.currentMatches.Add(aboveGem);
|
|
||||||
this.currentMatches.Add(bellowGem);
|
GemType color = start.MatchColor;
|
||||||
}
|
|
||||||
}
|
int runLen = 1;
|
||||||
}
|
while (y + runLen < boardHeight) {
|
||||||
|
Gem next = grid[x, y + runLen];
|
||||||
|
if (next == null || next.MatchColor != color) break;
|
||||||
|
runLen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.currentMatches.Count > 0)
|
if (runLen >= 3) {
|
||||||
this.currentMatches = this.currentMatches.Distinct().ToList();
|
for (int i = 0; i < runLen; i++)
|
||||||
|
this.currentMatches.Add(grid[x, y + i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += runLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
10
Assets/Scripts/Structs/FallMove.cs
Normal file
10
Assets/Scripts/Structs/FallMove.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Services;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Structs {
|
||||||
|
public struct FallMove {
|
||||||
|
public Vector2Int from;
|
||||||
|
public Vector2Int to;
|
||||||
|
public Gem gem;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Scripts/Structs/FallMove.cs.meta
Normal file
3
Assets/Scripts/Structs/FallMove.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 420c7135e99442e280e7ac7439d5c702
|
||||||
|
timeCreated: 1765995012
|
||||||
@@ -5,13 +5,33 @@ using Random = UnityEngine.Random;
|
|||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
public static class RandomUtils {
|
public static class RandomUtils {
|
||||||
public static int RandomGemTypeAsInt() {
|
private static readonly GemType[] spawnableGems = BuildSpawnableGems();
|
||||||
GemType[] spawnableGems = Enum.GetValues(typeof(GemType))
|
|
||||||
.Cast<GemType>()
|
|
||||||
.Where(gType => gType != GemType.Bomb)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
return Random.Range(0, spawnableGems.Length);
|
private static GemType[] BuildSpawnableGems() {
|
||||||
|
Array values = Enum.GetValues(typeof(GemType));
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < values.Length; i++) {
|
||||||
|
if ((GemType)values.GetValue(i) != GemType.Bomb)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GemType[] result = new GemType[count];
|
||||||
|
int write = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < values.Length; i++) {
|
||||||
|
GemType t = (GemType)values.GetValue(i);
|
||||||
|
if (t == GemType.Bomb)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result[write++] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GemType RandomGemType() {
|
||||||
|
return spawnableGems[Random.Range(0, spawnableGems.Length)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user