Пример #1
0
    private void AddBallsIfThereIsBomb(List <BallSlot> ballsToDestroySlots)
    {
        BallSlot ballSlot = ballsToDestroySlots.FirstOrDefault(bs => bs.ball.type == BallType.Bomb);

        if (ballSlot)
        {
            int indexOfBombSlot = Array.IndexOf(BallSlotsByDistance, ballSlot);
            for (int i = 1; i <= gameProperties.bombRadius; i++)
            {
                int leftIndex  = indexOfBombSlot - i;
                int rightIndex = indexOfBombSlot + i;
                if (leftIndex >= 0 && BallSlotsByDistance[leftIndex].ball &&
                    !ballsToDestroySlots.Contains(BallSlotsByDistance[leftIndex]))
                {
                    ballsToDestroySlots.Add(BallSlotsByDistance[leftIndex]);
                }

                if (rightIndex < BallSlotsByDistance.Length && BallSlotsByDistance[rightIndex].ball &&
                    !ballsToDestroySlots.Contains(BallSlotsByDistance[rightIndex]))
                {
                    ballsToDestroySlots.Add(BallSlotsByDistance[rightIndex]);
                }
            }
        }
    }
Пример #2
0
    public void LandBall(BallSlot collidedSlot, Ball landingBall)
    {
        BallSlot[] ballSlotsByDistance = BallSlotsByDistance;
        int        indexOfCollidedSlot = Array.IndexOf(ballSlotsByDistance, collidedSlot);

        int firstEmptySlotIndexAfter = FirstEmptySlotIndexAfter(indexOfCollidedSlot, ballSlotsByDistance);

        for (int i = firstEmptySlotIndexAfter; i > indexOfCollidedSlot + 1; i--)
        {
            ballSlotsByDistance[i].AssignBall(ballSlotsByDistance[i - 1].ball);
        }

        if (collidedSlot.distanceTraveled <
            pathCreator.path.GetClosestDistanceAlongPath(landingBall.transform.position))
        {
            ballSlotsByDistance[indexOfCollidedSlot + 1].AssignBall(landingBall);
        }
        else
        {
            ballSlotsByDistance[indexOfCollidedSlot + 1].AssignBall(collidedSlot.ball);
            collidedSlot.AssignBall(landingBall);
        }

        landingBall.Land();
        foreach (BallSlot ballSlot in ballSlotsByDistance
                 .Where(bs => bs.ball && bs.ball.state == BallState.InSlot))
        {
            ballSlot.ball.MoveToSlot();
        }

        StartCoroutine(DestroyMatchingBallsCo(landingBall.slot));
    }
Пример #3
0
 public void OnClickBallSlot(BallSlot Ball)
 {
     if (Ball.myBall == null)
     {
         if (heldObject == null)
         {
             return;
         }
         else
         {
             Ball.myBall           = heldObject.GetComponent <Ball>();
             Ball.ballSprite.color = Color.white;
             if (heldObject.GetComponent <SpriteRenderer>())
             {
                 Ball.ballSprite.sprite = heldObject.GetComponent <SpriteRenderer>().sprite;
             }
             else
             {
                 Ball.ballSprite.sprite = heldObject.GetComponentInChildren <SpriteRenderer>().sprite;
             }
             heldObjectSprite.color  = Color.clear;
             heldObjectSprite.sprite = null;
             heldObject = null;
         }
     }
     else
     {
         if (heldObject == null)
         {
             heldObject = Ball.myBall.gameObject;
             if (heldObject.GetComponent <SpriteRenderer>())
             {
                 heldObjectSprite.sprite = heldObject.GetComponent <SpriteRenderer>().sprite;
             }
             else
             {
                 heldObjectSprite.sprite = heldObject.GetComponentInChildren <SpriteRenderer>().sprite;
             }
             heldObjectSprite.color = Color.white;
             Ball.ballSprite.sprite = null; Ball.ballSprite.color = Color.clear;
             Ball.myBall            = null;
         }
         else
         {
             GameObject temp = heldObject;
             heldObject = Ball.myBall.gameObject;
             if (heldObject.GetComponent <SpriteRenderer>())
             {
                 heldObjectSprite.sprite = heldObject.GetComponent <SpriteRenderer>().sprite;
             }
             else
             {
                 heldObjectSprite.sprite = heldObject.GetComponentInChildren <SpriteRenderer>().sprite;
             }
             Ball.myBall            = temp.GetComponent <Ball>();
             Ball.ballSprite.sprite = temp.GetComponent <SpriteRenderer>().sprite;
         }
     }
 }
