public static Grid MakeMove(Grid grid, Move move) { var newGrid = new int[4, 4]; switch (move) { case Move.Left: for (var y = 0; y < 4; y++) { var nonZeroes = merge(grid.GetRow(y).Where(n => n != 0).ToArray()); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[i, y] = nonZeroes[i]; } } break; case Move.Right: for (var y = 0; y < 4; y++) { var nonZeroes = merge(grid.GetRow(y).Where(n => n != 0).ToArray().Reverse().ToArray()).Reverse().ToArray(); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[i + (4-l), y] = nonZeroes[i]; } } break; case Move.Up: for (var x = 0; x < 4; x++) { var nonZeroes = merge(grid.GetColumn(x).Where(n => n != 0).ToArray()); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[x, i] = nonZeroes[i]; } } break; case Move.Down: for (var x = 0; x < 4; x++) { var nonZeroes = merge(grid.GetColumn(x).Where(n => n != 0).ToArray().Reverse().ToArray()).Reverse().ToArray(); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[x, i + (4-l)] = nonZeroes[i]; } } break; default: throw new ArgumentOutOfRangeException("move"); } return new Grid(newGrid); }