栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2048小游戏c语言(附带颜色)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2048小游戏c语言(附带颜色)

//全文复制,可直接使用,具体的解析看注释,函数都是使用的比较通俗易懂的写法,不可直接抄袭

#include

#include//控制台输入输出函数头文件//getch

#include//提供rand函数,清屏函数

#include//随机数种子

#include//用于附颜色

 

void printmap();//输出整个二维数组和分数信息

void printline(int i);//输出某一行

void putnewnum();//在空白单元格内随机放置2或4

int getemptynum();//获取空白单元格数量

void copydata();//数据复制

int comparedata();//判断数据前后是否一致

int getmax();//获取当前二维数组中最大的数字

int gameover();//判断游戏是否结束

void moveup();//上移

void movedown();//下移

void moveleft();//左移

void moveright();//右移

int color(int num);//num为每一种颜色所代表的数字,范围是0~15

int setcolor(int n);//给不同数字附不同颜色

 

//全局变量

int data[4][4];

int old_data[4][4];

int count=0;//次数

int sum=0;//分数

 

//显示部分

void printmap()//输出整个二维数组和分数信息

{

    printf("┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┓n"); 

 printline(0);

 printf("┣━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━┫n");  

 printline(1);

 printf("┣━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━┫n");  

 printline(2);

 printf("┣━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━━━━┫n");  

 printline(3);

    printf("┗━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━━━━┛n");  

 printf("最大值:%dn",getmax());

 printf("游戏分数:%dn",sum);

 printf("操作次数:%dn",count);

 printf("剩余空间:%dn",getemptynum());

 printf("退出游戏:qn");

 if(gameover()==1)printf("很遗憾游戏结束!按q键退出");

 if(getmax()>=2048)printf("恭喜你通关了!n");

}

 

void printline(int i)//行

{

 int j;//列

 for(j=0;j<4;j++){

  printf("┃");

  if(data[i][j]==0)printf(" ");

  else {

   setcolor(data[i][j]);

   printf(" %4d ",data[i][j]);

   color(7);//制表变回白色

  }

 }

    printf("┃n");

}

int getemptynum()//获取空白单元格数量n

{

 int i,j,n=0;

 for(i=0;i<4;i++){

   for(j=0;j<4;j++){

    if(data[i][j]==0)n++;

  }

 }

 return n;

}

 

void putnewnum()//在空白单元格内随机放置2或4

{

    int i,j,a,b;

    a=1+rand()%getemptynum();//生成随机数,范围:[1,空白单元格数];

    b=(rand()%2+1)*2;//b为2或4

    for(i=0;i<4;i++){

  for(j=0;j<4;j++){

   if(data[i][j]==0){

    a--;

    if(a==0)data[i][j]=b;//把2或4放入某个空白单元格内

   }

  }

 }

}

 

void copydata()

{

 int i,j;

 for(i=0;i<4;i++)

  for(j=0;j<4;j++)

   old_data[i][j]=data[i][j];

 

}

int comparedata()

{

 int i,j;

 for(i=0;i<4;i++)

  for(j=0;j<4;j++)

   if(old_data[i][j] != data[i][j])return 0; 

 return 1; 

}

int getmax()//获取当前二维数组中最大的数字

{

 int max=0;

 int i,j;

 for(i=0;i<4;i++){

   for(j=0;j<4;j++){

    if(data[i][j]>max)max=data[i][j];

  }

 }

 return max;

}

void moveup()

{

 int i,j,m,n;

 for(i=0;i<4;i++)//列

 {

  //移动操作

  j=0;n=0; //j为当前判定的所在行

  while(n<3&&j<3)//n为移动的次数

  {

   if(data[j][i]==0) //当数据为0时

   {

    for(m=j;m<3;m++)//下方数据向上平移1格,覆盖空白格

     data[m][i]=data[m+1][i]; 

    

    data[3][i]=0; //最后一行置0

    n++; //移动的次数+1

   }

   else j++; //否则:让当前判定的所在行+1

  }

 

  //合并操作

  for(j=0;j<3;j++)//行

   if(data[j][i]==data[j+1][i]&&data[j][i]!=0)//相同(且不是0)则合并

   { // 0和0不需要合并

    data[j][i]=data[j][i]*2;//上面的保存合并后的数字

    sum=sum+data[j][i];

    data[j+1][i]=0; //下面的清零

   }

  //合并之后可能需要再次移动

  //移动操作

  j=0;n=0;

  while(n<3&&j<3)                                                                                                                                                                                                                                                                          

  {

   if(data[j][i]==0)

   {

    for(m=j;m<3;m++)

     data[m][i]=data[m+1][i]; 

    data[3][i]=0;

    n++; 

   }

   else j++;

  }

 }

}

 

void movedown()

