C语言编写2048小游戏

article/2025/10/27 6:57:42

一、原理

这里以向上移动为例,其他方向的移动类似。
因为纵向移动不会横向变化,所以可以单独拿出某一列来分析。

我们先假设一个具有代表性的例子,假设当前某列数据是【2】【0】【2】【8】(0代表空白),如下图:

再来分析每个过程:
过程①->②,移动: 从下往上,通过平移的方式把中间的所有空白格(即data[x][y]=0)消除,这有点像“删除字符串中的空格题目”。
从这个特例中可以看出,只需【2】【8】同时要向上平移1次就能把中间的所有空白格消除得到②,

当然实际情况有多种类型,例如:

(a)需要把【8】向上平移2次
(b)需要把【16】平移3次(这也是最多移3次的情况)

很明显全空或全满的情况也不需要移动
【0】 【2】
【0】 【8】
【0】 【4】
【0】 【32】

过程②->③,合并: 在这一过程中我们要反过来,从上往下找相邻的两个单元格内是否有相同的数字,图中【2】【2】【8】【0】开头的两个数字相同,则把第二个【2】加到第一个【2】,并且把第二个【2】清空,得到③【4】【0】【8】【0】

过程③->④,再次移动: 经过过程②->③得到的【4】【0】【8】【0】中间产生了一个空白格,很明显不是我们想要的结果,这时我们再次用过程①->②的方法再次向上平移(<=3次),即可消除所有空白格,从而得到某列的最终结果④【4】【8】【0】【0】。

处理向上移动的完整代码如下,处理其他方向的同理

void moveUP()
{int i,j;int m=0,n=0;for(i=0;i<4;i++)//列{//移动操作j=0;n=0;		 //j为当前判定的所在行while(n<3 && j<3)//n为移动的次数{if(data[j][i]==0)   //若发现空白格{for(m=j;m<3;m++)//下方数据向上平移1格,覆盖空白格data[m][i]=data[m+1][i];	data[3][i]=0;	//最后一行置0n++;			//移动的次数+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;//上面的保存合并后的数字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++;}}
}

二、程序

添加头文件、定义个4*4的数组,及其他全局变量

#include<stdio.h>
#include<conio.h>
#include <stdlib.h> 
#include<time.h>int data[4][4];
int data_old[4][4];//数据的备份,用于比较data[][]是否变化
int opTimes=0;//记录操作的步数

数据的复制和比较(主函数中会用到)
copyData():将data[][] 中的数据备份到data_old[][]中
int compareData():比较data[][] 和data_old[][]中的数据是否相同

void copyData()
{int i,j;for(i=0;i<4;i++)for(j=0;j<4;j++)data_old[i][j]=data[i][j];}
int compareData()
{int i,j;for(i=0;i<4;i++)for(j=0;j<4;j++)if(data_old[i][j] != data[i][j])return 0; return 1; 
}

获取空白单元格是数量

int getEmptyNum()
{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;
}

在空白单元格的随机位置上放置数字2

void putNewNum()
{int i,j,c=0;c=1+rand()%getEmptyNum();//生成随机数,范围:[1,空白单元格数)for(i=0;i<4;i++)for(j=0;j<4;j++)if(data[i][j]==0){c--;if(c==0)data[i][j]=2;//把2放入某空白单元格内}	
}

获取当前分数(即二维数组中最大的数字)