Пример #4
0
        private static List <BallSlot> GetAdjacentSlotsOnSameRow(BallSlot slot)
        {
            List <BallSlot> slots = new List <BallSlot>(6);

            slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex), GetClampledColumnIndex(slot.RowIndex, slot.ColumnIndex - 1)));
            slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex), GetClampledColumnIndex(slot.RowIndex, slot.ColumnIndex + 1)));

            return(slots);
        }
Пример #5
0
        private void GetAllPieceOfSameColorAlignedAtSlot(BallSlot ballSlot, Ball.BallColor color, List <BallSlot> slots)
        {
            Ball ball = GetBallAtSlot(ballSlot.RowIndex, ballSlot.ColumnIndex);

            if (ball != null && ball.Color == color && !slots.Contains(ballSlot))
            {
                slots.Add(ballSlot);
                GetAllAdjacentSlots(ballSlot).ForEach(slot => GetAllPieceOfSameColorAlignedAtSlot(slot, color, slots));
            }
        }
Пример #6
0
        private void FallBallAtSlot(BallSlot slot)
        {
            Ball ball = GetBallAtSlot(slot);

            if (ball != null)
            {
                ball.FallDown();
                DeletedBalls.Add(ball);
            }
            Balls[slot.RowIndex][slot.ColumnIndex] = null;
        }
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Ball Slot"))
        {
            BallSlot ballSlot = other.GetComponent <BallSlot>();

            if (ballSlot.ball)
            {
                ballSlot.ball.state = BallState.Destroying;
                ballSlot.ball       = null;
            }
        }
    }
Пример #8
0
        private List <BallSlot> GetAllBallsAdjacentToSlot(BallSlot ballSlot)
        {
            List <BallSlot> slots = new List <BallSlot>(6);

            foreach (BallSlot slot in GetAllAdjacentSlots(ballSlot))
            {
                if (GetBallAtSlot(slot) != null)
                {
                    slots.Add(slot);
                }
            }

            return(slots);
        }
Пример #9
0
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (!other.CompareTag("Ball Slot"))
        {
            return;
        }
        BallSlot ballSlot = other.GetComponent <BallSlot>();

        if (!ballSlot.ball || state != BallState.Shooting)
        {
            return;
        }

        board.LandBall(ballSlot, this);
        circleCollider2D.enabled = false;
    }
Пример #10
0
    private IEnumerator DestroyMatchingBallsCo(BallSlot landedBallSlot)
    {
        isDestroyingMatchingBalls = true;

        List <BallSlot> ballsToDestroySlots;
        BallSlot        collidedBallSlot = landedBallSlot;

        do
        {
            yield return(new WaitUntil(() => BallSlotsByDistance.All(bs =>
                                                                     !bs.ball || bs.ball.state != BallState.Landing && bs.ball.state != BallState.SwitchingSlots)));

            ballsToDestroySlots = GetSimilarBalls(collidedBallSlot);

            if (ballsToDestroySlots.Count < 3)
            {
                break;
            }

            AddBallsIfThereIsBomb(ballsToDestroySlots);
            if (ballsToDestroySlots.FindIndex(bs => bs.ball.type == BallType.Reverse) != -1)
            {
                StartCoroutine(StartReverseCo());
            }
            if (ballsToDestroySlots.FindIndex(bs => bs.ball.type == BallType.TimeSlow) != -1)
            {
                StartCoroutine(TimeSlowCo());
            }

            foreach (BallSlot ballsToDestroySlot in ballsToDestroySlots)
            {
                ballsToDestroySlot.ball.StartDestroying();
                ballsToDestroySlot.AssignBall(null);
            }

            collidedBallSlot = ballsToDestroySlots[0];

            yield return(new WaitForSeconds(0.5f));

            MoveSeparatedBallsBack();
        } while (ballsToDestroySlots.Count >= 3 && collidedBallSlot);

        yield return(new WaitUntil(() => BallSlotsByDistance.All(bs =>
                                                                 !bs.ball || bs.ball.state != BallState.SwitchingSlots)));

        isDestroyingMatchingBalls = false;
    }