{

 int i,j,m,n;

 for(i=0;i<4;i++)

 {

  //移动操作

  j=3;n=0;

  while(n<3&&j>0)

  {

   if(data[j][i]==0)

   {

    for(m=j;m>0;m--)data[m][i]=data[m-1][i]; 

    data[0][i]=0;

    n++; 

   }else j--;

  }

 

  //合并操作

  for(j=3;j>0;j--)

   if(data[j][i]==data[j-1][i]&&data[j][i]!=0)

   {

    data[j][i]=data[j][i]*2;

    sum=sum+data[j][i];

    data[j-1][i]=0;   

   }

  //移动操作

  j=3;n=0;

  while(n<3&&j>0)

  {

   if(data[j][i]==0)

   {

    for(m=j;m>0;m--)data[m][i]=data[m-1][i]; 

    data[0][i]=0;

    n++; 

   }

   else j--;

  }

 }

}

 

void moveleft()

{

 int i,j,m,n;

 for(i=0;i<4;i++)

 {

  //移动操作

  j=0;n=0;

  while(n<3&&j<3)

  {

   if(data[i][j]==0)

   {

    for(m=j;m<3;m++)data[i][m]=data[i][m+1]; 

    data[i][3]=0;

    n++; 

   }else j++;

  }

  //合并操作

  for(j=0;j<3;j++)

   if(data[i][j]==data[i][j+1]&&data[i][j]!=0)

   {

    data[i][j]=data[i][j]*2;

    sum=sum+data[i][j];

    data[i][j+1]=0;  

   }

  //移动操作

  j=0;n=0;

  while(n<3&&j<3)

  {

   if(data[i][j]==0)

   {

    for(m=j;m<3;m++)data[i][m]=data[i][m+1]; 

    data[i][3]=0;

    n++; 

   }

   else j++;

  }

 }

}

 

void moveright()

{

    int i,j,m,n;

 for(i=0;i<4;i++)

 {

  //移动操作

  j=3;n=0;

  while(n<3&&j>0)

  {

   if(data[i][j]==0)

   {

    for(m=j;m>0;m--)data[i][m]=data[i][m-1]; 

    data[i][0]=0;

    n++; 

   }else j--;

  }

  //合并操作

  for(j=3;j>0;j--)

   if(data[i][j]==data[i][j-1]&&data[i][j]!=0)

   {

    data[i][j]=data[i][j]*2;

    sum=sum+data[i][j];

    data[i][j-1]=0;   

   }

  //移动操作

  j=3;n=0;

  while(n<3&&j>0)

  {

   if(data[i][j]==0)

   {

    for(m=j;m>0;m--)data[i][m]=data[i][m-1]; 

    data[i][0]=0;

    n++; 

   }

   else j--;

  }

 }

}

 

int color(int num)//num为每一种颜色所代表的数字,范围是0~15

{

 //SetConsoleTextAttribute是设置控制台窗口字体颜色和背景色的函数

 //GetStdHandle是获得输入、输出或错误的屏幕缓冲区的句柄

 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),num);

 return 0;

}

 

int setcolor(int n)//给不同数字附不同颜色

{

 switch(n){

  case 2:color(7);break;//白色

  case 4:color(14);break;//淡黄色

  case 8:color(6);break;//黄色

  case 16:color(2);break;//绿色

  case 32:color(11);break;//淡浅绿色

  case 64:color(9);break;//淡蓝色

  case 128:color(1);break;//蓝色

  case 256:color(13);break;//淡紫色

  case 512:color(5);break;//紫色

  case 1024:color(8);break;//灰色

  case 2048:color(4);break;//红色

  default: break;

 }

 return 0;

}

 

int gameover()

{

 int i,j;

    for(i=0;i<4;i++)

 {

        for(j=0;j<4;j++)

  {

            if(data[i][j]==0)//任意一点为空,游戏继续

                return 0;

            if(i>0)

   {

                if(data[i-1][j]==data[i][j])//任意两个相邻的单元值相同,游戏继续

                    return 0;

            }

            if(j>0)

                if(data[i][j-1]==data[i][j])

                    return 0;

        }

    }

    return 1;

}

 

void start()

{

 int x;

 putnewnum();//生成一个2或4

 printmap();//显示

 //getch()用于瞬时读取按下的键,不等待回车和换行键的到来

 while((x=getch())!='q'){//按q退出游戏

  switch(x){

   case 0xE0://0xE0是方向键的开头,上(0xE0,72)、下(0xE0,80)、左(0xE0,75)、右(0xE0,77),按下方向键,getch()会读到2字节

    switch(x=getch()){

     case 72:moveup();break;

     case 80:movedown();break;

     case 75:moveleft();break;

     case 77:moveright();break;

     default: break;

    }

   if(comparedata()==0)//数据不同

   {

    putnewnum(); //放置新的数字

    copydata(); //备份数组的数据

       count++; //操作的次数+1   

   }

   system("cls");//清屏

   printmap();//显示

   default:break;

     }

    } 

}

 

int main()

{

 srand(time(NULL));//NULL代表空值,用系统当前时间设置rand()随机序列种子,保证每次运行随机序列不一样

 start();

 return 0;

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/969182.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号