#include "stdio.h"
#include "windows.h"
#include "conio.h"
#include "stdlib.h"
#define MAX 10
int box[MAX][MAX];
/* http://black4yl.blog.51cto.com
Black4yL: 2015年1月4日
/---2 0 4 8 游戏---\ (纯属练 数组 , 方向感, 测试是否瞌睡,以及 高数,大物,相对运动...)
以 left为例说明原理:
0x01: 进入left函数
0x02:
left(),(1)首先是moveleft操作,也即将所有数字左移
(2)然后是megerleft操作,也即左移后的同数字合并
合并完了,还必须执行一次移动,因为可能会有中间空隙.
比如 2 4 4 8 移动后是 2 8 空 8,需要再次移动变为 2 8 8 空
(3)最后就是返回一个 bool 型 ret值,表示当前数字是否发生变化,变化了需要
检查是否满了? 变化了还需要 随机生成一个数字,继续游戏~
0x03: 详解
mov 操作
for( )
for( )
{
(1)找空闲列
(2)前移
(3)修改移动的位置为 空 (-1)
}
meger操作
遍历数组,left情况 则 以行优先,列值由0 -> n-1
up情况 则 以列优先,行值由0 -> n-1
其他 同理。
寻找前后是否有相同值,有则 消除后面的,前面的数字X2
*/
bool megerleft(int n) //left 合并
{
bool ret = false;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(box[i][j] == -1) continue;
if(box[i][j] == box[i][j+1])
{
box[i][j] *= 2;
box[i][j+1] = -1;
ret = true;
j++;
}
}
}
return ret;
}
bool movleft(int n)
{
bool ret = false;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int k;
for(k=j-1;k>=0;k--) //找到第i行 j列前面第一个不是空的位置
{
if( box[i][k] != -1) break;
}
box[i][k+1] = box[i][j]; //插到它的前一个(这个不为空,前一个肯定是空)
if( k+1 != j) //如果发生移动,也就是 k != j-1 ,也就是 k+1 ! = j
{
box[i][j] = -1; //移动了 ,填充为空
ret = true; //发生变化
}
}
}
return ret;
}
bool left(int n)
{
bool ret = false;
ret = movleft(n);
ret = megerleft(n);
ret = movleft(n);
return ret;
}
bool megerright(int n)
{
bool ret = false;
for(int i=0;i<n;i++)
for(int j=n-1;j>=0;j--)
{
if( box[i][j] == -1) continue;
if( box[i][j] == box[i][j-1])
{
box[i][j] *= 2;
box[i][j-1] = -1;
ret = true;
j-- ;
}
}
return ret;
}
bool movright(int n)
{
bool ret = false;
for(int i=0;i<n;i++)
for(int j=n-1;j>=0;j--)
{
int k;
for(k=j+1;k<n;k++)
{
if(box[i][k]!=-1)
break;
}
box[i][k-1] = box[i][j];
if( k-1 != j)
{
box[i][j] = -1;
ret = true;
}
}
return ret;
}
bool right(int n)
{
bool ret = false;
ret = movright(n);
ret = megerright(n);
ret = movright(n);
return ret;
}
bool megerup(int n)
{
bool ret = false;
for( int i=0 ;i <n;i++) // 此时为列
for(int j=0 ; j<n;j++) // 此时为行
{
if( box[j][i] == -1) continue;
if( box[j][i] == box[j+1][i] )
{
box[j][i] *= 2;
box[j+1][i] = -1;
ret = true;
j++;
}
}
return ret;
}
bool movup(int n)
{
bool ret = false;
for( int i=0 ;i <n;i++) // 此时为列
for(int j=0 ; j<n;j++) // 此时为行
{
int k ;
for( k =j -1 ; k>=0 ; k--) //行变化
{
if( box[k][i] != -1) break;
}
box[k+1][i] = box[j][i];
if(k+1 != j)
{
box[j][i] = -1;
ret = true;
}
}
return ret;
}
bool up(int n)
{
bool ret = false;
ret = movup(n);
ret = megerup(n);
ret = movup(n);
return ret;
}
bool megerdown(int n)
{
bool ret = false;
for( int i = 0; i<n;i++) //列
for( int j = n-1; j >=0; j--) //行
{
if( box[j][i] == -1) continue;
if( box[j][i] == box[j-1][i])
{
box[j][i] *= 2;
box[j-1][i] = -1;
j--;
ret = true;
}
}
return ret;
}
bool movdown(int n)
{
bool ret = false;
for( int i = 0; i<n;i++) //列
for( int j = n-1;j>=0;j--) //行
{
int k;
for(k = j+1;k<n;k++)
{
if( box[k][i] != -1)
break;
}
box[k-1][i] = box[j][i];
if( k-1 != j)
{
box[j][i] = -1;
ret = true;
}
}
return ret;
}
bool down(int n)
{
bool ret = false;
ret = movdown(n);
ret = megerdown(n);
ret = movdown(n);
return ret;
}
void line(int n)
{
for (int i = 0; i < n; ++i)
{
printf("--------");
}
printf("-");
printf("\n");
}
void print(int n)
{
for(int i=0;i<n;i++)
{
line(n);
for(int j=0 ; j<n ; j++)
{
printf("|");
if( box[i][j] == -1)
{
printf("\t");
}
else
printf("%2d\t", box[i][j]);
}
printf("|");
printf("\n");
}
line(n);
}
bool isfull(int n) //是否 满
{
bool ret = true;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if( box[i][j] == -1)
{
ret = false;
return ret;
}
}
return ret; //满
}
bool isOver(int n) //是否 结束游戏
{
if( !isfull(n))
return false;
for(int i=0;i<n;i++)
for( int j=0;j<n;j++)
{
if( box[i][j] == box[i][j+1] || box[i][j] == box[i+1][j]) //有相同的
return false;
}
return true;
}
void fillbox(int n) //随机填充
{
int i,j,num;
if( isfull(n)) //格子满
return ;
while(1)
{
i = rand() % n;
j = rand() % n;
num = rand() % 2 ? 2 : 4;
if(box[i][j] == -1)
{
box[i][j] = num;
break;
}
}
}
void main()
{
char ch;
int n = 9;
memset(box,-1,sizeof(box));
bool mak = false ;
fillbox(n);
while(1)
{
system("CLS");
print(n);
ch = getch();
switch(ch)
{
case ‘a‘:
mak = left(n);
break;
case ‘d‘:
mak = right(n);
break;
case ‘w‘:
mak = up(n);
break;
case ‘s‘:
mak = down(n);
break;
default:
continue;
}
if(mak) //有变化
{
fillbox(n);
if(isOver(n))
{
system("CLS");
printf("Game oVer!\n");
break;
}
}
}
}本文出自 “black4yL” 博客,请务必保留此出处http://black4yl.blog.51cto.com/4222963/1599484
原文:http://black4yl.blog.51cto.com/4222963/1599484