/// <summary> /// Explodes given points. Explosion size is the direction count of the map (8) + 1 (the explosion origin) /// </summary> /// <param name="gonnaExplode"></param> private void ExplodeThisPoints(List <Vector> gonnaExplode) { OutputLog.AddLog("[BubbleGame] ExplodeThisPoints => " + gonnaExplode.Count); int count = gonnaExplode.Count; Vector[] around = new Vector[BubbleGrid.DirectionCount + 1]; for (int i = 0; i < count; i++) { List <ushort> tIds = new List <ushort>(); int result = map.GetAround(gonnaExplode[i], around); for (int e = 0; e < result; e++) { var bubble = map.GetFromPosition(around[e]); if (bubble != null) { tIds.Add(bubble.Id); AddScore(bubble.Numberos, 10); // add score, x10 Times!! map.RemoveFromPosition(around[e]); // bubble is killed. } } GameEvents.OnBubbleExploded?.Invoke(gonnaExplode[i].X, gonnaExplode[i].Y, tIds.ToArray()); } }
public void NextTurn() { if (!isStarted) { isStarted = true; CreateRows(startingRowCount, rowCrowdNess, true); } else { void unboundChecker() { // Remove unbounds if there is any. var unbounds = map.RemoveUnBounds(); foreach (var e in unbounds) { GameEvents.OnBubbleIsNowFree?.Invoke(e); } // } unboundChecker(); // Check for end game. Bubble[] bubbles = new Bubble[map.Size.X]; Vector[] positions = new Vector[map.Size.X]; int count = map.GetBubblesAtRow(map.Size.Y - 2, map.Size.X, ref bubbles, ref positions); if (count > 0) { // game over:( GameEvents.OnGameFinished?.Invoke(userScore); return; } CreateRows(rowCountAtPerTurn, rowCrowdNess, false); unboundChecker(); } if (activeBubble == null) { activeBubble = CreateBubble(ref idCounter); GameEvents.OnActiveBallCreated?.Invoke(activeBubble); OutputLog.AddLog("[BubbleGame] Active bubble Id => " + activeBubble.Id); } else { activeBubble = nextBubble; OutputLog.AddLog("[BubbleGame] Active bubble Id => " + activeBubble.Id); GameEvents.OnNextBallBecomeActive?.Invoke(); } nextBubble = CreateBubble(ref idCounter); GameEvents.OnNextBallSpawned?.Invoke(nextBubble); }
public void AddToPosition(Bubble bubble, Vector position) { if (grid[position.Y][position.X] != null) { OutputLog.AddError("[Grid] Target position is not empty. You cannot put anything on this position."); return; } grid[position.Y][position.X] = bubble; OutputLog.AddLog("[Grid] Bubble added to position => " + position); }
/// <summary> /// Returns the list of the unbound vectors. /// Unbound means, at least 1 non-empty grid point should be at the upper directions. /// X X B X X X B B X /// O O O /// Bound UnBound Bound /// </summary> /// <returns></returns> public List <ushort> RemoveUnBounds() { OutputLog.AddLog("Remove unbounds..."); List <ushort> unbounds = new List <ushort>(); int sizeX = Size.X; int sizeY = Size.Y; for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { Vector position = new Vector(x, y); var point = GetFromPosition(position); if (point != null) { bool found = false; // check for point. for (int i = 0; i < 3; i++) { var cPosition = position + seekDirections[DirectionCount - i - 1]; if (cPosition.Y < 0 || GetFromPosition(cPosition) != null) { found = true; break; } } if (!found) { // gone. unbounds.Add(point.Id); RemoveFromPosition(position); } } } } return(unbounds); }
public List <Vector> SeekForCombine(Vector mustContain) { int sizeY = Size.Y; int sizeX = Size.X; int bestLength = 0; int lastY = sizeY + 1; List <Vector> best = new List <Vector>(); for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { Vector position = new Vector(x, y); var bubble = GetFromPosition(position); if (bubble == null) { continue; } var cType = bubble.Numberos; var combines = GetCombinations(cType, position); combines.Insert(0, position); if (((bestLength == combines.Count && combines[combines.Count - 1].Y < lastY) || bestLength < combines.Count) && combines.Contains(mustContain)) { bestLength = combines.Count; best = combines; lastY = combines[combines.Count - 1].Y; OutputLog.AddLog("better combine path found, count => " + bestLength + ", y= " + lastY); } } } return(best); }
private void CheckForMatch(Vector position) { var combines = map.SeekForCombine(position); OutputLog.AddLog("combine count." + combines.Count); if (combines.Count < 2) { OutputLog.AddLog("no match."); } else { var mixTarget = map.GetFromPosition(position); // first member of combinations will get mixes, and start to combine. var except = new List <Vector>(); except.AddRange(combines); var mixes = map.GetMixes(mixTarget.Numberos, position, except); int mixCount = mixes.Count; OutputLog.AddLog("mix count => " + mixCount); // first mix for (int i = 0; i < mixCount; i++) { OutputLog.AddLog("mixing:" + mixes[i] + " to " + mixTarget.Id); GameEvents.OnBubbleMixed?.Invoke(map.GetFromPosition(mixes[i]).Id, mixTarget.Id); AddScore(mixTarget.Numberos); map.RemoveFromPosition(mixes[i]); } int length = combines.Count; for (int i = 0; i < length; i++) { OutputLog.AddLog("combine member: " + combines[i]); } List <Vector> gonnaExplode = new List <Vector>(); for (int i = 0; i < length - 1; i++) { var first = map.GetFromPosition(combines[i]); var next = map.GetFromPosition(combines[i + 1]); //OutputLog.AddLog("combining: " + first.Id + " to " + next.Id); AddScore(next.Numberos); GameEvents.OnBubbleCombined?.Invoke(first.Id, next.Id); if (!next.IncreaseNumberos()) { // max level reached. Explode gonnaExplode.Add(combines[i + 1]); } /// remove first. map.RemoveFromPosition(combines[i]); } ExplodeThisPoints(gonnaExplode); } }