2048核心算法
需求分析
2 | 2 | 2 | 2 |
---|---|---|---|
0 | 4 | 0 | 2 |
2 | 8 | 4 | 0 |
4 | 4 | 4 | 2 |
-
上移操作
- 由上到下获取第一列数据(一维数组) 。-》 2024
- 将0移动到末尾。-》 2240
- 相邻,相等的元素进行合并。将后面元素累加到前面元素上,然后将后面元素清0。-》 4040
- 将0移动到末尾。-》 4400
- 将处理后的数据还原到指定的列或行。
-
下移操作
- 由下到上获取第一列数据(一维数组) 。-》 4202
- 将0移动到末尾。-》 4220
- 相邻,相等的元素进行合并。将后面元素累加到前面元素上,然后将后面元素清0。-》 4400
- 将0移动到末尾。-》 4400
- 将处理后的数据还原到指定的列或行。
-
左移操作
- 由左到右获取第一行的数据(一维数组) 。-》 2222
- 将0移动到末尾。-》 2222
- 相邻,相等的元素进行合并。将后面元素累加到前面元素上,然后将后面元素清0。-》 4020
- 将0移动到末尾。-》 4200
- 将处理后的数据还原到指定的列或行。
-
右移操作
- 由右到左获取第一行的数据(一维数组) 。-》 2222
- 将0移动到末尾。-》 2222
- 相邻,相等的元素进行合并。将后面元素累加到前面元素上,然后将后面元素清0。-》 4020
- 将0移动到末尾。-》 4200
- 将处理后的数据还原到指定的列或行。
编码分析
- 将0移动末尾的方法。
- 合并数据方法(相邻,相等的元素进行合并。将后面元素累加到前面元素上,然后将后面元素清0。)
- 获取数据的方法
- 按什么方向取数据
- 合并处理数据
- 将处理好的数据,还原到指定的行或列
C#代码示例
/// <summary>
/// 将0移动到末尾
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[] RemoveZero(int[] arr)
{
// 创建相同大小的空数组
int[] newArr = new int[arr.Length];
int i = 0;
foreach (var v in arr)
{
// 将非0的数据存入新数组中
if (v != 0) newArr[i++] = v;
}
return newArr;
}
/// <summary>
/// 相邻,相同元素累加
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[] MergeArr(int[] arr)
{
// 去0
arr = RemoveZero(arr);
for (int i = 0; i < arr.Length - 1; i++)
{
if (arr[i] != 0 && arr[i] == arr[i + 1])
{
// 相邻,相同元素累加
arr[i] += arr[i + 1];
// 后一元素清0
arr[i + 1] = 0;
break;
}
}
// 去0
arr = RemoveZero(arr);
return arr;
}
/// <summary>
/// 向上移动
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[,] MoveUp(int[,] arr)
{
// 存放要合并的数组
int[] newArr = new int[arr.GetLength(0)];
// 列
for (int j = 0; j < arr.GetLength(1); j++)
{
// 由上到下取行数据
// 行
for (int i = 0; i < arr.GetLength(0); i++)
newArr[i] = arr[i, j];
// 合并数据
newArr = MergeArr(newArr);
// 还原数据
for (int i = 0; i < arr.GetLength(0); i++)
arr[i, j] = newArr[i];
}
return arr;
}
/// <summary>
/// 向下移动
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[,] MoveDown(int[,] arr)
{
// 存放要合并的数组
int[] newArr = new int[arr.GetLength(0)];
// 列
for (int j = 0; j < arr.GetLength(1); j++)
{
// 由下到上取行的数据
// 行
int maxLen = arr.GetLength(1);
for (int i = 0; i < maxLen; i++)
newArr[i] = arr[maxLen - 1 - i, j];
// 合并数据
newArr = MergeArr(newArr);
// 还原数据
for (int i = 0; i < arr.GetLength(1); i++)
arr[maxLen - 1 - i, j] = newArr[i];
}
return arr;
}
/// <summary>
/// 向左移动
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[,] MoveLeft(int[,] arr)
{
int[] newArr = new int[arr.GetLength(0)];
// 行
for (int i = 0; i < arr.GetLength(0); i++)
{
// 由左到右取列的数据
for (int j = 0; j < arr.GetLength(1); j++)
newArr[j] = arr[i, j];
// 合并数据
newArr = MergeArr(newArr);
// 还原数据
for (int j = 0; j < arr.GetLength(1); j++)
arr[i, j] = newArr[j];
}
return arr;
}
/// <summary>
/// 向右移动
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int[,] MoveRight(int[,] arr)
{
int[] newArr = new int[arr.GetLength(0)];
// 行
for (int i = 0; i < arr.GetLength(0); i++)
{
// 由右到左取列的数据
// 列
int maxLen = arr.GetLength(1);
for (int j = 0; j < maxLen; j++)
newArr[j] = arr[i, maxLen - 1 - j];
// 合并数据
newArr = MergeArr(newArr);
// 还原数据
for (int j = 0; j < arr.GetLength(1); j++)
arr[i, maxLen - 1 - j] = newArr[j];
}
return arr;
}
/// <summary>
/// 在控制顺打印二维数组
/// </summary>
/// <param name="arr"></param>
private static void PrintArr(int[,] arr)
{
// 行
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i, j] + "\t");
}
Console.WriteLine();
}
}
public static void Main()
{
int[,] arr = {
{ 2, 2, 2, 2 },
{ 2, 4, 4, 2 },
{ 2, 8, 0, 2 },
{ 2, 4, 4, 2 },
};
// 上移
arr = MoveUp(arr);
PrintArr(arr);
Console.WriteLine("-------------------");
// 下移
arr = MoveDown(arr);
PrintArr(arr);
Console.WriteLine("-------------------");
// 左移
arr = MoveLeft(arr);
PrintArr(arr);
Console.WriteLine("-------------------");
// 左移
arr = MoveRight(arr);
PrintArr(arr);
Console.WriteLine("-------------------");
}