public bool MoveBall(float x, float y) { if (this.selected == null) { return(false); } CLCell from = this.selected, to = GetCell(x, y); if (to == null) { return(false); } if (!IsReachable(from, to)) { return(false); } to.colour = from.colour; from.colour = CLColour.CLNone; this.selected.selected = false; this.selected = null; if (!BlowBalls(to)) { AddBalls(); } return(true); }
//cell is a four linked list public CLCell(int row, int column, CLCell top = null, CLCell bottom = null, CLCell left = null, CLCell right = null) { this.colour = CLColour.CLNone; this.row = row; this.column = column; this.selected = false; this.top = top; this.bottom = bottom; this.left = left; this.right = right; if (top != null) { top.bottom = this; } if (bottom != null) { bottom.top = this; } if (left != null) { left.right = this; } if (right != null) { right.left = this; } }
public bool SelectBall(float x, float y) { CLCell c = GetCell(x, y); if (c == null) { return(false); } if (c.colour == CLColour.CLNone) { return(false); } if (this.selected == c) { this.selected.selected = false; this.selected = null; return(true); } if (this.selected != null) { this.selected.selected = false; } this.selected = c; this.selected.selected = true; return(true); }
public void ClearField(bool restart = true) { for (CLCell cb = this.cells; cb != null; cb = cb.bottom) { for (CLCell cr = cb; cr != null; cr = cr.right) { cr.colour = CLColour.CLNone; } } if (this.selected != null) { this.selected.selected = false; this.selected = null; } if (restart) { this.ballsCount = 0; Random r = new Random(DateTime.Now.Millisecond); for (uint i = 0; i < 3; i++) { this.nextColours[i] = (CLColour)r.Next((int)CLColour.CLRed, (int)CLColour.CLMax); } //TODO: add fancy restart animation AddBalls(true); } this.score = 0; this.userScore.text = this.score.ToString(); this.bestScore.text = this.scoresTable[0, 1]; }
public CLField(int rows, int columns, int [] fieldTextures, Context context) { CLCell c = this.cells = new CLCell(0, 0); this.cellsCount++; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { if (i == 0 && j == 0) { continue; } CLCell ocell = null; if (i > 0) { ocell = this.cells; for (int k = 1; k < i; k++) { ocell = ocell.bottom; } for (int l = 0; l < j; l++) { ocell = ocell.right; } } if (j == 0) { c = null; } CLCell cell = new CLCell(i, j, top: ocell, left: c); this.cellsCount++; c = cell; } } c = this.cells; this.selected = null; this.rows = rows; this.columns = columns; this.score = 0; this.scoresTable = LoadBestScores(context); this.fieldTextures = fieldTextures; this.nextColours = new CLColour[3]; this.popUp = null; this.quit = false; Random r = new Random(DateTime.Now.Millisecond); for (uint i = 0; i < 3; i++) { this.nextColours[i] = (CLColour)r.Next((int)CLColour.CLRed, (int)CLColour.CLMax); } AddBalls(true); }
private CLCell GetCell(int row, int column) { CLCell cell = this.cells; for (uint i = 0; i < column; i++) { cell = cell.right; } for (uint j = 0; j < row; j++) { cell = cell.bottom; } return(cell); }
public bool IsReachable(CLCell from, CLCell to) { //the same point, wtf? should never happen if (from == to) { return(false); } bool[,] map = new bool[this.columns, this.rows]; CLCell cell = this.cells; for (int i = 0; i < this.rows; i++, cell = cell.bottom) { for (int j = 0; j < this.columns; j++, cell = cell.right) { if (cell == null) { break; } if (cell.colour == CLColour.CLNone) { map[j, i] = true; } else { map[j, i] = false; } } cell = this.cells; for (int k = 0; k < i; k++, cell = cell.bottom) { ; } if (cell == null) { break; } } SearchParameters searchParameters = new SearchParameters(new System.Drawing.Point(from.column, from.row), new System.Drawing.Point(to.column, to.row), map); PathFinder pathFinder = new PathFinder(searchParameters); if (pathFinder.HasPath()) { return(true); } return(false); }
private void BlowAnimation(CLCell newCell, CLCell cell, CLDirection dir) { CLCell c = cell; CLColour tempColour = newCell.colour; if (dir == CLDirection.CLLeft) { while (c.left != null && c.colour == c.left.colour) { c.colour = CLColour.CLNone; c = c.left; //TODO: add fancy opengl animations } } else if (dir == CLDirection.CLDown) { while (c.bottom != null && c.colour == c.bottom.colour) { c.colour = CLColour.CLNone; c = c.bottom; //TODO: add fancy opengl animations } } else if (dir == CLDirection.CLLeftDown) { while (c.bottom != null && c.left != null && c.colour == c.bottom.left.colour) { c.colour = CLColour.CLNone; c = c.bottom.left; //TODO: add fancy opengl animations } } else if (dir == CLDirection.CLRightDown) { while (c.bottom != null && c.right != null && c.colour == c.bottom.right.colour) { c.colour = CLColour.CLNone; c = c.bottom.right; //TODO: add fancy opengl animations } } c.colour = CLColour.CLNone; newCell.colour = tempColour; }
private bool BlowBalls(CLCell cell) { bool willBlow = false; int count = 1, countTotal = 0; //just to be sure..... if (cell.colour == CLColour.CLNone) { return(false); } /* LEFT-RIGHT (horizontal) balls sequence */ CLCell c = cell; while (c.left != null && c.colour == c.left.colour) { count++; c = c.left; } c = cell; while (c.right != null && c.colour == c.right.colour) { count++; c = c.right; } if (count >= 5) { countTotal = count; willBlow = true; BlowAnimation(cell, c, CLDirection.CLLeft); } /* BOTTOM-TOP (vertical) balls sequence */ count = 1; c = cell; while (c.bottom != null && c.colour == c.bottom.colour) { count++; c = c.bottom; } c = cell; while (c.top != null && c.colour == c.top.colour) { count++; c = c.top; } if (count >= 5) { if (willBlow) { countTotal--; } countTotal += count; willBlow = true; BlowAnimation(cell, c, CLDirection.CLDown); } /* BOTTOM|LEFT-TOP|RIGHT (increasing diagonal) balls sequence */ count = 1; c = cell; while (c.bottom != null && c.left != null && c.colour == c.bottom.left.colour) { count++; c = c.bottom.left; } c = cell; while (c.top != null && c.right != null && c.colour == c.top.right.colour) { count++; c = c.top.right; } if (count >= 5) { if (willBlow) { countTotal--; } countTotal += count; willBlow = true; BlowAnimation(cell, c, CLDirection.CLLeftDown); } /* BOTTOM|RIGHT-TOP|LEFT (decreasing diagonal) balls sequence */ count = 1; c = cell; while (c.bottom != null && c.right != null && c.colour == c.bottom.right.colour) { count++; c = c.bottom.right; } c = cell; while (c.top != null && c.left != null && c.colour == c.top.left.colour) { count++; c = c.top.left; } if (count >= 5) { if (willBlow) { countTotal--; } countTotal += count; willBlow = true; BlowAnimation(cell, c, CLDirection.CLRightDown); } if (willBlow) { this.ballsCount -= countTotal; this.score += AddScore(countTotal); this.userScore.text = this.score.ToString(); cell.colour = CLColour.CLNone; //TODO: add fancy opengl animations } return(willBlow); }
private void AddBalls(bool restart = false) { Random r = new Random(DateTime.Now.Millisecond); CLCell c = this.cells; int count = this.rows * this.columns - this.ballsCount; if (restart) { count = 5; } else if (count > 3) { count = 3; } for (int i = 0, n = count; i < n; i++, c = this.cells) { int column = r.Next(this.columns), row = r.Next(this.rows); for (int k = 0; k < row; k++) { c = c.bottom; } for (int l = 0; l < column; l++) { c = c.right; } //if the cell already has a ball then seek for the next empty one if (c.colour != CLColour.CLNone) { i--; continue; } if (!(restart && i > 2)) { c.colour = this.nextColours[i]; this.nextColours[i] = (CLColour)r.Next((int)CLColour.CLRed, (int)CLColour.CLMax); } else { c.colour = (CLColour)r.Next((int)CLColour.CLRed, (int)CLColour.CLMax); } if (!restart && BlowBalls(c) && n < 3) { n = 3; } } this.ballsCount += count; int nextCount = this.rows * this.columns - this.ballsCount; if (nextCount == 1) { this.nextColours[1] = this.nextColours[2] = CLColour.CLNone; } else if (nextCount == 2) { this.nextColours[2] = CLColour.CLNone; } else if (nextCount <= 0) { if (!CheckNewScore()) { this.ClearField(); } else { RequestUserName(); } } }
public void Draw(bool landscape, float left, float right, float bottom, float top) { float step; // CLReDraw.Rect(-1.0f, 1.0f, 2.0f, 2.0f, Color.Argb(255, 127, 127, 127)); if (this.rows > this.columns) { step = 2.0f / this.rows; } else { step = 2.0f / this.columns; } CLCell cell = this.cells; for (int i = 0; i < this.rows; i++, cell = cell.bottom) { for (int j = 0; j < this.columns; j++, cell = cell.right) { if (cell == null) { break; } cell.Draw(j * step - 1.0f, 1.0f - i * step, step, step, this.fieldTextures); } cell = this.cells; for (int k = 0; k < i; k++, cell = cell.bottom) { ; } if (cell == null) { break; } } float radius = step / 5.0f; if (!landscape) { CLReDraw.Rect(left + step * 3, top, step, step, this.fieldTextures[0]); if (this.nextColours[0] != CLColour.CLNone) { CLReDraw.Rect(left + step * 3.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[0]]); } CLReDraw.Rect(left + step * 4, top, step, step, this.fieldTextures[0]); if (this.nextColours[1] != CLColour.CLNone) { CLReDraw.Rect(left + step * 4.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[1]]); } CLReDraw.Rect(left + step * 5, top, step, step, this.fieldTextures[0]); if (this.nextColours[2] != CLColour.CLNone) { CLReDraw.Rect(left + step * 5.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[2]]); } } else { CLReDraw.Rect(left, top, step, step, this.fieldTextures[0]); if (this.nextColours[0] != CLColour.CLNone) { CLReDraw.Rect(left + step * 0.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[0]]); } CLReDraw.Rect(left + step, top, step, step, this.fieldTextures[0]); if (this.nextColours[1] != CLColour.CLNone) { CLReDraw.Rect(left + step * 1.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[1]]); } CLReDraw.Rect(left + step * 2, top, step, step, this.fieldTextures[0]); if (this.nextColours[2] != CLColour.CLNone) { CLReDraw.Rect(left + step * 2.5f - radius, top - step * 0.5f + radius, radius * 2, radius * 2, this.fieldTextures[(int)this.nextColours[2]]); } } int textureId = (int)CLColour.CLMax + (int)CLLabelSize.CLSmall; this.bestScore.Draw(this.fieldTextures[textureId], 0.0f, 0.0f); this.userScore.Draw(this.fieldTextures[textureId], 0.0f, 0.0f); this.results.Draw(this.fieldTextures[textureId], 0.0f, 0.0f); this.start.Draw(this.fieldTextures[textureId], 0.0f, 0.0f); this.exit.Draw(this.fieldTextures[textureId], 0.0f, 0.0f); if (this.popUp != null) { this.popUp.ExtraDraw(); } }