Пример #11
0
        private static List <BallSlot> GetAllAdjacentLowerSlots(BallSlot slot)
        {
            List <BallSlot> slots = new List <BallSlot>(6);

            if (slot.RowIndex % 2 == 0)
            {
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex + 1), GetClampledColumnIndex(slot.RowIndex + 1, slot.ColumnIndex - 1)));
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex + 1), GetClampledColumnIndex(slot.RowIndex + 1, slot.ColumnIndex)));
            }
            else
            {
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex + 1), GetClampledColumnIndex(slot.RowIndex + 1, slot.ColumnIndex)));
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex + 1), GetClampledColumnIndex(slot.RowIndex + 1, slot.ColumnIndex + 1)));
            }

            return(slots);
        }
Пример #12
0
    private List <BallSlot> GetSimilarBalls(BallSlot landedBallSlot)
    {
        List <BallSlot> ballsToDestroySlots = new List <BallSlot> {
            landedBallSlot
        };

        if (!landedBallSlot.ball)
        {
            return(ballsToDestroySlots);
        }

        int indexOfLandedBallSlot = Array.IndexOf(BallSlotsByDistance, landedBallSlot);

        for (int i = indexOfLandedBallSlot - 1; i >= 0; i--)
        {
            BallSlot ballSlot = BallSlotsByDistance[i];
            if (ballSlot.ball && !ballsToDestroySlots.Contains(ballSlot) &&
                BallUtil.GetBallColorByType(ballSlot.ball.type) ==
                BallUtil.GetBallColorByType(landedBallSlot.ball.type))
            {
                ballsToDestroySlots.Add(ballSlot);
            }
            else
            {
                break;
            }
        }

        for (int i = indexOfLandedBallSlot + 1; i < BallSlotsByDistance.Length; i++)
        {
            BallSlot ballSlot = BallSlotsByDistance[i];
            if (ballSlot.ball && !ballsToDestroySlots.Contains(ballSlot) &&
                BallUtil.GetBallColorByType(ballSlot.ball.type) ==
                BallUtil.GetBallColorByType(landedBallSlot.ball.type))
            {
                ballsToDestroySlots.Add(ballSlot);
            }
            else
            {
                break;
            }
        }

        return(ballsToDestroySlots.OrderBy(bs => bs.distanceTraveled).ToList());
    }
Пример #13
0
    private void ProduceBallsOnTrack()
    {
        if (isReverse)
        {
            return;
        }

        BallSlot zeroSlot = BallSlotsByDistance[0];

        if (!zeroSlot.ball)
        {
            Ball ball = ballFactory.CreateBallAt(zeroSlot.transform.position, ballFactory.GetRandomBallType());
            zeroSlot.AssignBall(ball);
            ball.transform.parent     = zeroSlot.transform;
            ball.transform.localScale = Vector3.zero;
            ball.state = BallState.Spawning;
        }
    }
Пример #14
0
    private void InitBallSlots()
    {
        float pathLength = pathCreator.path.length;
        int   slotsCount = (int)pathLength;
        float step       = pathLength / slotsCount;

        ballSlots = new BallSlot[slotsCount];

        for (int i = 0; i < slotsCount; i++)
        {
            float    distanceTraveled = i * step;
            Vector3  slotPos          = pathCreator.path.GetPointAtDistance(distanceTraveled);
            BallSlot ballSlot         = Instantiate(ballSlotPrefab, slotPos, Quaternion.identity);
            ballSlot.distanceTraveled = distanceTraveled;
            ballSlot.transform.parent = ballSlotsContainer.transform;
            ballSlots[i] = ballSlot;
        }
    }
