[DB-AL] Besoin d'aide pour la création d'un match3

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Khyinn
Messages : 3
Inscription : 09 Mars 2017 21:04

[DB-AL] Besoin d'aide pour la création d'un match3

Message par Khyinn » 09 Mars 2017 21:32

Bonjour,

Je suis nouveau dans Unity et C# et je cherche à apprendre en créant un jeu 2D de type Match 3 (Candy Crush, Bejeweled, etc).

Mon projet a bien avancé grace à un cours que j'ai suivi sur le sujet. Aujourd'hui, j'essaie d'étendre les fonctionnalités du jeu étudié en me basant sur son code pour l'étendre selon mes besoins.
Actuellement, le jeu permet de réaliser des "match" de 3 ou + pieces de même couleur dans une grille à 4 côtés (type carré, rectangle). Lorsqu'on réalise un "match", les pièces correspondantes sont détruites et les pièces au dessus viennent combler le trou laissé dans la grille. De nouvelles pièces viennent ensuite en haut de la grille afin qu'elle soit toujours complète.

Nous avons donc ici différentes pièces (et donc plusieurs Prefab) :

- PieceBG qui est un Prefab contenant un simple Sprite qui définira le "fond" des pièces sur la grille, aucun fond pour les pièces de type NONE;

- EmptyPiecePrefab est simplement un GameObject "vide". Il a le script GamePiece attaché pour la gestion du remplacement des pièces dans la grille (voir plus bas le script);

- NormalPiecePrefab contient une pièce normale qui peut prendre différentes couleurs;

- ColumnClearPiecePrefab est un dérivé de NormalPiecePrefab qui gérera la destruction de toutes les pièces d'une même colonne;

- RowClearPiecePrefab, idem que celui-ci dessus mais pour les "lignes".

Je ne vais pas mettre tous les scripts ici car ce n'est pas vraiment nécessaire, seule le script Grid est nécessaire pour le moment.

Voici les fonctionnalités/correction que j'aimerais ajouter/apporter :

- Permettre la création d'une grille "à trous" ou de forme variée (exemple une grille en forme de +). C'est codé en grande partie maintenant mais il reste un problème : actuellement, la grille se remplit "par le haut". Donc, si le "haut" de la grille est "bouché" par des pièces de type ROCK (indestructibles, non Movable), ICE (destructibles mais non Movable) ou NONE (justement un type de pièce permettant de dessiner une grille de forme autre que carré/rectangle, non Movable), elle ne se remplira pas. Il faut donc modifier FillStep() et SpawnNewPiece à mon avis pour permettre de remplir la grille en tenant compte de ces pièces.

- Corriger la fonction Shuffle pour qu'au lieu de changer aléatoirement la couleur des pièces "Movable", elle les déplace dans la grille.

- Ajouter un système de récolte d'ingrédients. Mais ça, c'est pour plus tard si je trouve quelqu'un pour m'aider.

Je précise qu'étant débutant, j'aimerais bien qu'on m'explique les modifications apportées au code afin que je profite au mieux de votre expérience :)

Et maintenant, voici le script Grid.cs. Si besoin, je peux fournir un certain type de script sur demande mais je ne pense pas que ce soit utile pour le moment, ce le sera probablement pour la partie ingrédients.