int getMaxScore()
{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 printLine(int L)//打印某一行
{int i=0;for(i=0;i<4;i++){printf("│");if(data[L][i]==0)printf("\t");else printf("%d\t",data[L][i]);}printf("│\n");
}
void printMap()//打印整个二维数组和分数信息
{printf("┌-------┬-------┬-------┬-------┐\n");printLine(0);printf("├-------┼-------┼-------┼-------┤\n");printLine(1);printf("├-------┼-------┼-------┼-------┤\n");printLine(2);printf("├-------┼-------┼-------┼-------┤\n");printLine(3);printf("└-------┴-------┴-------┴-------┘\n");printf("分数:%d\n",getMaxScore());printf("操作次数:%d\n",opTimes);printf("剩余空间:%d\n",getEmptyNum());
}

处理“上”、“下”、“左”、“右”移动

void moveUP()
{int i,j;int m=0,n=0;for(i=0;i<4;i++)//列{//移动操作j=0;n=0;		 //j为当前判定的所在行while(n<3 && j<3)//n为移动的次数{if(data[j][i]==0)   //若发现空白格{for(m=j;m<3;m++)//下方数据向上平移1格,覆盖空白格data[m][i]=data[m+1][i];	data[3][i]=0;	//最后一行置0n++;			//移动的次数+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;//上面的保存合并后的数字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;int m=0,n=0;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)//相同(且不是0)则合并{data[j][i]=data[j][i]*2;//下面的保存合并后的数字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;int m=0,n=0;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;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;int m=0,n=0;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;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 isGameover()
{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 main()
{int ch;srand(time(NULL));//用系统当前时间设置rand()随机序列种子,保证每次运行随机序列不一样putNewNum();//先生成两个2putNewNum();copyData(); //备份数组printMap(); //显示while( (ch=getch())!=0x1B ){ /* 按ESC键退出的死循环 */switch(ch){case 0xE0:switch(ch=getch()){//识别按下键case 72:  moveUP(); break;case 80:  moveDOWN(); break;case 75:  moveLEFT(); break;case 77:  moveRIGHT(); break;default:break;}if(compareData()==0)//数据不一样说明格子中的数字能且被移动了{putNewNum();  //放置新的数字‘2’copyData();   //备份数组的数据opTimes++;	  //操作的次数+1}system("cls");  //清屏printMap();	 //显示	if(isGameover())printf("游戏结束,按Q键退出\n");//if(getMaxScore()>=2048){}//这里也可以判断分数>=2048,提示通关break;default:break;}	}
}

三、效果

在这里插入图片描述
若有什么问题欢迎或邮件:LiHooo@qq.com(不要再向我要完整源码了,博客中的代码就是完整源码。在桌面上新建文本,将扩展名改.c,复制上面的代码,粘贴到记事本,保存,用C编译器打开,编译运行就行了,我希望你认真看完程序,自己理解,不懂的地方再问一起交流,而不是伸手党或应付交作业)


http://chatgpt.dhexx.cn/article/PKfU95Z7.shtml

相关文章

Linux C语言编写2048小游戏

2048 2048小游戏是用Linux C语言写的&#xff0c;运行在Ubuntu系统上&#xff0c;其中Ubuntu链接Ncuses库。首先&#xff0c;我们简单了解一下Ncurses。 Ncurses库是由原CURSES库发展而来的&#xff0c;这个库提供了C/C对屏幕以及光标、鼠标访问的特性。使得C/C简易写屏成为可能…

C语言编写小游戏:MinesWeeper(扫雷)闯关版

《扫雷》&#xff1a;大众类的益智小游戏&#xff0c;游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子&#xff0c;同时避免踩雷&#xff0c;踩到一个雷即全盘皆输。 话不多说&#xff0c;我们直接进入正题。 首先&#xff0c;我们得给用户显示一个菜单栏&…

(C语言)用C语言编写小游戏——三子棋

目录 三子棋效果展示 三子棋的功能实现 1、初始化棋盘格 2、打印棋盘 3、玩家下棋 4、电脑下棋 5、判断输赢&#xff08;玩家赢/电脑赢/平局&#xff09; 完整代码展示 三子棋小游戏的代码实现分为三个文件&#xff0c;test.c&#xff08;测试游戏功能&#xff09;、ga…

c语言编写的小游戏(c语言编写小游戏入门)

C语言编写是要注意什么&#xff1f; 因此&#xff0c;在编写选择语句之前&#xff0c;应该首先明确判断条件是什么&#xff0c;并确定当判断结果为“真”或“假”时应分别执行什么样的操作(算法) c语言编写小游戏请提供俄罗斯方块&#xff0c;坦克大战之类的小游戏的程序的c 应…

(C语言)用C语言编写小游戏——扫雷

目录 扫雷效果展示 扫雷的功能实现 1、初始化棋盘格 2、 打印棋盘 3、布置雷 4、排查雷 完整代码展示 扫雷小游戏的代码实现分为三个文件&#xff0c;test.c&#xff08;测试游戏功能&#xff09;、game.h&#xff08;头文件的包含和函数的声明&#xff09;、game.c&…

详解5个C语言简单易懂小游戏

文章目录 前言一、准备工作二、游戏菜单三、游戏内容1.猜数字2.三子棋3.扫雷4.五子棋5.飞行棋 总结 前言 我们通过5个简单易懂的小游戏来加强我们对C语言的认识&#xff0c;这五个小游戏不仅有单人&#xff0c;还有人机对战和人人对战。让我们在学习之余来上一局紧张刺激的小游…

C语言趣味小游戏——扫雷(详解版)

前言 ​ 全篇无任何废话&#xff0c;本文的解释大多数都在代码段中&#xff0c;所以一定要看代码&#xff0c;边看边学边理解。 这只是初学者入门的一个小游戏&#xff0c;不难懂&#xff0c;没有什么复杂的内容 可以先学习一下比扫雷还简单的猜数字和三子棋 C语言趣味小游戏—…

C语言小程序游戏

c语言小程序游戏 ​ 本代码是我大一刚学完c语言自己编写的&#xff0c;三个游戏分别是飞机竞速、走迷宫和魔塔&#xff0c;满满的都是回忆。 1、不可能的任务-飞机竞速 ​ 这种游戏在以前小时候玩的游戏机里面玩过&#xff0c;那时抱着个游戏机一玩就是一下午&#xff0c;如…

C语言简易小游戏

文章目录 前言一、猜数字游戏二、旋转光标三、多个字符从两端移动&#xff0c;向中间汇聚四、恶搞&#xff1a;关机小程序五、闪烁的五彩爱心六、扫雷七、三子棋 前言 本篇博客将带领大家自己动手写一下一些C语言小游戏&#xff1b;以增加对于C语言的兴趣&#x1f600;&#x…

c语言成绩管理系统(链表)

C语言实现了学生成绩管理系统&#xff0c;可以进行学生成绩的增加&#xff0c;删除&#xff0c;修改&#xff0c;查询&#xff0c;计算平均成绩和展示。 开发语言&#xff1a;C语言 开发工具&#xff1a;Dev c 开发者&#xff1a;呵呵up 创建学生成绩信息 2. 插入学生信息 3.…

C语言实现学生成绩管理系统设计

本系统有增加学生记录、修改学生记录、删除学生记录、按姓名查询学生记录、按C语言成绩对学生进行排序、退出系统6大功能。 能够对学生的姓名&#xff0c;学号&#xff0c;c语言成绩做相应的操作。 在检测到输入成绩大于55时&#xff0c;会自动加上5。 该管理系统设计功能模块…

c语言成绩管理系统常见错误,求教 学生成绩管理系统出错

已结贴√ 问题点数:20 回复次数:5 求教 学生成绩管理系统出错 小弟刚做了个学生成绩管理系统 编译无错误 但是运行的时候连选择函数都不能 特来求教 望高手解释 代码如下: #include #include #define N 20 #define M 100 struct score {int scr1; int scr2; int scr…

c语言课程设计 学生成绩管理系统

学生成绩管理系统要求&#xff1a; 1、系统功能以菜单方式工作&#xff1b; 2、数据的输入&#xff1b; 3、数据的插入&#xff1b; 4、数据的输出&#xff1b; 5、数据的删除&#xff1b; 6、数据的查找&#xff0c;通常以两种方式进行查找&#xff0c;如姓名、学号&#xff1…

C语言学生成绩管理系统详解

文章目录 一、系统概述二、数据类型三、自定义函数说明四、运行界面五、源代码 源代码请直接跳到最后 引言&#xff1a;最近写了C语言的大作业&#xff0c;感觉做得还行&#xff0c;记录一下&#xff0c;给后人一些参考&#xff0c;给自己留更深印象方便后续改进&#xff01; …

学生成绩管理系统 C语言

基础篇问题&#xff1a; 1.输出如下菜单&#xff1a; *********************学生成绩管理系统******************* * 1 成绩录入 2 成绩查询 3 计算平均分 * * 4 计算最高分 5 排名 6 退出 * ******************************…

C语言编程学生成绩管理系统

目录 一、介绍 二、功能 1.录入学生 2.删除学生信息 3.修改学生信息 4.查询学生信息 5.所有学生信息 6.成绩排序 7.退出程序 三、代码 1.主函数 2.头文件 3.函数封装库 一、介绍 利用C语言&#xff0c;运用链表、指针、封装函数等基本知识实现一个学生管理系统。通…

C语言学生成绩管理系统

制作学生成绩管理系统&#xff0c;可以实现以下功能&#xff1a; 每条记录包括&#xff1a;学号、姓名、专业和5门课程的成绩&#xff1b;能够实现添加、删除、修改功能&#xff1b;能够计算某学生的总分和平均分&#xff1b;能按照总分排序输出&#xff1b; 利用C语言的基本…

c语言成绩管理系统

关注微信公众号每日新觉&#xff0c;私聊作者获取提取密码点击下面链接&#xff0c;私聊作者获取提取密码。https://mp.weixin.qq.com/s/QgRQ3YB2JqCvNOGQHQ57rA 作者每日新觉&#xff0c;是一名热爱技术和编程的年轻程序员。他在计算机科学和软件工程领域有着广泛的研究和实践…

c语言成绩管理系统1.0,c语言成绩管理系统完整附源码v1.0 免费版

c语言成绩管理系统拥有和hello word一样的江湖地位&#xff0c;初学C语言的朋友基本都会从管理系统开始入手学习&#xff0c;对于很多大学生来说更是如此&#xff0c;今天为大家带来的这款系统以及源码希望能对大家学习学C语言有所帮助&#xff0c;欢迎下载使用。 C语言介绍 C语…

C语言学生成绩管理系统(综合项目)

1. 这个代码主要实现以下功能&#xff1a; 2. 用到的主要参数有&#xff1a; 1.整型变量int n;用于储存学生人数和之后的循环判断。 2.字符串char name[][];用于储存姓名。 3.浮点型变量float score[];用于储存成绩。 4.长整型变量long ID[Max];用于储存学号。 3.…