Пример #15
0
        private List <BallSlot> GetAllBallsWithNoUpperAndSameRowAdjacentBalls(int rowIndex, int columnIndex)
        {
            List <BallSlot> slots = new List <BallSlot>();

            for (int i = 1; i < NUMBER_OF_ROWS; i++)
            {
                List <BallSlot> slotListCandidate = new List <BallSlot>();
                for (int j = 0; j < GetNumberOfColumnForRow(i); j++)
                {
                    BallSlot slot = new BallSlot(i, j);

                    if ((rowIndex != i || columnIndex != j) &&
                        GetBallAtSlot(slot) != null)
                    {
                        if (GetBallsForSlots(GetAllAdjacentUpperSlots(slot)).All(ball => ball == null))
                        {
                            slotListCandidate.Add(slot);
                            if (j + 1 >= GetNumberOfColumnForRow(i))
                            {
                                slots.AddRange(slotListCandidate);
                            }
                        }
                        else
                        {
                            slotListCandidate = new List <BallSlot>();
                        }
                    }
                    else if (slotListCandidate.Count > 0)
                    {
                        slots.AddRange(slotListCandidate);
                    }
                }
            }

            return(slots);
        }
Пример #16
0
 private Ball GetBallAtSlot(BallSlot slot)
 {
     return(GetBallAtSlot(slot.RowIndex, slot.ColumnIndex));
 }
Пример #17
0
        public void SetBallToNearestSlot(Ball ball, BallSlot interSectingSlot)
        {
            int nearestRowIndex;
            int nearestColumnIndex;

            List<BallSlot> emptySlots;

            if (interSectingSlot != null)
            {
                // Get the nearest empty slots.
                emptySlots = GetAllAdjacentLowerSlots(interSectingSlot);
                emptySlots.AddRange(GetAdjacentSlotsOnSameRow(interSectingSlot));
            }
            else // The ball reached the ceiling
            {
                emptySlots = GetAllTopSlots();
            }
            emptySlots.RemoveAll(slot => GetBallAtSlot(slot) != null);

            emptySlots.Sort(delegate(BallSlot slot, BallSlot otherSlot)
            {
                float length1 = (GetSlotCenter(slot) - ball.Position).Length();
                float length2 = (GetSlotCenter(otherSlot) - ball.Position).Length();
                return length1.CompareTo(length2);
            });

            if (emptySlots.Count > 0)
            {
                try
                {
                    nearestRowIndex = emptySlots.ElementAt(0).RowIndex;
                    nearestColumnIndex = emptySlots.ElementAt(0).ColumnIndex;

                    SetBallAtPosition(nearestRowIndex, nearestColumnIndex, ball);
                    DestroyAlignedPieceAtSlot(nearestRowIndex, nearestColumnIndex);

                    int numOfBallsFallen = FallDownAllBallsWithNoUpperAdjacentBalls(nearestRowIndex, nearestColumnIndex);
                    CurrentScore.Value += (numOfBallsFallen > 0) ? (int)Math.Pow(2, numOfBallsFallen) * 10
                                                                 : 0;
                    CheckIfPlayerWins();
                    CheckIfPlayerLost();
                }
                catch (SlotOccupiedException ex)
                {
                }
            }
            else
            {
                //Set All balls to Dark
                foreach (List<Ball> list in Balls)
                {
                    foreach (Ball b in list)
                    {
                        if (b != null)
                        {
                            b.GoDark();
                        }
                    }
                }

                Observer.ForEach(observer => observer.OnPlayerLoses());
            }
        }
