#include<stdio.h>
#include<stdlib.h>//提供随机函数,清屏
#include<time.h>//为随机函数提供参数
#include<conio.h>//提供getch()函数
int map[4][4]={0};//游戏地图
int score=0;//分数
int movenum=-1;//移动次数
char input;//控制方向
int gameover=1;//判断游戏是否结束,0结束
int change=1;//判断数组是否改变,0不变
void menu(){
system("CLS");//每显示一次清屏之前的重新打印
int i=0,j=0;
printf(" 欢迎来到2048\n");
printf(" ----------------------------------------\n");
printf(" W——UP S——DOWN A——LEFT D——RIGHT\n");
printf(" Please enter 0 if you do not want paly.\n");
printf(" MOVE:%d SCORE:%d\n",movenum,score);
printf(" \n |-------------------------------------------|\n");
for ( i = 0; i <= 3; i++)
{
for ( j = 0; j<= 3; j++)
{
printf(" ");
if (map[i][j]==0)
printf("| ");
else
printf("|%5d",map[i][j]);
}
printf(" |\n |-------------------------------------------|\n");
}
}
int randIntNum(){//再数组里随机生成一个地址并赋值
int i,j,n;
if (change>=1)
{
do{
i=((unsigned)rand())%4;
j=((unsigned)rand())%4;
}while(map[i][j]!=0);
n=((unsigned)rand())%2;
if (n==0)
map[i][j]=n+2;
else
map[i][j]=n+3;
movenum++;
}
}
int up(){//向上
int now,next;
int i,j,k;
for (j = 0; j < 4; j++)//第一个for语句是把当前控制方向的数组里相同的数合并,其他方向的都是一样
{
for ( i = 0; i < 4; i++)
{
now=map[i][j];
if (now!=0)
{
k=i+1;
while(k<4){
next=map[k][j];
if (next!=0)
{
if (now==next)
{
change=1;
score+=map[k][j];
map[i][j]=2*map[k][j];
map[k][j]=0;
}
k=4;
}
k++;
}
}
}
}
for (j = 0; j < 4; j++)//第二个for语句是把当前控制方向的非零元素移动当前方向的前面
{
for (i = 0; i <4 ; i++)
{
now=map[i][j];
if (now==0)
{
k=1+i;
while(k<4){
next=map[k][j];
if (next!=0)
{
change=1;
map[i][j]=next;
map[k][j]=0;
k=4;
}
k++;
}
}
}
}
return change;
}
int right(){//向右
int i,j;
int now,next,k;
for ( i = 0; i < 4; i++)
{
for ( j = 3; j >= 0; j--)
{
now=map[i][j];
k=j-1;
while(k>=0){
next=map[i][k];
if (next!=0)
{
if (next==now)
{
change=1;
map[i][j]=map[i][k]*2;
map[i][k]=0;
}
k=-1;
}
k--;
}
}
}
for ( i = 0; i < 4; i++)
{
for ( j = 3; j >= 0; j--)
{
now=map[i][j];
if (now==0)
{
k=j-1;
while(k>=0){
next=map[i][k];
if (next!=0)
{
change=1;
map[i][j]=map[i][k];
map[i][k]=0;
k=-1;
}
k--;
}
}
}
}
return change;
}
int left(){//向左
int i,j;
int now,next,k;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
now=map[i][j];
k=j+1;
while(k<4){
next=map[i][k];
if (next!=0)
{
if (now==next)
{
change=1;
score+=map[i][k];
map[i][j]=map[i][k]*2;
map[i][k]=0;
}
k=4;
}
k++;
}
}
}
for ( i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
now=map[i][j];
if (now==0)
{
k=j+1;
while(k<4){
next=map[i][k];
if (next!=0)
{
change=1;
map[i][j]=map[i][k];
map[i][k]=0;
k=4;
}
k++;
}
}
}
}
return change;
}
int down(){//向下
int i,j;
int now,next,k;
for ( j = 0; j < 4; j++)
{
for ( i = 3; i >= 0; i--)
{
now=map[i][j];
if (now!=0)
{
k=i-1;
while(k>=0){
next=map[k][j];
if (next!=0)
{
if (now==next)
{
change=1;
map[i][j]=map[k][j]*2;
map[k][j]=0;
}
k=-1;
}
k--;
}
}
}
}
for ( j = 0; j < 4; j++)
{
for ( i = 3; i >= 0; i--)
{
now=map[i][j];
if (now==0)
{
k=i-1;
while(k>=0){
next=map[k][j];
if (next!=0)
{
change=1;
map[i][j]=map[k][j];
map[k][j]=0;
k=-1;
}
k--;
}
}
}
}
return change;
}
void move(){//控制移动
int i,j;
input=getch();//键盘读取控制
change=0;
switch(input){
case '0':
printf("Do you want exit?(y/n):");
input=getchar();
if (input=='y'||input=='Y')
exit(0);
break;
case 'w':
case 'W':
up();
break;
case 'a':
case 'A':
left();
break;
case 's':
case 'S':
down();
break;
case 'd':
case 'D':
right();
break;
}
}
int over(){//判断游戏是否结束
int i,j;
gameover=0;
for ( i = 0; i < 4; i++)
{
for ( j = 0; j < 4; j++)
{
if(map[i][j]==0)
gameover=1;
if(i>1){
if (map[i][j]==map[i-1][j])
gameover=1;
}
if (j>1){
if (map[i][j]==map[i][j-1])
gameover=1;
}
}
}
return 0;
}
void start(){//游戏开始
srand((unsigned)time(NULL));
while(gameover==1){
randIntNum();
menu();
move();
over();
}
}
int main(){
start();
printf(" GAME OVER\n");
printf(" YOUR SCORE IS %d\n",score );
printf(" YOUR MOVE %d TIMES\n",movenum);
return 0;
}