/// <summary> /// Checks in every direction around the centerPos for atleast /// 4 animal tiles of the same type in a row. Animal rows that are found /// are marked matched at the tile level. /// </summary> /// <param name="centerPos"></param> public void CheckForMatches(IntVector2 centerPos) { if (!IsValidIndex(centerPos)) { return; } AnimalTile centerAnimal = GetAnimal(centerPos); if (AnimalTile.IsNullOrMoving(centerAnimal)) { return; } //Match count for each direction. int[] matchCounts = { 1, 1, 1, 1, 0, 0, 0, 0 }; //Count matches found extending out from (x,y) in each direction. foreach (SwipeDirection direction in Enum.GetValues(typeof(SwipeDirection))) { IntVector2 currPos = GetNextNeighbor(centerPos, direction); AnimalTile currAnimal = GetAnimal(currPos); //While neighbor in direction is the same as center. Add to count and move to next while (!AnimalTile.IsNullOrMoving(currAnimal) && AnimalTile.IsSameType(centerAnimal, currAnimal)) { matchCounts[(int)direction]++; currPos = GetNextNeighbor(currPos, direction); currAnimal = GetAnimal(currPos); } } //Only iterate: North, NorthEast, East, SouthEast. The rest can be considered part of these. for (int i = 0; i < 4; i++) { IntVector2 currStartPos = new IntVector2(centerPos.x, centerPos.y); SwipeDirection currDirection = (SwipeDirection)i; int currLength = 0; //Center is not start of match SwipeDirection invertedDirection = InputController.InvertDirection(currDirection); //Find correct start, and how long it really is. currStartPos = GetNextNeighbor(currStartPos, invertedDirection, matchCounts[i + 4]); currLength += matchCounts[i + 4] + matchCounts[i]; //If the row is 4 or longer and has an unmatched animal in it. Remove it. if (currLength >= MinMatch && DoesRowHaveNonMatched(currStartPos, currLength, currDirection)) { IsReady = false; //Set them marked in the board. And give player points. MarkRowMatched(currStartPos, currLength, currDirection); playerScore.AddPoints(currStartPos, currLength, currDirection); } } }
/// <summary> /// Move the animal and remove it's reference. That way /// during lerping it wont have an incorrect reference. /// </summary> private void MoveAnimal(AnimalTile animal, IntVector2 targetPos) { if (AnimalTile.IsNullOrMoving(animal)) { return; } animal.LerpToPosition(targetPos); SetAnimalInBoard(animal, targetPos); }
/// <summary> /// Switch the animals at the two specific locations. Their /// references in the array are set to null until /// they both finish lerping to them. /// </summary> public void SwitchAnimals(IntVector2 posA, IntVector2 posB) { AnimalTile animalA = GetAnimal(posA); AnimalTile animalB = GetAnimal(posB); if (!AnimalTile.IsNullOrMoving(animalA) && !AnimalTile.IsNullOrMoving(animalB)) { MoveAnimal(animalA, posB); MoveAnimal(animalB, posA); } }
/// <summary> /// Move the animal and remove it's reference. That way /// during lerping it wont have an incorrect reference. /// </summary> private void MoveAnimal(IntVector2 animalPos, IntVector2 targetPos) { AnimalTile animalToMove = GetAnimal(animalPos); if (AnimalTile.IsNullOrMoving(animalToMove)) { return; } animalToMove.LerpToPosition(targetPos); animals[animalPos.x, animalPos.y] = null; SetAnimalInBoard(animalToMove, targetPos); }
/// <summary> /// Checks to see if every animal has finally reached its target. /// </summary> /// <returns></returns> private bool IsBoardFull() { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { AnimalTile currAnimal = GetAnimal(new IntVector2(x, y)); if (AnimalTile.IsNullOrMoving(currAnimal)) { return(false); } } } return(true); }
/// <summary> /// Sets all the animals in the row as matched. /// </summary> /// <param name="startPos"></param> /// <param name="length"></param> /// <param name="rowDirection"></param> private void MarkRowMatched(IntVector2 startPos, int length, SwipeDirection rowDirection) { IntVector2 currPos = new IntVector2(startPos.x, startPos.y); //Iterate through the row setting each animal to matched. for (int i = 0; i < length; i++) { AnimalTile toMark = GetAnimal(currPos); if (!AnimalTile.IsNullOrMoving(toMark)) { toMark.State = AnimalState.Matched; } currPos = GetNextNeighbor(currPos, rowDirection); } }
/// <summary> /// Squeeze the column back together. /// </summary> private int UpdateColumn(int x) { int emptyY = -1; //Start at bottom of column and squeeze it down. for (int y = 0; y < Height; y++) { IntVector2 currPos = new IntVector2(x, y); AnimalTile currAnimal = GetAnimal(currPos); //if empty tile, store y coord if none yet. if (AnimalTile.IsNullOrMoving(currAnimal)) { emptyY = (emptyY == -1) ? y : emptyY; } //Tile was not empty. If we need to fill a lower one do so. else { //We have an empty spot to fill. if (emptyY != -1) { //Move current animal to last empty slot found. IntVector2 newPos = new IntVector2(x, emptyY); MoveAnimal(currAnimal, newPos); KillAnimalAt(currPos); //Debug.Log("Moving " + currAnimal + " from: " + currPos + " to " + newPos); //If we jumped more than 1 empty slot, set it to current y. int yDelta = emptyY - y; emptyY = (yDelta > 1) ? y : emptyY + 1; } } } for (int y = 0; y < Height; y++) { IntVector2 currPos = new IntVector2(x, y); if (GetAnimal(currPos) == null) { animalSpawners[x].AddAnimalToSpawnQueue(currPos); } } return(emptyY); }
/// <summary> /// Checks if any of the animal tiles in the row /// are not matched. If so, match them. /// </summary> private bool DoesRowHaveNonMatched(IntVector2 startPos, int length, SwipeDirection rowDirection) { IntVector2 currPos = new IntVector2(startPos.x, startPos.y); bool unMatchedFound = false; AnimalTile currAnimal; for (int i = 0; i < length; i++) { currAnimal = GetAnimal(currPos); if (!AnimalTile.IsNullOrMoving(currAnimal) && currAnimal.State != AnimalState.Matched) { unMatchedFound = true; } currPos = GetNextNeighbor(currPos, rowDirection); } return(unMatchedFound); }