Пример #18
0
 private Vector3 GetSlotCenter(BallSlot slot)
 {
     return (slot.RowIndex % 2 == 0) ? Position + new Vector3(slot.RowIndex * Ball.BALL_RADIUS*2 + Ball.BALL_RADIUS, slot.ColumnIndex * Ball.BALL_RADIUS*2 + Ball.BALL_RADIUS, Ball.BALL_RADIUS)
                                     : Position + new Vector3(slot.RowIndex * Ball.BALL_RADIUS*2 + Ball.BALL_RADIUS, ODD_ROW_OFFSET + slot.ColumnIndex * Ball.BALL_RADIUS*2 + Ball.BALL_RADIUS, Ball.BALL_RADIUS);
 }
Пример #19
0
        private static List<BallSlot> GetAdjacentSlotsOnSameRow(BallSlot slot)
        {
            List<BallSlot> slots = new List<BallSlot>(6);

            slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex), GetClampledColumnIndex(slot.RowIndex, slot.ColumnIndex - 1)));
            slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex), GetClampledColumnIndex(slot.RowIndex, slot.ColumnIndex + 1)));

            return slots;
        }
Пример #20
0
 private Vector2 GetSlotCenter(BallSlot slot)
 {
     return (slot.RowIndex % 2 == 0) ? Position + new Vector2(slot.ColumnIndex * Ball.RECTANGLE_WIDTH + Ball.RECTANGLE_WIDTH / 2, slot.RowIndex * Ball.RECTANGLE_HEIGHT + Ball.RECTANGLE_HEIGHT / 2)
                                     : Position + new Vector2(ODD_ROW_OFFSET + slot.ColumnIndex * Ball.RECTANGLE_WIDTH + Ball.RECTANGLE_WIDTH / 2, slot.RowIndex * Ball.RECTANGLE_HEIGHT + Ball.RECTANGLE_HEIGHT / 2);
 }
Пример #21
0
 private Ball GetBallAtSlot(BallSlot slot)
 {
     return GetBallAtSlot(slot.RowIndex, slot.ColumnIndex);
 }
Пример #22
0
        private List<BallSlot> GetAllBallsWithNoUpperAndSameRowAdjacentBalls(int rowIndex, int columnIndex)
        {
            List<BallSlot> slots = new List<BallSlot>();

            for (int i = 1; i < NUMBER_OF_ROWS; i++)
            {
                List<BallSlot> slotListCandidate = new List<BallSlot>();
                for (int j = 0; j < GetNumberOfColumnForRow(i); j++)
                {
                    BallSlot slot = new BallSlot(i, j);

                    if((rowIndex != i || columnIndex != j)
                        && GetBallAtSlot(slot) != null)
                    {
                        if(GetBallsForSlots(GetAllAdjacentUpperSlots(slot)).All(ball => ball == null))
                        {
                            slotListCandidate.Add(slot);
                            if (j + 1 >= GetNumberOfColumnForRow(i))
                            {
                                slots.AddRange(slotListCandidate);
                            }
                        }
                        else
                        {
                            slotListCandidate = new List<BallSlot>();
                        }
                    }
                    else if (slotListCandidate.Count > 0)
                    {
                        slots.AddRange(slotListCandidate);
                    }
                }
            }

            return slots;
        }
Пример #23
0
        private List<BallSlot> GetAllBallsAdjacentToSlot(BallSlot ballSlot)
        {
            List<BallSlot> slots = new List<BallSlot>(6);

            foreach (BallSlot slot in GetAllAdjacentSlots(ballSlot))
            {
                if (GetBallAtSlot(slot) != null)
                {
                    slots.Add(slot);
                }
            }

            return slots;
        }
Пример #24
0
 private void FallBallAtSlot(BallSlot slot)
 {
     Ball ball = GetBallAtSlot(slot);
     if (ball != null)
     {
         ball.FallDown();
         DeletedBalls.Add(ball);
     }
     Balls[slot.RowIndex][slot.ColumnIndex] = null;
 }
