这个2048很简单,用的都是一些简单的语法和算法,很容易理解学会,下面我们开始吧
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("\t\t\t╔═══════════════════════════╗\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ 欢迎来到2048 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ┏━━┓ ┏━━┓ ║\n");
printf("\t\t\t║ 开始:┃ 1┃ 退出:┃ 2┃ ║\n");
printf("\t\t\t║ ┗━━┛ ┗━━┛ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t╚═══════════════════════════╝\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("\t\t\t┏━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓\n");
else printf("\t\t\t┣━━━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫\n");
printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");
for(l = 0 ; l < 4 ; l ++)//如果方格中是0,则方格中不放数字
{
if( a[h][l] == 0)
{
if(l==0)printf("\t\t\t┃ ");//如果是棋盘第一列,前面加三个\t
else printf("┃ ");
}
else //如果不是零,就把数字输出到方格中
{
if(l==0){
printf ("\t\t\t┃");//如果是棋盘第一列,前面加三个\t
printf("%5d ", a[h][l]);
}
else{
printf ("┃");
printf("%5d ", a[h][l]);
}
}
}
printf("┃\n");//最后给棋盘封个口
printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");
}
printf("\t\t\t┗━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛\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("\t\t\t 步数:%d 得分:%d",bz,fs);
GET(&fs); //这是正经的操作函数,由wsad控制上下左右
point=CHECK(); //检查棋盘是否变化
if(OVER()==0){ //检查游戏是否结束,棋盘是否还可以操作
printf("\n\t\t\t 游戏结束");
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<stdio.h>
#include<stdlib.h>
#include <conio.h> /*使用getch()函数*/
#include <time.h>
#include <windows.h>
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("\t\t\t 步数:%d 得分:%d",bz,fs);
GET(&fs); //这是正经的操作函数,由wsad控制上下左右
point=CHECK(); //检查棋盘是否变化
if(OVER()==0){ //检查游戏是否结束,棋盘是否还可以操作
printf("\n\t\t\t 游戏结束");
break;
}
system("cls"); //清屏,以便打印下一次操作完的棋盘
}
}
void MENU ()//先用字符谁出一个菜单
{
printf("\t\t\t╔═══════════════════════════╗\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ 欢迎来到2048 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ┏━━┓ ┏━━┓ ║\n");
printf("\t\t\t║ 开始:┃ 1┃ 退出:┃ 2┃ ║\n");
printf("\t\t\t║ ┗━━┛ ┗━━┛ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t╚═══════════════════════════╝\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("\t\t\t┏━━━━━━┳━━━━━━┳━━━━━━┳━━━━━━┓\n");
else printf("\t\t\t┣━━━━━━╋━━━━━━╋━━━━━━╋━━━━━━┫\n");
printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");
for(l = 0 ; l < 4 ; l ++)//如果方格中是0,则方格中不放数字
{
if( a[h][l] == 0)
{
if(l==0)printf("\t\t\t┃ ");//如果是棋盘第一列,前面加三个\t
else printf("┃ ");
}
else //如果不是零,就把数字输出到方格中
{
if(l==0){
printf ("\t\t\t┃");//如果是棋盘第一列,前面加三个\t
printf("%5d ", a[h][l]);
}
else{
printf ("┃");
printf("%5d ", a[h][l]);
}
}
}
printf("┃\n");//最后给棋盘封个口
printf("\t\t\t┃ ┃ ┃ ┃ ┃\n");
}
printf("\t\t\t┗━━━━━━┻━━━━━━┻━━━━━━┻━━━━━━┛\n");//棋盘的四行都输出完了,把棋盘的底封上
}
void AGAIN ()
{
system("cls");
printf("\t\t\t╔═══════════════════════════╗\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ 游戏结束啦 ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ┏━━┓ ┏━━┓ ║\n");
printf("\t\t\t║ 重来:┃ 1┃ 退出:┃ 2┃ ║\n");
printf("\t\t\t║ ┗━━┛ ┗━━┛ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t║ ║\n");
printf("\t\t\t╚═══════════════════════════╝\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;
}
}
学费了吗,点个赞吧