void MENU ();//菜单 void START ();//开始界面 void TABLE ();//构建4*4棋盘 void KEEP ();//保存当前棋盘 void AGAIN ();//游戏结束后的界面 void GET ();//上下左右移动的函数 int CHECK ();//检查棋盘是否发生变动 int RANDOM1 ();//随机数1 int RANDOM2 ();//随机数2 int OVER ();//判断是否死棋
首先列出了所有需要的函数,下面我们开始介绍其中主要的函数。
(1)MNUE 它的作用就是输出一个菜单,并判断是否开始游戏。
void MENU ()//先用字符谁出一个菜单
{
printf("ttt╔═══════════════════════════╗n");
printf("ttt║ ║n");
printf("ttt║ 欢迎来到2048 ║n");
printf("ttt║ ║n");
printf("ttt║ ║n");
printf("ttt║ ┏━━┓ ┏━━┓ ║n");
printf("ttt║ 开始:┃ 1┃ 退出:┃ 2┃ ║n");
printf("ttt║ ┗━━┛ ┗━━┛ ║n");
printf("ttt║ ║n");
printf("ttt║ ║n");
printf("ttt╚═══════════════════════════╝n");
switch(getch()){ //判断是否开始游戏
case '1':
system("cls");
START();
break;
case '2':
exit(0);
break;
}
}
(2)TABLE 它的作用就是输出当前棋盘和棋盘中保存的数字。
void TABLE ()//输出棋盘和棋盘中的数。
{
for(h=0;h<4;h++)//四重循环输出棋盘的四行
{
if(h==0)printf("ttt┏━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓n");
else printf("ttt┣━━━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫n");
printf("ttt┃ ┃ ┃ ┃ ┃n");
for(l = 0 ; l < 4 ; l ++)//如果方格中是0,则方格中不放数字
{
if( a[h][l] == 0)
{
if(l==0)printf("ttt┃ ");//如果是棋盘第一列,前面加三个t
else printf("┃ ");
}
else //如果不是零,就把数字输出到方格中
{
if(l==0){
printf ("ttt┃");//如果是棋盘第一列,前面加三个t
printf("%5d ", a[h][l]);
}
else{
printf ("┃");
printf("%5d ", a[h][l]);
}
}
}
printf("┃n");//最后给棋盘封个口
printf("ttt┃ ┃ ┃ ┃ ┃n");
}
printf("ttt┗━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛n");//棋盘的四行都输出完了,把棋盘的底封上
}
(3)START 这个是开始游戏的函数,也是一个循环控制系统,跳出循环的条件就是游戏结束。
void START ()
{
int point=1; //配合CHECK检查棋盘是否变化,也就是操作完棋盘动没动
int bz =0, fs=0;//分别保存步数和得分
while(1)
{
while(1)
{
if(point==1)
{
h=RANDOM2();
l=RANDOM2();
if(a[h][l]==0){
a[h][l]=RANDOM1();//如果上一步操作完棋盘动了,找一个棋盘上没数的方格放入2或4
bz++; //步数加1
break;
}
}
else{
break; //如果上一步操作完棋盘没动,不放入新的数字
}
}
TABLE(); //放完新数重新打印棋盘
KEEP(); //保存当前棋盘用于比较操作完棋盘动没动
printf("ttt 步数:%d 得分:%d",bz,fs);
GET(&fs); //这是正经的操作函数,由wsad控制上下左右
point=CHECK(); //检查棋盘是否变化
if(OVER()==0){ //检查游戏是否结束,棋盘是否还可以操作
printf("nttt 游戏结束");
break;
}
system("cls"); //清屏,以便打印下一次操作完的棋盘
}
}
(4)GET 它的作用就是在键盘get字符,判断是上下左右,然后对棋盘进行操作,整体思想就是先把所有数字移动到棋盘的一侧,然后让相邻且相同的两个方格相加,最后再此移动到一侧。移动到一侧的想法很简单用三层循环即可实现,下面用向上移动举例,以便理解
for(l = 0 ; l < 4 ; l ++){ //向上移是每一列的数字相邻相同相加,所以外层循环是 l
for(t = 0 ; t < 4 ; t ++){//做四次移动,因为每次移动只能动一步
for(h = 3 ; h > 0 ; h --){//从最底下开始移动,只要上面的方格是0,就向上移动一个
if(a[h-1][l] == 0){
a[h-1][l] = a[h][l];
a[h][l] = 0;
}
}
}
}
for(l = 0 ; l < 4 ; l ++){
for(t = 0 ; t < 4 ; t ++){
for(h = 3 ; h > 0 ; h --){
if(a[h-1][l] == a[h][l]){
a[h-1][l] += a[h][l];//也是同样的循环,只不过这次是相邻相同相加
a[h][l] = 0;
*fs = *fs+ a[h][l];//记录得分
}
}
}
}
for(l = 0 ; l < 4 ; l++){ //同样的移动操作
for(t = 0 ; t < 4 ; t ++){
for(h = 3 ; h > 0 ; h --){
if(a[h-1][l] == 0){
a[h-1][l] = a[h][l];
a[h][l] = 0;
}
}
}
}
向其他方向移动的原理相同,就不过多介绍。
其他的函数都很简单,也都很好理解,下面直接上源代码吧
#include#include #include #include #include void MENU ();//菜单 void START ();//开始界面 void TABLE ();//构建4*4棋盘 void KEEP ();//保存当前棋盘 void AGAIN ();//游戏结束后的界面 void GET ();//上下左右移动的函数 int CHECK ();//检查棋盘是否发生变动 int RANDOM1 ();//随机数1 int RANDOM2 ();//随机数2 int OVER ();//判断是否死棋 int h,l,a[4][4]={0},A[4][4];//创建两个全局二位数组用来保存当前和上一步棋盘 int main () { system ("color F0");//F 表示背景颜色,0表示前景颜色 MENU (); system ("pause");//暂停,按任意键继续 AGAIN (); } void START () { int point=1; //配合CHECK检查棋盘是否变化,也就是操作完棋盘动没动 int bz =0, fs=0;//分别保存步数和得分 while(1) { while(1) { if(point==1) { h=RANDOM2(); l=RANDOM2(); if(a[h][l]==0){ a[h][l]=RANDOM1();//如果上一步操作完棋盘动了,找一个棋盘上没数的方格放入2或4 bz++; //步数加1 break; } } else{ break; //如果上一步操作完棋盘没动,不放入新的数字 } } TABLE(); //放完新数重新打印棋盘 KEEP(); //保存当前棋盘用于比较操作完棋盘动没动 printf("ttt 步数:%d 得分:%d",bz,fs); GET(&fs); //这是正经的操作函数,由wsad控制上下左右 point=CHECK(); //检查棋盘是否变化 if(OVER()==0){ //检查游戏是否结束,棋盘是否还可以操作 printf("nttt 游戏结束"); break; } system("cls"); //清屏,以便打印下一次操作完的棋盘 } } void MENU ()//先用字符谁出一个菜单 { printf("ttt╔═══════════════════════════╗n"); printf("ttt║ ║n"); printf("ttt║ 欢迎来到2048 ║n"); printf("ttt║ ║n"); printf("ttt║ ║n"); printf("ttt║ ┏━━┓ ┏━━┓ ║n"); printf("ttt║ 开始:┃ 1┃ 退出:┃ 2┃ ║n"); printf("ttt║ ┗━━┛ ┗━━┛ ║n"); printf("ttt║ ║n"); printf("ttt║ ║n"); printf("ttt╚═══════════════════════════╝n"); switch(getch()){ //判断是否开始游戏 case '1': system("cls"); START(); break; case '2': exit(0);//退出程序 break; } } void TABLE ()//输出棋盘和棋盘中的数。 { for(h=0;h<4;h++)//四重循环输出棋盘的四行 { if(h==0)printf("ttt┏━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓n"); else printf("ttt┣━━━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫n"); printf("ttt┃ ┃ ┃ ┃ ┃n"); for(l = 0 ; l < 4 ; l ++)//如果方格中是0,则方格中不放数字 { if( a[h][l] == 0) { if(l==0)printf("ttt┃ ");//如果是棋盘第一列,前面加三个t else printf("┃ "); } else //如果不是零,就把数字输出到方格中 { if(l==0){ printf ("ttt┃");//如果是棋盘第一列,前面加三个t printf("%5d ", a[h][l]); } else{ printf ("┃"); printf("%5d ", a[h][l]); } } } printf("┃n");//最后给棋盘封个口 printf("ttt┃ ┃ ┃ ┃ ┃n"); } printf("ttt┗━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛n");//棋盘的四行都输出完了,把棋盘的底封上 } void AGAIN () { system("cls"); printf("ttt╔═══════════════════════════╗n"); printf("ttt║ ║n"); printf("ttt║ 游戏结束啦 ║n"); printf("ttt║ ║n"); printf("ttt║ ║n"); printf("ttt║ ┏━━┓ ┏━━┓ ║n"); printf("ttt║ 重来:┃ 1┃ 退出:┃ 2┃ ║n"); printf("ttt║ ┗━━┛ ┗━━┛ ║n"); printf("ttt║ ║n"); printf("ttt║ ║n"); printf("ttt╚═══════════════════════════╝n"); switch(getch()){ case '1': system("cls");//清屏 START(); break; case '2': exit(0); break; } } void KEEP () { for(h = 0 ; h < 4;h++){ for(l=0 ; l<4;l++){ A[h][l]=a[h][l];//保存当前棋盘 } } } int CHECK () { for(h = 0 ; h < 4 ; h ++){ for(l = 0 ; l<4 ; l ++){ if(A[h][l]!=a[h][l])//检查棋盘是否发生变化 return 1; } } return 0; } int OVER () //判断是否游戏结束 { int h , l , t , over=0; for(h = 0 ; h < 4 ; h ++){ for(l = 0 ; l<4 ; l ++){ if(a[h][l]==0) return 1;//如果有0,则没结束 } } for(l = 0 ; l < 4 ; l ++){ for(t = 0 ; t < 4 ; t ++){ for(h = 3 ; h > 0 ; h --){ if(a[h-1][l] == a[h][l]){ return 1;//如果同一列有相邻数字相同,则没结束 } } } } for(h = 0; h < 4; h ++){ for(t = 0; t < 4; t ++){ for(l = 3; l > 0; l --){ if(a[h][l-1] == a[h][l]){ return 1;//如果同一行有相邻数字相同,则没结束 } } } } return 0; } int RANDOM1 () { int x; srand (time(NULL));//初始化随机数生成器 x=((unsigned)rand()%2);//生成随机数 x= x == 0 ? 2 : 4;//判断是奇是偶 return x; } int RANDOM2 () { int x; x=((unsigned)rand()%4); return x; } void GET (int*fs) { int h , l , t ; char ch; ch=getch(); switch(ch){ case 'w': case 'W': for(l = 0 ; l < 4 ; l ++){ //向上移是每一列的数字相邻相同相加,所以外层循环是 l for(t = 0 ; t < 4 ; t ++){//做四次移动,因为每次移动只能动一步 for(h = 3 ; h > 0 ; h --){ //从最底下开始移动,只要上面的方格是0,就向上移动一个 if(a[h-1][l] == 0){ a[h-1][l] = a[h][l]; a[h][l] = 0; } } } } for(l = 0 ; l < 4 ; l ++){ for(t = 0 ; t < 4 ; t ++){ for(h = 3 ; h > 0 ; h --){ if(a[h-1][l] == a[h][l]){ a[h-1][l] += a[h][l];//也是同样的循环,只不过这次是相邻相同相加 a[h][l] = 0; *fs = *fs+ a[h][l];//记录得分 } } } } for(l = 0 ; l < 4 ; l++){ //同样的移动操作 for(t = 0 ; t < 4 ; t ++){ for(h = 3 ; h > 0 ; h --){ if(a[h-1][l] == 0){ a[h-1][l] = a[h][l]; a[h][l] = 0; } } } } break; case 's': case 'S': for(l = 0; l < 4; l ++){ for(t = 0; t < 4; t ++){ for(h = 0; h < 3; h ++){ if(a[h+1][l] == 0){ a[h+1][l] = a[h][l]; a[h][l] = 0; } } } } for(l = 0; l < 4; l ++){ for(h = 3; h > 0; h --){ if(a[h][l] == a[h-1][l]){ a[h][l] += a[h-1][l]; a[h-1][l] = 0; *fs = *fs+ a[h][l]; } } } for(l = 0; l < 4; l ++){ for(t = 0; t < 4; t ++){ for(h = 0; h < 3; h ++){ if(a[h+1][l] == 0){ a[h+1][l] = a[h][l]; a[h][l] = 0; } } } } break; case 'a': case 'A': for(h = 0; h < 4; h ++){ for(t = 0; t < 4; t ++){ for(l = 3; l > 0; l --){ if(a[h][l-1] == 0){ a[h][l-1] = a[h][l]; a[h][l] = 0; } } } } for(h = 0; h < 4; h ++){ for(l = 0; l < 3; l ++){ if(a[h][l] == a[h][l+1]){ a[h][l] += a[h][l+1]; a[h][l+1] = 0; *fs = *fs+ a[h][l]; } } } for(h = 0; h < 4; h ++){ for(t = 0; t < 4; t ++){ for(l = 3; l > 0; l --){ if(a[h][l-1] == 0){ a[h][l-1] = a[h][l]; a[h][l] = 0; } } } } break; case 'd': case 'D': for(h = 0; h < 4; h ++){ for(t = 0; t < 4; t ++){ for(l = 0; l < 3; l ++){ if(a[h][l+1] == 0){ a[h][l+1] = a[h][l]; a[h][l] = 0; } } } } for(h = 0; h < 4; h ++){ for(l = 3; l > 0; l --){ if(a[h][l] == a[h][l-1]){ a[h][l] += a[h][l-1]; a[h][l-1] = 0; *fs = *fs+ a[h][l]; } } } for(h = 0; h < 4; h ++){ for(t = 0; t < 4; t ++){ for(l = 0; l < 3; l ++){ if(a[h][l+1] == 0){ a[h][l+1] = a[h][l]; a[h][l] = 0; } } } } break; default: break; } }
学费了吗,点个赞吧