Пример #25
0
        private static List<BallSlot> GetAllAdjacentUpperSlots(BallSlot slot)
        {
            List<BallSlot> slots = new List<BallSlot>(6);

            if (slot.RowIndex % 2 == 0)
            {
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex - 1), GetClampledColumnIndex(slot.RowIndex - 1, slot.ColumnIndex - 1)));
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex - 1), GetClampledColumnIndex(slot.RowIndex - 1, slot.ColumnIndex)));
            }
            else
            {
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex - 1), GetClampledColumnIndex(slot.RowIndex - 1, slot.ColumnIndex)));
                slots.Add(new BallSlot(GetClampedRowIndex(slot.RowIndex - 1), GetClampledColumnIndex(slot.RowIndex - 1, slot.ColumnIndex + 1)));
            }

            return slots;
        }
Пример #26
0
 private Vector2 GetSlotCenter(BallSlot slot)
 {
     return((slot.RowIndex % 2 == 0) ? Position + new Vector2(slot.ColumnIndex * Ball.RECTANGLE_WIDTH + Ball.RECTANGLE_WIDTH / 2, slot.RowIndex * Ball.RECTANGLE_HEIGHT + Ball.RECTANGLE_HEIGHT / 2)
                                     : Position + new Vector2(ODD_ROW_OFFSET + slot.ColumnIndex * Ball.RECTANGLE_WIDTH + Ball.RECTANGLE_WIDTH / 2, slot.RowIndex * Ball.RECTANGLE_HEIGHT + Ball.RECTANGLE_HEIGHT / 2));
 }
Пример #27
0
 public bool Equals(BallSlot otherSlot)
 {
     return RowIndex == otherSlot.RowIndex && ColumnIndex == otherSlot.ColumnIndex;
 }
