当前位置: 首页 > news >正文

c语言实现2048小游戏

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>int best = 0 ;// 定义2048游戏的结构体 
typedef struct { int martix[16];			// 当前4*4矩阵的数字 int martixPrior[16];	// 上一步的4*4矩阵的数字 int emptyIndex[16];		// 空位置的索引值 int emptyCount;			// 空位置的数量 int score;				// 当前的分数 int step;				// 记录操作步数 
}Game;int solve_best(int best){FILE *file;file = fopen("C:/Users/Redmi/Desktop/a.txt", "w"); // 以写入方式打开文件,如果文件不存在则创建if (file == NULL) {perror("Error opening file");return -1;}// 向文件中写入内容fprintf(file, "%d", best);fclose(file); // 关闭文件
}int get_best(){FILE *file;// 打开文件以读取原有数字file = fopen("C:/Users/Redmi/Desktop/a.txt", "r");if (file == NULL) {perror("Error opening file for reading");return -1;}int num = 0 ;// 读取原有数字int originalNumber;if (fscanf(file, "%d", &num) != 1) {perror("Error reading original number from file");fclose(file);return -1;}fclose(file); // 关闭文件return num ;
}// 生成[min, max]的随机整数
int RandomInt(int min, int max) {	srand((unsigned)time(NULL) + rand());	//以时间为随机种子return min + rand() % (max - min + 1);
}// 结构体的初始化 
void gameInit(Game *game) {int i;game->score = 0;game->step = 0;game->emptyCount = 16;for(i = 0; i < 16; i++) { game->martix[i] = 0;game->martixPrior[i] = 0;game->emptyIndex[i] = -1;}
}// 空位检测
void emptyDetect(Game *game) {int i = 0, j = 0;game->emptyCount = 0;for(i = 0; i < 16; i++) { game->emptyIndex[i] = -1; }for(i = 0; i < 16; i++) {if (game->martix[i] == 0) {game->emptyIndex[j++] = i;game->emptyCount++;}}
}// 在随机空位生成数字
void numberGenerate(Game *game) {int pos, numberIs4;numberIs4 = RandomInt(0, 3);	// 生成数字4的概率,这里为 1/4 pos = game->emptyIndex[RandomInt(0, game->emptyCount - 1)];if (numberIs4 == 0) { game->martix[pos] = 4; } else { game->martix[pos] = 2; }
} // 获取某行或某列
int *getLine(int *martix, int row, int col) {int i, *array;array = (int *)malloc(sizeof(int)*4);for (i = 0; i < 4; i++) {if (col != -1) { *(array+i) = *(martix + col+(i*4)); }if (row != -1) { *(array+i) = *(martix + row*4+i); }}return array;
} // 数字边缘对齐 
int *numberAlign(int *array, int reverse) {// reverse : 0: 向左对齐、向上对齐;  1: 向右对齐,向下对齐// 0 0 2 0 --> 2 0 0 0// 2 0 2 0 --> 2 2 0 0int i, j;int *newArray;newArray = (int *)malloc(sizeof(int)*4);for(j = 0; j < 4; j++) { *(newArray + j) = 0; }if (reverse == 0) {j = 0;for(i = 0; i < 4; i++) {if (*(array + i) != 0) { *(newArray + j) = *(array + i);j++;}}}if (reverse == 1) {j = 3;for(i = 3; i >= 0; i--) {if (*(array + i) != 0) {*(newArray + j) = *(array + i);j--;}}}return newArray;
}// 相邻数字相加
int *numberMerge(Game *game, int *array, int reverse) {int i, j, num1, num2;int *newArray;newArray = (int *)malloc(sizeof(int)*4);if (reverse == 0) {j = 0;for (i = 0; i < 4; i++) {num1 = *(array + i);num2 = 0;if (i != 3) { num2 = *(array + i + 1); } if (num1 == num2 && num1 > 0 && num2 > 0) {*(newArray + j) = num1 + num2;*(array + i + 1) = 0;game->score += (num1 + num2); } else {*(newArray + j) = *(array + i);}j++;}}if (reverse == 1) {j = 3;for (i = 3; i >= 0; i--) {num1 = *(array + i);num2 = 0;if (i != 0) { num2 = *(array + i - 1); }if (num1 == num2 && num1 > 0 && num2 > 0) {*(newArray + j) = num1 + num2;*(array + i - 1) = 0;game->score += (num1 + num2);} else {*(newArray + j) = *(array + i);}j--;}}return newArray;
}// 数字移动
void numberMoving(Game *game, int direction) {int *line[4];int i, j;switch(direction) {case 1:for (i = 0; i < 4; i++) {line[0] = getLine(game->martix, i, -1);line[1] = numberAlign(line[0], 0);line[2] = numberMerge(game, line[1], 0);line[3] = numberAlign(line[2], 0);for (j = 0; j < 4; j++) { game->martix[i*4+j] = *(line[3] + j);game->martixPrior[i*4+j] = *(line[0] + j);}}break;case 2:for(i = 0; i < 4; i++) {line[0] = getLine(game->martix, i, -1);line[1] = numberAlign(line[0], 1);line[2] = numberMerge(game, line[1], 1);line[3] = numberAlign(line[2], 1);for (j = 0; j < 4; j++) { game->martix[i*4+j] = *(line[3] + j);game->martixPrior[i*4+j] = *(line[0] + j);}}break;case 3:for(i = 0; i < 4; i++) {line[0] = getLine(game->martix, -1, i);line[1] = numberAlign(line[0], 0);line[2] = numberMerge(game, line[1], 0);line[3] = numberAlign(line[2], 0);for (j = 0; j < 4; j++) { game->martix[i+4*j] = *(line[3] + j);game->martixPrior[i+4*j] = *(line[0] + j);}}break;case 4:for(i = 0; i < 4; i++) {line[0] = getLine(game->martix, -1, i);line[1] = numberAlign(line[0], 1);line[2] = numberMerge(game, line[1], 1);line[3] = numberAlign(line[2], 1);for (j = 0; j < 4; j++) { game->martix[i+4*j] = *(line[3] + j); game->martixPrior[i+4*j] = *(line[0] + j);}}break;}for (j = 0; j < 4; j++) { free(line[j]); }}// 游戏结束判定
int gameOverDetect(Game *game) {// 当判定为输时返回 1 int i, j, row, col;if (game->emptyCount > 0) { return 0; }for (i = 0; i < 16; i++) {int numberBeside[4] = {0, 0, 0, 0};		// 相邻上下左右四个位置的数字row = i / 4;col = i % 4;if (row - 1 >= 0) { numberBeside[0] = game->martix[(row-1)*4+col]; }		// 获取上面的数字if (row + 1 < 4) { numberBeside[1] = game->martix[(row+1)*4+col]; }			// 获取下面的数字 if (col - 1 >= 0) { numberBeside[2] = game->martix[row*4+(col-1)]; }		// 获取左边的数字 if (col + 1 < 4) { numberBeside[3] = game->martix[row*4+(col+1)]; }			// 获取右边的数字 for(j = 0; j < 4; j++) {if (game->martix[i] == numberBeside[j]) { return 0; }}}return 1;
} // 键盘操作 
int keyboardPress() {// 返回值: 0: 无效操作; 1、2、3、4: 左右上下;int charAscii;charAscii = _getch();if (charAscii == 65 || charAscii == 97) { return 1; }		// A, 左if (charAscii == 68 || charAscii == 100) { return 2; }		// D, 右if (charAscii == 87 || charAscii == 119) { return 3; }		// W, 上if (charAscii == 83 || charAscii == 115) { return 4; }		// S, 下 return 0;
}// 检查数字是否移动过
int checkNumberMove(Game *game) {// 返回值: 0: 数字没有移动过; 1: 数字移动过 int i;for(i = 0; i < 16; i++) {if (game->martix[i] != game->martixPrior[i]) { return 1; } }return 0;
}// 游戏开始时随机生成2个数字 
void gameStart(Game *game) {int i;gameInit(game);emptyDetect(game);numberGenerate(game);emptyDetect(game);numberGenerate(game);emptyDetect(game);
}// 绘制画面
void drawGame(Game *game) {int row;system("cls");printf("\n      GAME : 2 0 4 8 BEST : %d    \n",best);printf("\n按键说明:  W:上  A:左  S:下  D:右\n\n");for(row = 0; row < 4; row++) {if (row == 0) { printf("---------------------------------\n"); }printf("|\t|\t|\t|\t|\n");if (game->martix[row*4] != 0) { printf("|%7d", game->martix[row*4]); } else { printf("|\t"); }if (game->martix[row*4+1] != 0) { printf("|%7d", game->martix[row*4+1]); } else { printf("|\t"); }if (game->martix[row*4+2] != 0) { printf("|%7d", game->martix[row*4+2]); } else { printf("|\t"); }if (game->martix[row*4+3] != 0) { printf("|%7d|\n", game->martix[row*4+3]); } else { printf("|\t|\n"); }printf("|\t|\t|\t|\t|\n");printf("---------------------------------\n");}printf("步数: %d\n分数: %d\n\n", game->step, game->score);
} // 主程序 
int main() {Game *gamePtr;int key;best = get_best() ;gamePtr = (Game *)malloc(sizeof(Game));gameInit(gamePtr);gameStart(gamePtr);drawGame(gamePtr);while(gameOverDetect(gamePtr) != 1) {key = keyboardPress();// 移动数字后生成数字 if (key != 0) {numberMoving(gamePtr, key);if (checkNumberMove(gamePtr) != 0) {emptyDetect(gamePtr);numberGenerate(gamePtr);emptyDetect(gamePtr);gamePtr->step += 1;drawGame(gamePtr); }}}printf("%d\n",gamePtr->score);if(gamePtr->score > best){solve_best(best) ;}printf("\n游 戏 结 束 !\n"); return 0;
}

效果 : 

相关文章:

c语言实现2048小游戏

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h>int best 0 ;// 定义2048游戏的结构体 typedef struct { int martix[16]; // 当前4*4矩阵的数字 int martixPrior[16]; // 上一步的4*4矩阵的数字 int emptyIndex[16…...

159 Linux C++ 通讯架构实战14,epoll 函数代码实战

ngx_epoll_init函数的调用 //&#xff08;3.2&#xff09;ngx_epoll_init函数的调用&#xff08;要在子进程中执行&#xff09; //四章&#xff0c;四节 project1.cpp&#xff1a;nginx中创建worker子进程&#xff1b; //nginx中创建worker子进程 //官方nginx ,一个…...

【鹅厂摸鱼日记(一)】(工作篇)认识八大技术架构

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:重生之我在鹅厂摸鱼⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多知识   &#x1f51d;&#x1f51d; 认识八大架构 1. 前言2. 架构简介&…...

CA根证书——https安全保障的基石

HTTPS通信中&#xff0c;服务器端使用数字证书来证明自己的身份。客户端需要验证服务器发送的证书的真实性。这就需要一个可信的第三方机构&#xff0c;即CA&#xff0c;来颁发和管理证书。CA根证书是证书颁发机构层次结构的顶级证书&#xff0c;客户端信任的所有证书都可以追溯…...

Spark-Scala语言实战(10)

在之前的文章中&#xff0c;我们学习了如何在spark中使用RDD的filter,distinct,intersection三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-…...

【C++庖丁解牛】高阶数据结构---红黑树详解(万字超详细全面介绍红黑树)

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.红黑树的概念2.红黑…...

汽车网络安全管理

汽车网络安全管理 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c…...

文本自动粘贴编辑器:支持自动粘贴并筛选手机号码,让信息处理更轻松

在信息时代的浪潮中&#xff0c;文本处理已成为我们日常工作与生活的重要组成部分。无论是商务沟通、社交互动还是个人事务处理&#xff0c;手机号码的筛选与粘贴都显得尤为关键。然而&#xff0c;传统的文本处理方式效率低下、易出错&#xff0c;已无法满足现代人的高效需求。…...

Linux云计算之网络基础9——园区网络架构项目

要求构建大型园区网络架构&#xff0c;方案如下&#xff1a; 园区A 园区c 公司B 要求&#xff1a; 1、A公司园区网络 一台汇聚层三层交换机&#xff0c;两台接入层二层交换机。 出口有一台路由器。 2、A园区有五台服务器。 分别为两台 WEB 服务器&#xff0c;…...

Java 中的 List 集合

文章目录 添加元素获取元素检查元素删除元素修改元素获取列表大小检查列表是否为空清空列表查找元素索引获取列表的子列表 List 是 Java 集合框架中的一个接口&#xff0c;它表示一个有序的集合&#xff08;序列&#xff09;&#xff0c;允许存储重复的元素。List 接口提供了许…...

数据库之DDL操作(数据库,表,字段)

Data Definition Language&#xff0c;数据库定义语言&#xff0c;用来定义数据库对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09; 1.数据库操作 1.1查询所有数据库 show databases; 1.2查询当前数据库 show databases(); 1.3创建数据库 create da…...

5.3.1 配置交换机 SSH 管理和端口安全

5.3.1 实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握&#xff1a; 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 交换机基本安全和 SSH管理实验拓扑 3、实验步骤 &a…...

Django--数据库连接

数据库配置 打开mysite/settings.py配置文件&#xff0c;这是整个Django项目的设置中心。Django默认使用SQLite3数据库&#xff0c;因为Python原生支持SQLite3数据库&#xff0c;所以你无须安装任何程序&#xff0c;就可以直接使用它。 下面是默认的数据库配置&#xff1a; …...

CKA 基础操作教程(二)

Kubernetes Deployment 理论学习 Kubernetes Deployment &#xff08;部署&#xff09;是一种 Kubernetes 资源对象&#xff0c;用于定义和管理容器化应用程序的部署和更新。Deployment 提供了一种声明性的方式来定义应用程序的期望状态&#xff0c;并负责确保所需数量的 Pod…...

【SQLServer】快速查看SQL Server中所有数据库中所有表的行数

1.查看某个数据库中每个表的行数 SELECT @@servername as servername, db_name() as databasename, s.name AS schemaname, t.name AS tablename,p.rows AS rowcounts,SUM(a...

Node.js------Express

◆ 能够使用 express.static( ) 快速托管静态资源◆ 能够使用 express 路由精简项目结构◆ 能够使用常见的 express 中间件◆ 能够使用 express 创建API接口◆ 能够在 express 中启用cors跨域资源共享 一.初识Express 1.Express 简介 官方给出的概念&#xff1a;Express 是基…...

CSS - 你实现过0.5px的线吗

难度级别:中级及以上 提问概率:75% 我们知道在网页显示或是网页打印中,像素已经是最小单位了,但在很多时候,即便是最小的1像素,精度却不足以呈现所需的线条精度和细节。因此,为了在网页显示和网页打印中呈现更加细致的线条,为了在视觉…...

hbuilderX创建的uniapp项目转移到vscode

场景&#xff1a;一直使用hbuilderX开发的朋友想转移到vscode获取更好的TypeScript支持&#xff0c;所以想把整个项目目录拖到vscode进行开发&#xff0c;但发现运行不了&#xff0c;提示没有package.json等&#xff0c;并且不能执行pnpm命令 首先&#xff0c;我们先来看一下h…...

JavaScript 事件流

JavaScript与HTML之间的交互是通过事件实现的&#xff0c;而用户与浏览器页面的互动也是通过事件来实现的事件就是文档或浏览器窗口中发生的一些特定的交互瞬间&#xff0c;所以分为两种事件&#xff0c;一是发生在 浏览器对象&#xff08;BOM&#xff09;上的事件&#xff0c;…...

HTML——5.表单、框架、颜色

一、表单 HTML 表单用于在网页中收集用户输入的数据&#xff0c;例如登录信息、搜索查询等。HTML 提供了一系列的表单元素&#xff0c;允许用户输入文本、选择选项、提交数据等。 <!DOCTYPE html> <html lang"en"> <head> <meta charset&q…...

如何免费获取Book118文档?这个Java工具让你轻松下载完整PDF

如何免费获取Book118文档&#xff1f;这个Java工具让你轻松下载完整PDF 【免费下载链接】book118-downloader 基于java的book118文档下载器 项目地址: https://gitcode.com/gh_mirrors/bo/book118-downloader 你是否曾经在Book118网站上找到了一份急需的学习资料&#x…...

GD32F407时钟树详解:168MHz系统时钟如何驱动你的ADC、SPI和CAN?

GD32F407时钟树深度解析&#xff1a;从PLL到外设的168MHz信号之旅 在嵌入式系统设计中&#xff0c;时钟如同芯片的"心跳"&#xff0c;精确控制着每个外设的运作节奏。GD32F407这颗基于Cortex-M4内核的MCU&#xff0c;其168MHz的系统时钟如何精准分配到ADC、SPI、CAN等…...

HDLbits实战解析:从异步复位到同步复位,掌握三段式FSM的核心差异与设计要点

1. 异步复位与同步复位的本质区别 在数字电路设计中&#xff0c;复位信号就像电脑的重启按钮&#xff0c;它能将电路恢复到初始状态。但很多初学者第一次在HDLbits上做FSM练习题时&#xff0c;会被"asynchronous reset"和"synchronous reset"这两个概念搞…...

别让直觉带路:Infoseek视角下的噪音过滤与火情预警实战

在舆情的世界里&#xff0c;最可怕的不是对手太强大&#xff0c;而是自己吓自己。很多时候&#xff0c;企业之所以“翻车”&#xff0c;并非因为危机本身不可控&#xff0c;而是因为公关团队在面对网友吐槽时过度敏感&#xff0c;发布了不必要的声明或做出了过激反应&#xff0…...

AI应用开发面试题总结(非八股文)

前端请求超过 3 秒&#xff0c;怎么分析原因&#xff1f; 1.看前端和网络 F12开发者模式去查看network&#xff0c;首先判断是前端问题还是后端问题 通过查看接口 Waiting 时间进行判断是后端响应时间太长还是说前端渲染问题 2.给后端接口添加日志进一步定位后端问题 3.如果…...

Godot 4.x ECS插件GECS:数据驱动架构提升游戏性能与可维护性

1. 项目概述&#xff1a;GECS&#xff0c;为Godot 4.x注入ECS架构之力如果你正在用Godot开发游戏&#xff0c;尤其是那种实体数量多、交互逻辑复杂的项目&#xff0c;比如RTS、模拟经营或者一个满屏敌人的弹幕游戏&#xff0c;你很可能已经感受到了传统面向对象&#xff08;OOP…...

卷积运算:数字信号处理的核心原理与实践

1. 卷积在数字信号处理中的核心地位第一次接触卷积这个概念时&#xff0c;我正坐在实验室里调试一个音频滤波器。示波器上的波形始终无法达到预期效果&#xff0c;直到导师走过来画了那个著名的"翻转滑动"示意图。那一刻我突然明白&#xff0c;卷积不是抽象的数学运算…...

基于大语言模型的自动化股票研报生成系统设计与实现

1. 项目概述&#xff1a;当ChatGPT遇上股票研报最近几年&#xff0c;AI在金融领域的应用已经从简单的数据查询&#xff0c;进化到了能够进行复杂分析和生成专业报告的程度。我关注到一个挺有意思的项目&#xff0c;叫ddobokki/chatgpt_stock_report。光看这个名字&#xff0c;你…...

终极Windows右键菜单管理神器:ContextMenuManager让你的桌面效率提升300%

终极Windows右键菜单管理神器&#xff1a;ContextMenuManager让你的桌面效率提升300% 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾经在Windows右键菜…...

RE正则提取数字

RE正则提取数字import resddfff1234567890aasdfff s1s[::-1] print(fs:{s};s1:{s1}) option_str re.sub("\D", "", s) print(option_str )...