Code : Tout sélectionner

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Grid : MonoBehaviour {

	public enum PieceType
	{
		EMPTY,
		NORMAL,
		ICE,
		ROW_CLEAR,
		COLUMN_CLEAR,
		RAINBOW,
		NONE,
		ROCK,
		COUNT,
	};

	[System.Serializable]
	public struct PiecePrefab
	{
		public PieceType type;
		public GameObject prefab;
	};

	[System.Serializable]
	public struct PiecePosition
	{
		public PieceType type;
		public int x;
		public int y;
	};

	// Grid size
	public int xDim;
	public int yDim;
	// Time to fill/refill the grid
	public float fillTime;

	// Used to call the level class
	public Level level;

	// Array of piece types that can be defined in the inspector
	public PiecePrefab[] piecePrefabs;
	// GameObject to set a background for our pieces
	public GameObject backgroundPrefab;

	// Used to set our initial pieces in the inspector, for each level
	public PiecePosition[] initialPieces;

	// Dictionary for attaching a piece to its prefab
	private Dictionary<PieceType, GameObject> piecePrefabDict;

	// 2D array to contain all our pieces
	private GamePiece[,] pieces;

	// Used to move pieces in diag (for filling a grid with obstacles)
	private bool inverse = false;

	// Used to know wich pieces will be swapped
	private GamePiece pressedPiece;
	private GamePiece enteredPiece;

	Coroutine co;
	private bool coroutineIsRunning;

	// Set the game over. Doesn't mean that the player loose
	private bool gameOver = false;

	// Use this for initialization
	void Awake () {
		piecePrefabDict = new Dictionary<PieceType, GameObject> ();

		// First we need to check if we have keys in our dictionary. If not, add them
		for (int i = 0; i < piecePrefabs.Length; i++) {
			if (!piecePrefabDict.ContainsKey (piecePrefabs [i].type)) {
				piecePrefabDict.Add (piecePrefabs [i].type, piecePrefabs [i].prefab);
			}
		}

		// Now we need to add our initial and empty pieces on the grid
		pieces = new GamePiece[xDim, yDim];

		for (int i = 0; i < initialPieces.Length; i++) {
			if (initialPieces [i].x >= 0 && initialPieces [i].x < xDim
				&& initialPieces [i].y >= 0 && initialPieces [i].y < yDim) {
				SpawnNewPiece (initialPieces [i].x, initialPieces [i].y, initialPieces [i].type);
			}
		}

		// Instantiate the background for all our pieces on the grid
		for (int x = 0; x < xDim; x++) {
			for (int y = 0; y < yDim; y++) {
				if (pieces [x, y] == null || pieces [x, y].Type != PieceType.NONE) { // No background for NONE pieces
					GameObject background = (GameObject)Instantiate (backgroundPrefab, GetWorldPosition (x, y), Quaternion.identity);
					background.transform.parent = transform;
				}
			}
		}

		for (int x = 0; x < xDim; x++) {
			for (int y = 0; y < yDim; y++) {
				if (pieces [x, y] == null) {
					SpawnNewPiece (x, y, PieceType.EMPTY);
				}
			}
		}

		// Now the grid is filled with empty pieces, we need to replace them by our non-empty pieces with animation
		StartCoroutine(Fill ());
	}

	// Update is called once per frame
	void Update () {

	}

	// Fill the grid
	public IEnumerator Fill()
	{
		bool needsRefill = true;
		if (coroutineIsRunning) {
			StopCoroutine (co);
		}

		while (needsRefill) {
			yield return new WaitForSeconds (fillTime);

			while (FillStep ()) {
				inverse = !inverse;
				yield return new WaitForSeconds (fillTime);
			}
			needsRefill = ClearAllValidMatches ();
		}
		co = StartCoroutine (advert());
	}

	// Move a piece to fill the grid
	// Todo : add a check for ROCK Pieces so that they'll be ignored when filling the grid as they can't be destroyed and can be on top of the grid
	public bool FillStep()
	{
		bool movedPiece = false;

		for (int y = yDim-2; y >= 0; y--)
		{
			for (int loopX = 0; loopX < xDim; loopX++)
			{
				int x = loopX;

				if (inverse) {
					x = xDim - 1 - loopX;
				}

				GamePiece piece = pieces [x, y];

				if (piece.IsMovable ())
				{
					GamePiece pieceBelow = pieces [x, y + 1];

					if (pieceBelow.Type == PieceType.EMPTY) {
						Destroy (pieceBelow.gameObject);
						piece.MovableComponent.Move (x, y + 1, fillTime);
						pieces [x, y + 1] = piece;
						SpawnNewPiece (x, y, PieceType.EMPTY);
						movedPiece = true;
					} else {
						for (int diag = -1; diag <= 1; diag++)
						{
							if (diag != 0)
							{
								int diagX = x + diag;

								if (inverse)
								{
									diagX = x - diag;
								}

								if (diagX >= 0 && diagX < xDim)
								{
									GamePiece diagonalPiece = pieces [diagX, y + 1];

									if (diagonalPiece.Type == PieceType.EMPTY)
									{
										bool hasPieceAbove = true;

										for (int aboveY = y; aboveY >= 0; aboveY--)
										{
											GamePiece pieceAbove = pieces [diagX, aboveY];

											if (pieceAbove.IsMovable ())
											{
												break;
											}
											else if(!pieceAbove.IsMovable() && pieceAbove.Type != PieceType.EMPTY)
											{
												hasPieceAbove = false;
												break;
											}
										}

										if (!hasPieceAbove)
										{
											Destroy (diagonalPiece.gameObject);
											piece.MovableComponent.Move (diagX, y + 1, fillTime);
											pieces [diagX, y + 1] = piece;
											SpawnNewPiece (x, y, PieceType.EMPTY);
											movedPiece = true;
											break;
										}
									} 
								}
							}
						}
					}
				}
			}
		}

		for (int x = 0; x < xDim; x++)
		{
			GamePiece pieceBelow = pieces [x, 0];

			if (pieceBelow.Type == PieceType.EMPTY)
			{
				Destroy (pieceBelow.gameObject);
				GameObject newPiece = (GameObject)Instantiate(piecePrefabDict[PieceType.NORMAL], GetWorldPosition(x, -1), Quaternion.identity);
				newPiece.transform.parent = transform;

				pieces [x, 0] = newPiece.GetComponent<GamePiece> ();
				pieces [x, 0].Init (x, -1, this, PieceType.NORMAL);
				pieces [x, 0].MovableComponent.Move (x, 0, fillTime);
				pieces [x, 0].ColorComponent.SetColor ((ColorPiece.ColorType)Random.Range (0, pieces [x, 0].ColorComponent.NumColors));
				movedPiece = true;
			}
		}

		return movedPiece;
	}

	// Used to get the offset of our pieces
	public Vector2 GetWorldPosition(int x, int y)
	{
		return new Vector2 (transform.position.x - xDim / 2.0f + x,
			transform.position.y + yDim / 2.0f - y);
	}

	// Spawn a new piece
	public GamePiece SpawnNewPiece(int x, int y, PieceType type)
	{
		GameObject newPiece = (GameObject)Instantiate (piecePrefabDict [type], GetWorldPosition (x, y), Quaternion.identity);
		newPiece.transform.parent = transform;

		pieces [x, y] = newPiece.GetComponent<GamePiece> ();
		pieces [x, y].Init (x, y, this, type);

		return pieces [x, y];
	}

	// Used to know if piece1 is adjacent to piece2
	public bool IsAdjacent(GamePiece piece1, GamePiece piece2)
	{
		return (piece1.X == piece2.X && (int)Mathf.Abs (piece1.Y - piece2.Y) == 1)
			|| (piece1.Y == piece2.Y && (int)Mathf.Abs (piece1.X - piece2.X) == 1);
	}

	// Swap pieces if they are adjacent
	public void SwapPieces(GamePiece piece1, GamePiece piece2)
	{
		// If the game is over, just disabled this function
		if (gameOver) {
			return;
		}

		// Swap only if they are movable
		if (piece1.IsMovable () && piece2.IsMovable ()) {
			pieces [piece1.X, piece1.Y] = piece2;
			pieces [piece2.X, piece2.Y] = piece1;

			if (GetMatch (piece1, piece2.X, piece2.Y) != null || GetMatch (piece2, piece1.X, piece1.Y) != null
				|| piece1.Type == PieceType.RAINBOW || piece2.Type == PieceType.RAINBOW) {

				int piece1X = piece1.X;
				int piece1Y = piece1.Y;

				// Make some animation while swaping
				piece1.MovableComponent.Move (piece2.X, piece2.Y, fillTime);
				piece2.MovableComponent.Move (piece1X, piece1Y, fillTime);

				// Clear the Rainbow piece manually before clearing matches
				if (piece1.Type == PieceType.RAINBOW && piece1.IsClearable () && piece2.IsColored ()) {
					ClearColorPiece clearColor = piece1.GetComponent<ClearColorPiece> ();

					if (clearColor) {
						clearColor.Color = piece2.ColorComponent.Color;
					}

					ClearPiece (piece1.X, piece1.Y);
				}

				if (piece2.Type == PieceType.RAINBOW && piece2.IsClearable () && piece1.IsColored ()) {
					ClearColorPiece clearColor = piece2.GetComponent<ClearColorPiece> ();

					if (clearColor) {
						clearColor.Color = piece1.ColorComponent.Color;
					}

					ClearPiece (piece2.X, piece2.Y);
				}

				// Now we need to clear all pieces from this match
				ClearAllValidMatches ();

				if (piece1.Type == PieceType.ROW_CLEAR || piece1.Type == PieceType.COLUMN_CLEAR) {
					ClearPiece (piece1.X, piece1.Y);
				}

				if (piece2.Type == PieceType.ROW_CLEAR || piece2.Type == PieceType.COLUMN_CLEAR) {
					ClearPiece (piece2.X, piece2.Y);
				}

				pressedPiece = null;
				enteredPiece = null;

				// And finally refilling the board
				StartCoroutine (Fill ());

				// Declares a player move
				level.OnMove();
			} else {
				// No match, return pieces to their own positions
				pieces [piece1.X, piece1.Y] = piece1;
				pieces [piece2.X, piece2.Y] = piece2;
			}
		}
	}

	// Assign piece when piece is pressed
	public void PressPiece(GamePiece piece)
	{
		pressedPiece = piece;
	}

	// Assign piece when piece is entered
	public void EnterPiece(GamePiece piece)
	{
		enteredPiece = piece;
	}

	// Swap pieces when piece is released
	public void ReleasePiece()
	{
		if (IsAdjacent (pressedPiece, enteredPiece)) {
			SwapPieces (pressedPiece, enteredPiece);
		}
	}

	// Used to know if pieces can match
	public List<GamePiece> GetMatch(GamePiece piece, int newX, int newY)
	{
		if (piece.IsColored ()) {
			ColorPiece.ColorType color = piece.ColorComponent.Color;
			List<GamePiece> horizontalPieces = new List<GamePiece> ();
			List<GamePiece> verticalPieces = new List<GamePiece> ();
			List<GamePiece> matchingPieces = new List<GamePiece> ();

			// First check horizontal
			horizontalPieces.Add(piece);

			for (int dir = 0; dir <= 1; dir++) {
				for (int xOffset = 1; xOffset < xDim; xOffset++) {
					int x;

					if (dir == 0) { // Left
						x = newX - xOffset;
					} else { // Right
						x = newX + xOffset;
					}

					if (x < 0 || x >= xDim) {
						break;
					}

					if (pieces [x, newY].IsColored () && pieces [x, newY].ColorComponent.Color == color) {
						horizontalPieces.Add (pieces [x, newY]);
					} else {
						break;
					}
				}
			}

			if (horizontalPieces.Count >= 3) {
				for (int i = 0; i < horizontalPieces.Count; i++) {
					matchingPieces.Add (horizontalPieces [i]);
				}
			}

			// Traverse vertically if we found a match (for L and T shapes)
			if (horizontalPieces.Count >= 3) {
				for (int i = 0; i < horizontalPieces.Count; i++) {
					for (int dir = 0; dir <= 1; dir++) {
						for (int yOffset = 1; yOffset < yDim; yOffset++) {
							int y;

							if (dir == 0) { // Up
								y = newY - yOffset;
							} else { // Down
								y = newY + yOffset;
							}

							if (y < 0 || y >= yDim) {
								break;
							}

							if (pieces [horizontalPieces [i].X, y].IsColored () && pieces [horizontalPieces [i].X, y].ColorComponent.Color == color) {
								verticalPieces.Add (pieces [horizontalPieces [i].X, y]);
							} else {
								break;
							}
						}
					}

					if (verticalPieces.Count < 2) {
						verticalPieces.Clear ();
					} else {
						for (int j = 0; j < verticalPieces.Count; j++) {
							matchingPieces.Add (verticalPieces [j]);
						}

						break;
					}
				}
			}

			if (matchingPieces.Count >= 3) {
				return matchingPieces;
			}

			// Didn't find anything going horizontally first,
			// so now check vertically
			horizontalPieces.Clear();
			verticalPieces.Clear ();
			verticalPieces.Add(piece);

			for (int dir = 0; dir <= 1; dir++) {
				for (int yOffset = 1; yOffset < yDim; yOffset++) {
					int y;

					if (dir == 0) { // Up
						y = newY - yOffset;
					} else { // Down
						y = newY + yOffset;
					}

					if (y < 0 || y >= yDim) {
						break;
					}

					if (pieces [newX, y].IsColored () && pieces [newX, y].ColorComponent.Color == color) {
						verticalPieces.Add (pieces [newX, y]);
					} else {
						break;
					}
				}
			}

			if (verticalPieces.Count >= 3) {
				for (int i = 0; i < verticalPieces.Count; i++) {
					matchingPieces.Add (verticalPieces [i]);
				}
			}

			// Traverse horizontally if we found a match (for L and T shapes)
			if (verticalPieces.Count >= 3) {
				for (int i = 0; i < verticalPieces.Count; i++) {
					for (int dir = 0; dir <= 1; dir++) {
						for (int xOffset = 1; xOffset < xDim; xOffset++) {
							int x;

							if (dir == 0) { // Left
								x = newX - xOffset;
							} else { // Right
								x = newX + xOffset;
							}

							if (x < 0 || x >= xDim) {
								break;
							}

							if (pieces [x, verticalPieces[i].Y].IsColored () && pieces [x, verticalPieces[i].Y].ColorComponent.Color == color) {
								horizontalPieces.Add (pieces [x, verticalPieces[i].Y]);
							} else {
								break;
							}
						}
					}

					if (horizontalPieces.Count < 2) {
						horizontalPieces.Clear ();
					} else {
						for (int j = 0; j < horizontalPieces.Count; j++) {
							matchingPieces.Add (horizontalPieces [j]);
						}

						break;
					}
				}
			}

			if (matchingPieces.Count >= 3) {
				return matchingPieces;
			}
		}

		return null;
	}

	// Clear all matches for one player move
	public bool ClearAllValidMatches()
	{
		bool needsRefill = false;

		for (int y = 0; y < yDim; y++) {
			for (int x = 0; x < xDim; x++) {
				if (pieces [x, y].IsClearable ()) {
					List<GamePiece> match = GetMatch (pieces [x, y], x, y);

					if (match != null) {
						// Start Special piece spawning
						PieceType specialPieceType = PieceType.COUNT;
						GamePiece randomPiece = match [Random.Range (0, match.Count)];
						int specialPieceX = randomPiece.X;
						int specialPieceY = randomPiece.Y;

						if (match.Count == 4) {
							if (pressedPiece == null || enteredPiece == null) {
								specialPieceType = (PieceType)Random.Range ((int)PieceType.ROW_CLEAR, (int)PieceType.COLUMN_CLEAR);
							} else if (pressedPiece.Y == enteredPiece.Y) {
								specialPieceType = PieceType.ROW_CLEAR;
							} else {
								specialPieceType = PieceType.COLUMN_CLEAR;
							}
						} else if (match.Count >= 5) {
							specialPieceType = PieceType.RAINBOW;
						}
						// End Special piece spawning

						for (int i = 0; i < match.Count; i++) {
							if (ClearPiece (match [i].X, match [i].Y)) {
								needsRefill = true;

								if (match [i] == pressedPiece || match [i] == enteredPiece) {
									specialPieceX = match [i].X;
									specialPieceY = match [i].Y;
								}
							}
						}

						// Spawn the special piece
						if (specialPieceType != PieceType.COUNT) {
							Destroy (pieces [specialPieceX, specialPieceY]);
							GamePiece newPiece = SpawnNewPiece (specialPieceX, specialPieceY, specialPieceType);

							if ((specialPieceType == PieceType.ROW_CLEAR || specialPieceType == PieceType.COLUMN_CLEAR)
								&& newPiece.IsColored () && match [0].IsColored ()) {
								newPiece.ColorComponent.SetColor(match[0].ColorComponent.Color);
							} else if (specialPieceType == PieceType.RAINBOW && newPiece.IsColored ()) {
								newPiece.ColorComponent.SetColor (ColorPiece.ColorType.ANY);
							}
						}
					}
				}
			}
		}

		return needsRefill;
	}

	// Clear a piece and respawn an empty piece
	public bool ClearPiece(int x, int y)
	{
		if (pieces [x, y].IsClearable () && !pieces [x, y].ClearableComponent.IsBeingCleared) {
			pieces [x, y].ClearableComponent.Clear ();
			SpawnNewPiece (x, y, PieceType.EMPTY);

			ClearObstacles (x, y);

			return true;
		}

		return false;
	}

	// Used to clear Ice pieces
	public void ClearObstacles(int x, int y)
	{
		for (int adjacentX = x - 1; adjacentX <= x + 1; adjacentX++) {
			if (adjacentX != x && adjacentX >= 0 && adjacentX < xDim) {
				if (pieces [adjacentX, y].Type == PieceType.ICE && pieces [adjacentX, y].IsClearable ()) {
					pieces [adjacentX, y].ClearableComponent.Clear ();
					SpawnNewPiece (adjacentX, y, PieceType.EMPTY);
				}
			}
		}

		for (int adjacentY = y - 1; adjacentY <= y + 1; adjacentY++) {
			if (adjacentY != y && adjacentY >= 0 && adjacentY < yDim) {
				if (pieces [x, adjacentY].Type == PieceType.ICE && pieces [x, adjacentY].IsClearable ()) {
					pieces [x, adjacentY].ClearableComponent.Clear ();
					SpawnNewPiece (x, adjacentY, PieceType.EMPTY);
				}
			}
		}
	}

	// Clear entire row
	public void ClearRow(int row)
	{
		for (int x = 0; x < xDim; x++) {
			ClearPiece (x, row);
		}
	}

	// Clear entire column
	public void ClearColumn(int column)
	{
		for (int y = 0; y < yDim; y++) {
			ClearPiece (column, y);
		}
	}

	// Clear all pieces with the same color
	public void ClearColor(ColorPiece.ColorType color)
	{
		for (int x = 0; x < xDim; x++) {
			for (int y = 0; y < yDim; y++) {
				if (pieces [x, y].IsColored () && (pieces [x, y].ColorComponent.Color == color
					|| color == ColorPiece.ColorType.ANY)) {
					ClearPiece (x, y);
				}
			}
		}
	}

	// Set the game over so the current level ends
	public void GameOver()
	{
		gameOver = true;
	}

	// Returns a list of pieces on the grid with the given type parameter
	public List<GamePiece> GetPiecesOfType(PieceType type)
	{
		List<GamePiece> piecesOfType = new List<GamePiece> ();

		for (int x = 0; x < xDim; x++) {
			for (int y = 0; y < yDim; y++) {
				if (pieces [x, y].Type == type) {
					piecesOfType.Add (pieces [x, y]);
				}
			}
		}

		return piecesOfType;
	}

/*	// Used to know if two pieces have the same color
	public bool IsSameColor(int x, int y, int color)
	{
		if (pieces [x, y].IsColored ()) {
			return (int)pieces [x, y].ColorComponent.Color == color;
		} else {
			return false;
		}
	}*/

	// Used to know if two pieces have the same color
	public bool IsSameColor(int x, int y, ColorPiece.ColorType color)
	{
		if (pieces [x, y].IsColored ()) {
			return pieces [x, y].ColorComponent.Color == color;
		} else {
			return false;
		}
	}

	// Used to know if two pieces have the same color
	public bool IsMovableAndMatching(int x, int y)
	{
		return pieces [x, y].IsMovable ();
	}

	// Used to check all possible matches on the grid
	public List<GamePiece> CheckAllPossibleMatches()
	{
		// We add a list of possible matches
		List<GamePiece> matchingPieces = new List<GamePiece> ();

		// Vertical check
		for (int x = 0; x < xDim; x++) {
			for (int y = 0; y < yDim - 2; y++) {
				// Only if piece is colored and clearable
				if (pieces [x, y].IsClearable () && pieces [x, y].IsColored ()) {
					if (y < yDim - 3)
					{
						/*
						 &
						 *
						 &
						 &
						 */
						if (IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 3, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x, y + 2]);
							matchingPieces.Add (pieces [x, y + 3]);
							return matchingPieces;
						}
						/*
						 &
						 &
						 *
						 &
						 */
						if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 3, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x, y + 1]);
							matchingPieces.Add (pieces [x, y + 3]);
							return matchingPieces;
						}
					}
					if (x > 0)
					{
						/*
						 * &
						 & *
						 & *
						 */
						if (IsSameColor (x - 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x - 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x - 1, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x - 1, y + 1]);
							matchingPieces.Add (pieces [x - 1, y + 2]);
							return matchingPieces;
						}
						/*
						 * &
						 * &
						 & *
						 */
						if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x - 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x, y + 1]);
							matchingPieces.Add (pieces [x - 1, y + 2]);
							return matchingPieces;
						}
						/*
						 * &
						 & *
						 * &
						 */
						if (IsSameColor (x - 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x - 1, y + 1]);
							matchingPieces.Add (pieces [x, y + 2]);
							return matchingPieces;
						}
					}
					if (x < xDim - 1)
					{
						/*
						 & *
						 & *
						 * &
						 */
						if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x, y + 1]);
							matchingPieces.Add (pieces [x + 1, y + 2]);
							return matchingPieces;
						}
						/*
						 & *
						 * &
						 * &
						 */
						if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y + 1]);
							matchingPieces.Add (pieces [x + 1, y + 2]);
							return matchingPieces;
						}
						/*
						 & *
						 * &
						 & *
						 */
						if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y + 1]);
							matchingPieces.Add (pieces [x, y + 2]);
							return matchingPieces;
						}
					}
				}
			}
		}

		// Horizontal check
		for (int y = 0; y < yDim; y++) {
			for (int x = 0; x < xDim - 2; x++) {
				// Only if piece is colored and clearable
				if (pieces [x, y].IsClearable () && pieces [x, y].IsColored ()) {
					if (x < xDim - 3)
					{
						/*
						 & * & &
						 */
						if (IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 3, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 2, y]);
							matchingPieces.Add (pieces [x + 3, y]);
							return matchingPieces;
						}
						/*
						 & & * &
						 */
						if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 3, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y]);
							matchingPieces.Add (pieces [x + 3, y]);
							return matchingPieces;
						}
					}
					if (y > 0)
					{
						/*
					 	* & &
					 	& * *
					 	*/
						if (IsSameColor (x + 1, y - 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y - 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y - 1)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y - 1]);
							matchingPieces.Add (pieces [x + 2, y - 1]);
							return matchingPieces;
						}
						/*
						 * * &
						 & & *
						 */
						if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y - 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y]);
							matchingPieces.Add (pieces [x + 2, y - 1]);
							return matchingPieces;
						}
						/*
						 * & *
						 & * &
						 */
						if (IsSameColor (x + 1, y - 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y - 1]);
							matchingPieces.Add (pieces [x + 2, y]);
							return matchingPieces;
						}
					}
					if (y < yDim - 1)
					{
						/*
						 & * *
						 * & &
						 */
						if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y + 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y + 1]);
							matchingPieces.Add (pieces [x + 2, y + 1]);
							return matchingPieces;
						}
						/*
						 & & *
						 * * &
						 */
						if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y + 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y]);
							matchingPieces.Add (pieces [x + 2, y + 1]);
							return matchingPieces;
						}
						/*
						 & * &
						 * & *
						 */
						if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
							matchingPieces.Add (pieces [x, y]);
							matchingPieces.Add (pieces [x + 1, y + 1]);
							matchingPieces.Add (pieces [x + 2, y]);
							return matchingPieces;
						}
					}
				}
			}
		}

		// No matches?
		return matchingPieces;
	}

	// Shuffle the grid
	public void Shuffle()
	{
		// If the game is over, just disabled this function
		if (!gameOver) {
			for (int x = 0; x < xDim; x++) {
				for (int y = 0; y < yDim; y++) {
					// We only need to shuffle movable pieces
					if (pieces [x, y].IsMovable ()) {
						// Todo : replace this code. We need some kind of list of colored and movable pieces and shuffle it
						pieces [x, y].ColorComponent.SetColor ((ColorPiece.ColorType)Random.Range (0, 5));
					}
					if (ClearAllValidMatches ())
						StartCoroutine (Fill ());
				}
			}
		}
	}

	// Used to advertise the user with possible match
	public IEnumerator advert()
	{
		coroutineIsRunning = true;
		// Check for possible moves
		List<GamePiece> matchingPieces = new List<GamePiece> ();
		List<GamePiece> piecesOfType = new List<GamePiece> ();
		piecesOfType = GetPiecesOfType(PieceType.RAINBOW);
		// Checking for a rainbow piece
		if (piecesOfType.Count == 0) {
			matchingPieces = CheckAllPossibleMatches ();
			if (matchingPieces.Count != 0) {
				// We have a match, we can advert the player
				yield return new WaitForSeconds (5);
				// advert the player
				pieces [matchingPieces [0].X, matchingPieces [0].Y].ClearableComponent.AdvertMatch ();
				pieces [matchingPieces [1].X, matchingPieces [1].Y].ClearableComponent.AdvertMatch ();
				pieces [matchingPieces [2].X, matchingPieces [2].Y].ClearableComponent.AdvertMatch ();
				coroutineIsRunning = false;
			} else {
				// No match and no rainbows, shuffle the grid
				yield return new WaitForSeconds (2);
				coroutineIsRunning = false;
				Shuffle ();
			}
		} else {
			// We have rainbows so highlight them !
			yield return new WaitForSeconds (5);
			pieces [piecesOfType [0].X, piecesOfType [0].Y].ClearableComponent.AdvertMatch ();
			coroutineIsRunning = false;
		}
	}
}
J'ai essayé de commenter le code au mieux car il ne l'était pas du tout à l'origine (puisqu'on le réalisait pendant le cours vidéo). Par rapport au code d'origine, j'ai déjà ajouté pas mal de choses (CheckAllPossibleMatches, advert, shuffle par exemple).

Voilà, j'espère que quelqu'un ici saura m'apporter son aide.

Répondre

Revenir vers « (C#) CSharp »