Пример #28
0
        public void SetBallToNearestSlot(Ball ball, BallSlot interSectingSlot)
        {
            int nearestRowIndex;
            int nearestColumnIndex;

            if (interSectingSlot != null)
            {
                // Get the nearest empty slot.
                List <BallSlot> emptySlots = GetAllAdjacentLowerSlots(interSectingSlot);
                emptySlots.AddRange(GetAdjacentSlotsOnSameRow(interSectingSlot));
                emptySlots.RemoveAll(slot => GetBallAtSlot(slot) != null);

                Vector2 ballCenter = new Vector2(ball.Rectangle.Center.X, ball.Rectangle.Center.Y);
                emptySlots.Sort(delegate(BallSlot slot, BallSlot otherSlot)
                {
                    float length1 = (GetSlotCenter(slot) - ballCenter).Length();
                    float length2 = (GetSlotCenter(otherSlot) - ballCenter).Length();
                    return(length1.CompareTo(length2));
                });

                if (emptySlots.Count > 0)
                {
                    if (emptySlots.ElementAt(0).RowIndex > GetCurrentLowestRowIndexLimit())
                    {
                        //Set All balls to Dark
                        foreach (List <Ball> list in Balls)
                        {
                            foreach (Ball hangingBall in list)
                            {
                                if (hangingBall != null)
                                {
                                    hangingBall.GoDark();
                                }
                            }
                        }
                        Observer.ForEach(observer => observer.OnPlayerLoses());
                    }

                    nearestRowIndex    = emptySlots.ElementAt(0).RowIndex;
                    nearestColumnIndex = emptySlots.ElementAt(0).ColumnIndex;
                }
                else
                {
                    // There is no room left to place that ball.
                    //Set All balls to Dark
                    foreach (List <Ball> list in Balls)
                    {
                        foreach (Ball hangingBall in list)
                        {
                            if (hangingBall != null)
                            {
                                hangingBall.GoDark();
                            }
                        }
                    }
                    Observer.ForEach(observer => observer.OnPlayerLoses());
                    nearestColumnIndex = interSectingSlot.ColumnIndex;
                    nearestRowIndex    = interSectingSlot.RowIndex;
                }
            }
            else // The ball reached the ceiling
            {
                float nearestRowRatio = Math.Abs(ball.Rectangle.Center.Y - Position.Y) / (Ball.RECTANGLE_HEIGHT * NUMBER_OF_ROWS);
                nearestRowIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestRowRatio * NUMBER_OF_ROWS), 0, NUMBER_OF_ROWS - 1);

                if (nearestRowIndex % 2 == 0)
                {
                    float nearestColumnRatio = Math.Abs(ball.Rectangle.Center.X - Position.X) / Bounds.Rectangle.Width;

                    nearestColumnIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestColumnRatio * NUMBER_OF_COLUMNS_EVEN), 0, NUMBER_OF_COLUMNS_EVEN - 1);
                }
                else
                {
                    float nearestColumnRatio = Math.Abs(ball.Rectangle.Center.X + ODD_ROW_OFFSET - Position.X) / (Bounds.Rectangle.Width - 2 * ODD_ROW_OFFSET);
                    nearestColumnIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestColumnRatio * NUMBER_OF_COLUMNS_ODD), 0, NUMBER_OF_COLUMNS_ODD - 1);
                }
            }

            try
            {
                if (GetAllBallsAdjacentToSlot(new BallSlot(nearestRowIndex, nearestColumnIndex)).Count == 0)
                {
                    nearestColumnIndex = (ball.Direction.X > 0) ? GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex + 1)
                                                                : GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex - 1);

                    if (GetAllBallsAdjacentToSlot(new BallSlot(nearestRowIndex, nearestColumnIndex)).Count == 0)
                    {
                        nearestColumnIndex = (ball.Direction.X > 0) ? GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex - 2)
                                                                    : GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex + 2);
                    }
                }

                SetBallAtPosition(nearestRowIndex, nearestColumnIndex, ball);
                DestroyAlignedPieceAtSlot(nearestRowIndex, nearestColumnIndex);

                int numOfBallsFallen = FallDownAllBallsWithNoUpperAdjacentBalls(nearestRowIndex, nearestColumnIndex);
                CurrentScore.Value += (numOfBallsFallen > 0) ? (int)Math.Pow(2, numOfBallsFallen) * 10
                                                             : 0;
                CheckIfPlayerWins();
            }
            catch (SlotOccupiedException ex)
            {
                //nearestRowIndex = GetClampedRowIndex(nearestRowIndex+1);
                //SetBallAtPosition(GetClampedRowIndex(nearestRowIndex),
                //                  GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex),
                //                  ball);
            }
        }
Пример #29
0
 public bool Equals(BallSlot otherSlot)
 {
     return(RowIndex == otherSlot.RowIndex && ColumnIndex == otherSlot.ColumnIndex);
 }
Пример #30
0
        private void GetAllPieceOfSameColorAlignedAtSlot(BallSlot ballSlot, Ball.BallColor color, List<BallSlot> slots)
        {
            Ball ball = GetBallAtSlot(ballSlot.RowIndex, ballSlot.ColumnIndex);

            if (ball != null && ball.Color == color && !slots.Contains(ballSlot))
            {
                slots.Add(ballSlot);
                GetAllAdjacentSlots(ballSlot).ForEach(slot => GetAllPieceOfSameColorAlignedAtSlot(slot, color, slots));
            }
        }
