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();
            }
        }