private Positions FindFarthestPosition(CellPosition cell, Vector vector)
        {
            CellPosition previous;

            // Progress towards the vector direction until an obstacle is found
            do
            {
                previous = cell;

                cell = new CellPosition(previous.X + vector.X, previous.Y + vector.Y);
            } while (_grid.WithinBounds(cell) &&
                     _grid.CellAvailable(cell));

            return(new Positions(
                       previous,
                       cell // Used to check if a merge is required
                       ));
        }
Exemple #2
0
 public bool WithinBounds(CellPosition position)
 {
     return(WithinBounds(position.X, position.Y));
 }
Exemple #3
0
 public GameTile CellContent(CellPosition position)
 {
     return(CellContent(position.X, position.Y));
 }
Exemple #4
0
 public bool IsEqual(CellPosition pos)
 {
     return(X == pos.X && Y == pos.Y);
 }
Exemple #5
0
 private bool CellOccupied(CellPosition position)
 {
     return(null != Cells[position.X, position.Y]);
 }
Exemple #6
0
 // Check if the specified cell is taken
 public bool CellAvailable(CellPosition position)
 {
     return(!CellOccupied(position));
 }
 public Positions(CellPosition farthest, CellPosition next)
 {
     Farthest = farthest;
     Next     = next;
 }
 private void MoveTile(GameTile tile, CellPosition cell)
 {
     _grid.Cells[tile.Position.X, tile.Position.Y] = null;
     _grid.Cells[cell.X, cell.Y] = tile;
     tile.UpdatePosition(cell);
 }
        // Move tiles on the grid in the specified direction
        private void InternalMove(MoveDirection direction)
        {
            if (IsGameTerminated())
            {
                return;                     // Don't do anything if the game's over
            }
            GameTile tile = null;

            var vector     = GetVector(direction);
            var traversals = new Traversals(_size, vector);
            var moved      = false;

            // Save the current tile positions and remove merger information
            PrepareTiles();

            // Traverse the grid in the right direction and move tiles
            foreach (var x in traversals.Xs)
            {
                foreach (var y in traversals.Ys)
                {
                    var cell = new CellPosition(x, y);
                    tile = _grid.CellContent(cell);

                    if (null != tile)
                    {
                        var positions = FindFarthestPosition(cell, vector);
                        var next      = _grid.CellContent(positions.Next);

                        // Only one merger per row traversal?
                        if (null != next && next.Value == tile.Value && (null == next.MergedFrom))
                        {
                            var merged = new GameTile(positions.Next, tile.Value * 2);
                            merged.MergedFrom = new MergeTile(tile.Position, next.Position);

                            _grid.InsertTile(merged);
                            _grid.RemoveTile(tile);

                            // Converge the two tiles' positions
                            tile.UpdatePosition(positions.Next);

                            // Update the score
                            Score += merged.Value;

                            // The mighty 2048 tile
                            if (merged.Value == _winingTileValue)
                            {
                                Won = true;
                            }
                        }
                        else
                        {
                            MoveTile(tile, positions.Farthest);
                        }

                        if (!cell.IsEqual(tile.Position))
                        {
                            moved = true; // The tile moved from its original cell!
                        }
                    }
                }
            }

            if (moved)
            {
                AddRandomTile();

                if (!MovesAvailable())
                {
                    Over = true; // Game over!
                }

                Actuate();
            }
        }