Пример #31
0
        public void SetBallToNearestSlot(Ball ball, BallSlot interSectingSlot)
        {
            int nearestRowIndex;
            int nearestColumnIndex;

            if (interSectingSlot != null)
            {
                // Get the nearest empty slot.
                List<BallSlot> emptySlots = GetAllAdjacentLowerSlots(interSectingSlot);
                emptySlots.AddRange(GetAdjacentSlotsOnSameRow(interSectingSlot));
                emptySlots.RemoveAll(slot => GetBallAtSlot(slot) != null);

                Vector2 ballCenter = new Vector2(ball.Rectangle.Center.X, ball.Rectangle.Center.Y);
                emptySlots.Sort(delegate(BallSlot slot, BallSlot otherSlot)
                {
                    float length1 = (GetSlotCenter(slot) - ballCenter).Length();
                    float length2 = (GetSlotCenter(otherSlot) - ballCenter).Length();
                    return length1.CompareTo(length2);
                });

                if (emptySlots.Count > 0)
                {

                    if (emptySlots.ElementAt(0).RowIndex > GetCurrentLowestRowIndexLimit())
                    {
                        //Set All balls to Dark
                        foreach (List<Ball> list in Balls)
                        {
                            foreach (Ball hangingBall in list)
                            {
                                if (hangingBall != null)
                                {
                                    hangingBall.GoDark();
                                }
                            }
                        }
                        Observer.ForEach(observer => observer.OnPlayerLoses());

                    }

                    nearestRowIndex = emptySlots.ElementAt(0).RowIndex;
                    nearestColumnIndex = emptySlots.ElementAt(0).ColumnIndex;
                }
                else
                {
                    // There is no room left to place that ball.
                    //Set All balls to Dark
                    foreach (List<Ball> list in Balls)
                    {
                        foreach (Ball hangingBall in list)
                        {
                            if (hangingBall != null)
                            {
                                hangingBall.GoDark();
                            }
                        }
                    }
                    Observer.ForEach(observer => observer.OnPlayerLoses());
                    nearestColumnIndex = interSectingSlot.ColumnIndex;
                    nearestRowIndex = interSectingSlot.RowIndex;
                }
            }
            else // The ball reached the ceiling
            {
                float nearestRowRatio = Math.Abs(ball.Rectangle.Center.Y - Position.Y) / (Ball.RECTANGLE_HEIGHT * NUMBER_OF_ROWS);
                nearestRowIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestRowRatio * NUMBER_OF_ROWS), 0, NUMBER_OF_ROWS - 1);

                if (nearestRowIndex % 2 == 0)
                {
                    float nearestColumnRatio = Math.Abs(ball.Rectangle.Center.X - Position.X) / Bounds.Rectangle.Width;

                    nearestColumnIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestColumnRatio * NUMBER_OF_COLUMNS_EVEN), 0, NUMBER_OF_COLUMNS_EVEN - 1);
                }
                else
                {
                    float nearestColumnRatio = Math.Abs(ball.Rectangle.Center.X + ODD_ROW_OFFSET - Position.X) / (Bounds.Rectangle.Width - 2 * ODD_ROW_OFFSET);
                    nearestColumnIndex = (int)MathHelper.Clamp((float)Math.Floor(nearestColumnRatio * NUMBER_OF_COLUMNS_ODD), 0, NUMBER_OF_COLUMNS_ODD - 1);
                }
            }

            try
            {
                if (GetAllBallsAdjacentToSlot(new BallSlot(nearestRowIndex, nearestColumnIndex)).Count == 0)
                {
                     nearestColumnIndex = (ball.Direction.X > 0) ? GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex + 1)
                                                                : GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex - 1);

                     if (GetAllBallsAdjacentToSlot(new BallSlot(nearestRowIndex, nearestColumnIndex)).Count == 0)
                     {
                         nearestColumnIndex = (ball.Direction.X > 0) ? GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex - 2)
                                                                    : GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex + 2);

                     }
                }

                SetBallAtPosition(nearestRowIndex, nearestColumnIndex, ball);
                DestroyAlignedPieceAtSlot(nearestRowIndex, nearestColumnIndex);

                int numOfBallsFallen = FallDownAllBallsWithNoUpperAdjacentBalls(nearestRowIndex, nearestColumnIndex);
                CurrentScore.Value += (numOfBallsFallen > 0) ? (int)Math.Pow(2, numOfBallsFallen) * 10
                                                             : 0;
                CheckIfPlayerWins();
            }
            catch (SlotOccupiedException ex)
            {
                //nearestRowIndex = GetClampedRowIndex(nearestRowIndex+1);
                //SetBallAtPosition(GetClampedRowIndex(nearestRowIndex),
                //                  GetClampledColumnIndex(nearestRowIndex, nearestColumnIndex),
                //                  ball);
            }
        }