一、原理
这里以向上移动为例,其他方向的移动类似。
因为纵向移动不会横向变化,所以可以单独拿出某一列来分析。
我们先假设一个具有代表性的例子,假设当前某列数据是【2】【0】【2】【8】(0代表空白),如下图:

再来分析每个过程:
过程①->②,移动: 从下往上,通过平移的方式把中间的所有空白格(即data[x][y]=0)消除,这有点像“删除字符串中的空格题目”。
从这个特例中可以看出,只需【2】【8】同时要向上平移1次就能把中间的所有空白格消除得到②,
当然实际情况有多种类型,例如:
(a)需要把【8】向上平移2次
(b)需要把【16】平移3次(这也是最多移3次的情况)
很明显全空或全满的情况也不需要移动
【0】 【2】
【0】 【8】
【0】 【4】
【0】 【32】
过程②->③,合并: 在这一过程中我们要反过来,从上往下找相邻的两个单元格内是否有相同的数字,图中【2】【2】【8】【0】开头的两个数字相同,则把第二个【2】加到第一个【2】,并且把第二个【2】清空,得到③【4】【0】【8】【0】
过程③->④,再次移动: 经过过程②->③得到的【4】【0】【8】【0】中间产生了一个空白格,很明显不是我们想要的结果,这时我们再次用过程①->②的方法再次向上平移(<=3次),即可消除所有空白格,从而得到某列的最终结果④【4】【8】【0】【0】。
处理向上移动的完整代码如下,处理其他方向的同理
void moveUP()
{
int i,j;
int m=0,n=0;
for(i=0;i<4;i++)//列
{
//移动操作
j=0;n=0; //j为当前判定的所在行
while(n<3 && j<3)//n为移动的次数
{
if(data[j][i]==0) //若发现空白格
{
for(m=j;m<3;m++)//下方数据向上平移1格,覆盖空白格