Cleanup
This commit is contained in:
@@ -3,10 +3,10 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Services {
|
namespace Services {
|
||||||
public class GameBoard : IGameBoard {
|
public class GameBoard : IGameBoard {
|
||||||
private int height, width;
|
private readonly int height, width;
|
||||||
public int Height => this.height;
|
public int Height => this.height;
|
||||||
public int Width => this.width;
|
public int Width => this.width;
|
||||||
private Gem[,] gemsGrid;
|
private readonly Gem[,] gemsGrid;
|
||||||
public Gem[,] GemsGrid => this.gemsGrid;
|
public Gem[,] GemsGrid => this.gemsGrid;
|
||||||
|
|
||||||
public GameBoard(int width, int height) {
|
public GameBoard(int width, int height) {
|
||||||
@@ -17,7 +17,7 @@ namespace Services {
|
|||||||
|
|
||||||
public Gem GetGemAt(Vector2Int pos) {
|
public Gem GetGemAt(Vector2Int pos) {
|
||||||
Gem gameObject = this.gemsGrid[pos.x, pos.y];
|
Gem gameObject = this.gemsGrid[pos.x, pos.y];
|
||||||
return gameObject != null ? gameObject : null;
|
return gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetGemAt(Vector2Int pos, Gem gameObject) {
|
public void SetGemAt(Vector2Int pos, Gem gameObject) {
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Services {
|
namespace Services {
|
||||||
public class Gem {
|
public class Gem {
|
||||||
private GemType type;
|
private readonly GemType type;
|
||||||
private Vector2Int position;
|
private Vector2Int position;
|
||||||
public GemType Type => this.type;
|
public GemType Type => this.type;
|
||||||
public Vector2Int Position => this.position;
|
public Vector2Int Position => this.position;
|
||||||
|
|
||||||
private int scoreValue;
|
private readonly int scoreValue;
|
||||||
public int ScoreValue => this.scoreValue;
|
public int ScoreValue => this.scoreValue;
|
||||||
|
|
||||||
private GemType colorType;
|
private readonly GemType colorType;
|
||||||
public GemType MatchColor => this.type == GemType.Bomb ? this.colorType : this.type;
|
public GemType MatchColor => this.type == GemType.Bomb ? this.colorType : this.type;
|
||||||
|
|
||||||
public Gem(GemType type, Vector2Int position, GemTypeValues gemValue, GemType? colorType = null) {
|
public Gem(GemType type, Vector2Int position, GemTypeValues gemValue, GemType? colorType = null) {
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
using Services;
|
using Services;
|
||||||
using UnityEngine;
|
|
||||||
using Utils;
|
using Utils;
|
||||||
using VContainer.Unity;
|
|
||||||
using Views;
|
using Views;
|
||||||
|
|
||||||
namespace Presenter {
|
namespace Presenter {
|
||||||
public class GemPresenter {
|
public class GemPresenter {
|
||||||
private Gem gem;
|
private readonly Gem gem;
|
||||||
private GemView gemView;
|
private readonly GemView gemView;
|
||||||
|
|
||||||
public Gem Gem => this.gem;
|
public Gem Gem => this.gem;
|
||||||
public GemView GemView => this.gemView;
|
public GemView GemView => this.gemView;
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using Services.Interfaces;
|
using Services.Interfaces;
|
||||||
using VContainer.Unity;
|
|
||||||
using Views;
|
using Views;
|
||||||
|
|
||||||
namespace Presenter {
|
namespace Presenter {
|
||||||
public class ScorePresenter : IDisposable{
|
public class ScorePresenter : IDisposable{
|
||||||
private IScoreService scoreService;
|
private readonly IScoreService scoreService;
|
||||||
private ScoreView scoreView;
|
private readonly ScoreView scoreView;
|
||||||
public ScorePresenter(IScoreService scoreService, ScoreView scoreView) {
|
public ScorePresenter(IScoreService scoreService, ScoreView scoreView) {
|
||||||
this.scoreService = scoreService;
|
this.scoreService = scoreService;
|
||||||
this.scoreView = scoreView;
|
this.scoreView = scoreView;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Models;
|
|
||||||
using Models.Interfaces;
|
using Models.Interfaces;
|
||||||
using Presenter;
|
using Presenter;
|
||||||
using ScriptableObjects;
|
using ScriptableObjects;
|
||||||
@@ -23,14 +22,14 @@ namespace Scopes
|
|||||||
|
|
||||||
builder.RegisterComponentInHierarchy<ScoreView>();
|
builder.RegisterComponentInHierarchy<ScoreView>();
|
||||||
|
|
||||||
builder.Register<IGameBoard>(c =>
|
builder.Register<IGameBoard>(_ =>
|
||||||
new GameBoard(this.gameVariables.width, this.gameVariables.height),
|
new GameBoard(this.gameVariables.width, this.gameVariables.height),
|
||||||
Lifetime.Scoped);
|
Lifetime.Scoped);
|
||||||
|
|
||||||
builder.Register<IMatchService, MatchService>(Lifetime.Scoped);
|
builder.Register<IMatchService, MatchService>(Lifetime.Scoped);
|
||||||
builder.Register<IScoreService, ScoreService>(Lifetime.Scoped);
|
builder.Register<IScoreService, ScoreService>(Lifetime.Scoped);
|
||||||
|
|
||||||
builder.Register<IObjectPool<GemView>>(c =>
|
builder.Register<IObjectPool<GemView>>(_ =>
|
||||||
new ObjectPoolService(this.gameVariables.gemsPrefabs, this.gemsHolder),
|
new ObjectPoolService(this.gameVariables.gemsPrefabs, this.gemsHolder),
|
||||||
Lifetime.Scoped);
|
Lifetime.Scoped);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Enums;
|
|
||||||
using Structs;
|
using Structs;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Views;
|
|
||||||
|
|
||||||
namespace ScriptableObjects {
|
namespace ScriptableObjects {
|
||||||
[CreateAssetMenu(fileName = "GameVariables", menuName = "Game Variables")]
|
[CreateAssetMenu(fileName = "GameVariables", menuName = "Game Variables")]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using Enums;
|
using Enums;
|
||||||
using Models;
|
|
||||||
using Services.Interfaces;
|
using Services.Interfaces;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ using Utils;
|
|||||||
using VContainer.Unity;
|
using VContainer.Unity;
|
||||||
using Views;
|
using Views;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
using Random = UnityEngine.Random;
|
|
||||||
|
|
||||||
namespace Services {
|
namespace Services {
|
||||||
public class GameBoardService : IGameBoardService, ITickable, IDisposable {
|
public class GameBoardService : IGameBoardService, ITickable, IDisposable {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Services {
|
|||||||
|
|
||||||
private void TryEmitSwap(Vector2 downScreen, Vector2 upScreen)
|
private void TryEmitSwap(Vector2 downScreen, Vector2 upScreen)
|
||||||
{
|
{
|
||||||
if (this.inputCamera == null) return;
|
if (this.inputCamera is null) return;
|
||||||
|
|
||||||
Vector2 downWorld = this.inputCamera.ScreenToWorldPoint(downScreen);
|
Vector2 downWorld = this.inputCamera.ScreenToWorldPoint(downScreen);
|
||||||
Vector2 upWorld = this.inputCamera.ScreenToWorldPoint(upScreen);
|
Vector2 upWorld = this.inputCamera.ScreenToWorldPoint(upScreen);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using Enums;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Views;
|
|
||||||
|
|
||||||
namespace Services.Interfaces {
|
namespace Services.Interfaces {
|
||||||
public interface IGameBoardService {
|
public interface IGameBoardService {
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ namespace Services {
|
|||||||
private List<Gem> currentMatches = new List<Gem>();
|
private List<Gem> currentMatches = new List<Gem>();
|
||||||
public List<Gem> CurrentMatches => this.currentMatches;
|
public List<Gem> CurrentMatches => this.currentMatches;
|
||||||
|
|
||||||
public List<BombSpawnRequest> pendingBombSpawns = new List<BombSpawnRequest>();
|
private readonly List<BombSpawnRequest> pendingBombSpawns = new List<BombSpawnRequest>();
|
||||||
public IReadOnlyList<BombSpawnRequest> PendingBombSpawns => this.pendingBombSpawns;
|
public IReadOnlyList<BombSpawnRequest> PendingBombSpawns => this.pendingBombSpawns;
|
||||||
|
|
||||||
private Vector2Int lastSwapFrom;
|
private Vector2Int lastSwapFrom;
|
||||||
private Vector2Int lastSwapTo;
|
private Vector2Int lastSwapTo;
|
||||||
|
|
||||||
private IGameBoard gameBoard;
|
private readonly IGameBoard gameBoard;
|
||||||
|
|
||||||
public MatchService(IGameBoard gameBoard) {
|
public MatchService(IGameBoard gameBoard) {
|
||||||
this.gameBoard = gameBoard;
|
this.gameBoard = gameBoard;
|
||||||
@@ -125,9 +125,9 @@ namespace Services {
|
|||||||
if (this.currentMatches.All(g => g.Position != pivot))
|
if (this.currentMatches.All(g => g.Position != pivot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If the matched group that includes this pivot has 4+ connected gems, spawn a bomb.
|
// Only create a bomb if pivot is part of a straight 4+ line of the SAME color.
|
||||||
int groupSize = GetMatchedGroupSize(pivot);
|
int longestLine = GetLongestMatchedLineThroughPivot(pivot, pivotGem.MatchColor);
|
||||||
if (groupSize < 4)
|
if (longestLine < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Prevent duplicates for the same cell.
|
// Prevent duplicates for the same cell.
|
||||||
@@ -137,52 +137,30 @@ namespace Services {
|
|||||||
this.pendingBombSpawns.Add(new BombSpawnRequest(pivot, pivotGem.MatchColor));
|
this.pendingBombSpawns.Add(new BombSpawnRequest(pivot, pivotGem.MatchColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetMatchedGroupSize(Vector2Int pivot) {
|
private int GetLongestMatchedLineThroughPivot(Vector2Int pivot, GemType color) {
|
||||||
Gem pivotGem = this.gameBoard.GetGemAt(pivot);
|
int horizontal = 1 + CountSameColorInDirection(pivot, Vector2Int.left, color)
|
||||||
if (pivotGem == null)
|
+ CountSameColorInDirection(pivot, Vector2Int.right, color);
|
||||||
return 0;
|
|
||||||
|
|
||||||
GemType color = pivotGem.MatchColor;
|
int vertical = 1 + CountSameColorInDirection(pivot, Vector2Int.up, color)
|
||||||
|
+ CountSameColorInDirection(pivot, Vector2Int.down, color);
|
||||||
|
|
||||||
HashSet<Vector2Int> matchedPositions = new HashSet<Vector2Int>(
|
return Mathf.Max(horizontal, vertical);
|
||||||
this.currentMatches
|
}
|
||||||
.Where(g => g != null && g.MatchColor == color)
|
|
||||||
.Select(g => g.Position)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!matchedPositions.Contains(pivot))
|
private int CountSameColorInDirection(Vector2Int start, Vector2Int direction, GemType color) {
|
||||||
return 0;
|
int count = 0;
|
||||||
|
Vector2Int oivot = start + direction;
|
||||||
|
|
||||||
Queue<Vector2Int> queue = new Queue<Vector2Int>();
|
while (oivot.x >= 0 && oivot.x < this.gameBoard.Width && oivot.y >= 0 && oivot.y < this.gameBoard.Height) {
|
||||||
HashSet<Vector2Int> visited = new HashSet<Vector2Int>();
|
Gem g = this.gameBoard.GetGemAt(oivot);
|
||||||
|
if (g == null || g.Type == GemType.Bomb || g.MatchColor != color)
|
||||||
|
break;
|
||||||
|
|
||||||
queue.Enqueue(pivot);
|
count++;
|
||||||
visited.Add(pivot);
|
oivot += direction;
|
||||||
|
|
||||||
Vector2Int[] directions = {
|
|
||||||
Vector2Int.left,
|
|
||||||
Vector2Int.right,
|
|
||||||
Vector2Int.up,
|
|
||||||
Vector2Int.down
|
|
||||||
};
|
|
||||||
|
|
||||||
while (queue.Count > 0) {
|
|
||||||
Vector2Int currentPivot = queue.Dequeue();
|
|
||||||
|
|
||||||
for (int i = 0; i < directions.Length; i++) {
|
|
||||||
Vector2Int n = currentPivot + directions[i];
|
|
||||||
if (visited.Contains(n))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!matchedPositions.Contains(n))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
visited.Add(n);
|
|
||||||
queue.Enqueue(n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return visited.Count;
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using Enums;
|
|
||||||
using Services;
|
using Services;
|
||||||
using Structs;
|
using Structs;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using System;
|
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Views {
|
namespace Views {
|
||||||
public class ScoreView : MonoBehaviour {
|
public class ScoreView : MonoBehaviour {
|
||||||
private TextMeshProUGUI scoreText;
|
private TextMeshProUGUI scoreText;
|
||||||
private float displayScore = 0;
|
private float displayScore;
|
||||||
private int actualScore = 0;
|
private int actualScore;
|
||||||
|
|
||||||
private void Awake() {
|
private void Awake() {
|
||||||
this.scoreText = GetComponentInChildren<TextMeshProUGUI>();
|
this.scoreText = GetComponentInChildren<TextMeshProUGUI>();
|
||||||
|
|||||||
Reference in New Issue
Block a user