/// <summary> /// Moves a piece down the grid /// </summary> /// <param name="collapse">Whether to move the piece all the way down to its resting point</param> /// <returns>Whether The piece is at its resting point</returns> public bool MoveDown(bool collapse = false) { do { int[] bottoms = FindBottomSurfaces(Structure); for (int x = 0; x < 4; x++) { if (Y + bottoms[x] == Tetris.Height || (bottoms[x] != 0 && TetrisState.Grid[X + x, Y + bottoms[x]] != Color.Transparent)) { return(true); } } //if we get here then we can move for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (Structure[x, y]) { TetrisState.Grid[x + X, y + Y] = Color.Transparent; } } } Y++; #if diagnose Debug.WriteLine("Move (0, 1)"); #endif LinkedList <Tuple <int, int> > reindex = new LinkedList <Tuple <int, int> >(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Structure[i, j]) { TetrisState.Grid[i + X, j + Y] = Color; reindex.AddLast(Tuple.Create(X + i, Y + j - 1)); } } } TetrisState.ReIndexTransitions(reindex, t => Tuple.Create(t.Item1, t.Item2 + 1)); TranslationTransition.FromTetromino(TetrisState, this, X, Y - 1, TransitionTime); }while (collapse); return(false); }
public int[] ClearFullLines() { bool[] toClear = FindFullLines(); int lookingAtY = Height - 1; int copyFromY = Height - 1; while (copyFromY > 0) { while (toClear[copyFromY]) { copyFromY--; } if (copyFromY == 0) { break; } if (lookingAtY != copyFromY) { LinkedList <Tuple <int, int> > reindex = new LinkedList <Tuple <int, int> >(); for (int x = 0; x < Width; x++) { reindex.AddLast(Tuple.Create(x, copyFromY)); Grid[x, lookingAtY] = Grid[x, copyFromY]; } ReIndexTransitions(reindex, t => Tuple.Create(t.Item1, lookingAtY)); TranslationTransition.FromRow(this, copyFromY, lookingAtY, Tetromino.TransitionTime); } copyFromY--; lookingAtY--; } while (lookingAtY >= 0) { for (int i = 0; i < Width; i++) { Grid[i, lookingAtY] = Color.Transparent; } lookingAtY--; } return(new int[1]); }
public void MoveRight() { int[] rights = FindRightSurfaces(Structure); for (int y = 0; y < 4; y++) { if (rights[y] != -1 && (rights[y] + X >= Tetris.Width || TetrisState.Grid[X + rights[y], Y + y] != Color.Transparent)) { return; } } for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (Structure[x, y]) { TetrisState.Grid[x + X, y + Y] = Color.Transparent; } } } X++; #if diagnose Debug.WriteLine("Move (1, 0)"); #endif LinkedList <Tuple <int, int> > reindex = new LinkedList <Tuple <int, int> >(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Structure[i, j]) { TetrisState.Grid[i + X, j + Y] = Color; reindex.AddLast(Tuple.Create(X + i - 1, Y + j)); } } } TetrisState.ReIndexTransitions(reindex, t => Tuple.Create(t.Item1 + 1, t.Item2)); TranslationTransition.FromTetromino(TetrisState, this, X - 1, Y, TransitionTime); }
public bool Rotate(bool left) { int oldX = X, oldY = Y; IEnumerable <Tuple <int, int> > reindex = new LinkedList <Tuple <int, int> >(); //erase old location for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (Structure[x, y]) { TetrisState.Grid[x + X, y + Y] = Color.Transparent; ((LinkedList <Tuple <int, int> >)reindex).AddLast(Tuple.Create(x + X, y + Y)); } } } bool[,] candidateStructure = Rotate(Structure, left ? 1 : 3); //check wall collisions, and try to correct for them //is there a left collision? int leftBound = FindLeftSurfaces(candidateStructure).Min(); if (X + leftBound < 0) { X = -leftBound - 1; } int rightBound = FindRightSurfaces(candidateStructure).Max(); if (X + rightBound >= Tetris.Width) { X = Tetris.Width - rightBound; } int bottomBound = FindBottomSurfaces(candidateStructure).Max(); if (Y + bottomBound >= Tetris.Height) { Y = Tetris.Height - bottomBound; } //check block intersections bool failure = false; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (candidateStructure[i, j] && TetrisState.Grid[i + X, j + Y] != Color.Transparent) { failure = true; break; } } } if (!failure) { //we have a valid location, put the tetromino there #if diagnose Debug.WriteLine("tetra rotating"); #endif if (oldX != X || oldY != Y) { reindex = TetrisState.ReIndexTransitions(reindex, t => Tuple.Create(t.Item1 + (X - oldX), t.Item2 + (Y - oldY))); TranslationTransition.FromTetromino(TetrisState, this, oldX, oldY, TransitionTime); } Structure = candidateStructure; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Structure[i, j]) { TetrisState.Grid[i + X, j + Y] = Color; } } } TetrisState.ReIndexTransitions(reindex, t => { Tuple <int, int> transformed = Tetromino.RotationTransform(Tuple.Create(t.Item1 - X, t.Item2 - Y), left ? 1 : 3); return(Tuple.Create(transformed.Item1 + X, transformed.Item2 + Y)); }); RotationTransition.FromTetromino(TetrisState, this, left ? -1 : 1, TransitionTime); return(true); } else { X = oldX; Y = oldY; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (Structure[x, y]) { TetrisState.Grid[x + X, y + Y] = Color; } } } return(false); } }