2048开发
其他项目开发
[Windows通用应用开发] 2048
[Windows通用应用开发] 俄罗斯方块
算法流程
以从左向右滑动为例,其他的移动方式算法相似。
从右往左看:本格不为空,一直向前看,直到不空的格,看数字是否与本格一致。
本格为空,向前一格看。
若前一格为空,类似于本格为空的算法,继续向前一格看。
若前一格不为空,再向前看。
前面全部为空,直接将此格右移。
前面有非空格,看能否合并右移,否则直接右移。
继续循环,对前一格使用此算法。
- 示例代码
TBSet是TextBlock数组,存放界面中的16个数字。
IsFill为Bool数组,标识16格是否为空。
ClearRect方法用于清除界面显示及本格标识。
MoveMent类定义在后面。
private List<MoveMent> ToMove = new List<MoveMent>();
private void MoveRight()
{
bool[] IsFill = new bool[16];
for (int i = 0; i < 16; i++)
{
if (NumberSet[i] == 0)
IsFill[i] = false;
else
IsFill[i] = true;
}
for (int i = 3; i > 0; i--) //X
{
for (int j = 0; j < 4; j++) //Y
{
int num = 0;
if (IsFill[i + j * 4] == true)
num = NumberSet[i + j * 4]; //获取本格数字
int k = i - 1;
if (num == 0) //i格为空,
{
if (IsFill[k + j * 4] == true) //k格不为空
{
int KNum = NumberSet[k + j * 4];
if (k > 0)
{
//再往前看,是否有可以合成的
if (IsFill[k - 1 + j * 4] == true)
{
int KMinusNum = NumberSet[k - 1 + j * 4];
if (KNum == KMinusNum)
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 1, j, i, j, KNum, KNum - 1);
ToMove.Add(m1);
MoveMent m2 = new MoveMent(MoveMent.Direct.Right, k, j, i, j, KNum, KNum - 1);
ToMove.Add(m2);
IsFill[k - 1 + j * 4] = false;
IsFill[k + j * 4] = false;
}
}
else if (k - 1 > 0)
{
if (IsFill[k - 2 + j * 4] == true)
{
int KMinus2Num = NumberSet[k - 2 + j * 4];
if (KNum == KMinus2Num)
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 2, j, i, j, KNum, KNum - 1);
ToMove.Add(m1);
MoveMent m2 = new MoveMent(MoveMent.Direct.Right, k, j, i, j, KNum, KNum - 1);
ToMove.Add(m2);
IsFill[k - 2 + j * 4] = false;
IsFill[k + j * 4] = false;
}
}
}
}
if (ToMove.Where(n => n.StartX == k && n.StartY == j && n.d == MoveMent.Direct.Right).Count() == 0)
{
MoveMent m3 = new MoveMent(MoveMent.Direct.Right, k, j, i, j, KNum, KNum);
ToMove.Add(m3);
IsFill[k + j * 4] = false;
}
}
else if (k > 0)
{
if (IsFill[k - 1 + j * 4] == true)
{
int KMinusNum = NumberSet[k - 1 + j * 4];
if (k - 1 > 0 && IsFill[k - 2 + j * 4] == true)
{
int KMinus2Num = NumberSet[k - 2 + j * 4];
if (KMinusNum == KMinus2Num)
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 2, j, i, j, KMinusNum, KMinusNum - 1);
ToMove.Add(m1);
MoveMent m2 = new MoveMent(MoveMent.Direct.Right, k - 1, j, i, j, KMinusNum, KMinusNum - 1);
ToMove.Add(m2);
IsFill[k - 1 + j * 4] = false;
IsFill[k - 2 + j * 4] = false;
}
else
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 1, j, i, j, KMinusNum, KMinusNum);
ToMove.Add(m1);
IsFill[k - 1 + j * 4] = false;
}
}
else
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 1, j, i, j, KMinusNum, KMinusNum);
ToMove.Add(m1);
IsFill[k - 1 + j * 4] = false;
}
}
else if (k - 1 > 0 && IsFill[k - 2 + j * 4] == true)
{
int KMinus2Num = NumberSet[k - 2 + j * 4];
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, k - 2, j, i, j, KMinus2Num, KMinus2Num);
ToMove.Add(m1);
IsFill[k - 2 + j * 4] = false;
}
}
}
else
{
for (int l = i - 1; l >= 0; l--)
{
if (IsFill[l + j * 4] == true)
{
int LNum = NumberSet[l + j * 4];
if (LNum == num)
{
MoveMent m1 = new MoveMent(MoveMent.Direct.Right, l, j, i, j, num, num - 1);
ToMove.Add(m1);
IsFill[l + j * 4] = false;
break;
}
else
break;
}
}
}
}
}
}
public class MoveMent
{
public enum Direct
{ Left, Right, Up, Down };
public Direct d;
public int StartX;
public int StartY;
public int EndX;
public int EndY;
public int NumOriginal;
public int NumWillBe;
public MoveMent(Direct dd, int Sx, int Sy, int Ex, int Ey, int Num1, int Num2)
{
d = dd;
StartX = Sx;
StartY = Sy;
EndX = Ex;
EndY = Ey;
NumOriginal = Num1;
NumWillBe = Num2;
}
}
其他的移动方式代码与此类似,不再叙述。
所有代码均通过Windows 10 Mobile和Windows 10真机调试