C语言写的2048小游戏

基于"基于C_语言的2048算法设计_颜冠鹏.pdf"
这一篇文献提供的思路
在中国知网上能找到 就不贴具体内容了
[摘 要] 针对2048的游戏规则,分析了该游戏的算法特点,对其相关的功能需求和算法设计进行了简单介绍,提出了一种 新的设计方案。解决了该设计在方阵数据结构、运动算法和游戏结束判断方面的问题,并阐述了以队列方式进行坐标运算和操 作扩展的关键技术。软件测试表明,该设计的方块数值最大值受方阵阶数和操作次数的限制,四阶方阵的理论最大值为 65 536, 智力极高的人可达 16 384,而一般人仅能达到 2 048 左右。
[关键词] 2048 算法设计 数据结构 坐标运算 队列
中图分类号:TP301.6 文献标识码:A 文章编号:1008- 1739(2014)24- 62- 5

主要是几个小的函数
用两个for循环打印地图和遍历地图
把一个4*4的二维数组改成一个一维数组来简化处理思路

学到的知识

switch函数每一个case都需要加break来结束判断
for在c99标准下 初始化的循环变量和外界所有变量毫无关系
c99标准才有了布尔型变量
尽量不要大循环套小循环 嵌套四层循环之后就晕了 下断点都不好调试
如果数组越界访问会返回0
随机数函数必须撒种子 不然每次都是同一个值

// // main.c // 2048 // 表示 为了练习C语言 在这先写着一个小游戏吧 // “听说以后上课要用?” // 调试代码已注释 目前游戏所有功能均实现 // 唯一不足的是在苹果系统环境无getch函数 // 且不会自行实现 在其他系统直接include <conio.h> // 把getchar改为getch即可畅玩2048 // Created by licsber on 2018/10/11. // Copyright © 2018 licsber. All rights reserved. // #include <stdio.h>//emmmm #include <stdbool.h> //c里没有布尔型变量 c99标准才加的 #include <time.h>//用于产生随机数 #include <stdlib.h> //#include <ncurses.h>//图形界面库 等后来更新printMap函数再引用 void gameStart(void);//游戏开始 void randomAdd(void);//在空格随机加2和4 其中2为十分之九概率 void printMap(void);//用printf打印地图 void getDirection(void);//读取键盘输入 void moveUp(void);//上 void moveDown(void);//下 void moveLeft(void);//左 void moveRight(void);//右 void moveForward(void);//推进 void moveMerge(void);//合并 bool checkIfGameOver(void);//检测游戏是否over 即无空位同时相邻数组元素各不相等 void restart(void);//重新开始 void loop(void);//循环游戏 //int countZero(void);//还有几个是0 //int returnZero(int line); int score = 0;//当前得分 int map[4][4]={ {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} };//这是地图 用二维数组实现 int tmp[4] = {0,0,0,0}; void gameStart(void){ printf("Welcome to play 2048 game! by licsber\n"); randomAdd(); printMap(); printf("[w][s][a][d]move [r]restart [q]quit\n"); } void randomAdd(void){ srand((unsigned int)time(NULL));//撒随机数种子 //printf("%d",rand()); int i,j,time = 0;//行 列 循环次数(debug用) do{ i = rand() % 4; j = rand() % 4; time++; }while (map[i][j] != 0); if (rand() % 10 == 0 ) { map[i][j]=4; } else{ map[i][j]=2; } //printf("%d",time); //上面的代码在格子快满之后也有几率循环N次都不停 //todo改进方案:先找到所有空格子 //下面的代码是有问题的 有几率无限循环 /* bool finish = 0;//本轮是否已放置方块 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (!map[i][j]) { if (rand() % 16 == 0 && finish == 0) { // 十分之一的概率放4 if (rand() % 10 == 0 ) { map[i][j]=4; } else{ map[i][j]=2; } finish = 1; } } } } if (finish == 0) { randomAdd(); } else{ return; } */ } void printMap(void){ for (int i = 0; i < 4; i++) { printf(" "); for (int j = 0; j < 4; j++) { printf("%4d ",map[i][j]); } printf("\n"); } return; } void getDirection(void){ tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; char in = getchar(); switch (in) { case 'w': moveUp(); break; case 's': moveDown(); break; case 'a': moveLeft(); break; case 'd': moveRight(); break; case 'r': restart(); break; case 'q': exit(0); break; default: getDirection(); break; } } void moveUp(void){ for (int line = 0; line < 4; line++) { for (int i = 0; i < 4; i++) { tmp[i] = map[i][line]; } moveMerge(); for (int i = 0; i < 4; i++) { map[i][line] = tmp[i]; } } } void moveDown(void){ for (int line = 0; line < 4; line++) { for (int i = 0; i < 4; i++) { tmp[3 - i] = map[i][line]; } moveMerge(); for (int i = 0; i < 4; i++) { map[i][line] = tmp[3 - i]; } } } void moveLeft(void){ for (int line = 0; line < 4; line++) { for (int i = 0; i < 4; i++) { tmp[i] = map[line][i]; } moveMerge(); for (int i = 0; i < 4; i++) { map[line][i] = tmp[i]; } } } void moveRight(void){ for (int line = 0; line < 4; line++) { for (int i = 3; i >= 0; i--) { tmp[3 - i] = map[line][i]; } moveMerge(); for (int i = 3; i >= 0; i--) { map[line][i] = tmp[3 - i]; } } } bool checkIfGameOver(void){ //先检查格子是不是都满了 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (!map[i][j]) { //只要有空的格子 游戏就没结束 return false; } } } //格子满了之后 for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { if (map[i][j] == map[i+1][j] || map[i][j] == map[i][j+1]) { //如果一个格子和它右边或下边相等 游戏也没结束 //这里数组如果越界访问会返回0 所以不影响结果 return false; } } } return true; } void moveForward(void){ //i为0的话就把最先一个非零的j挪到i的位置 int j = 0; for (int i = 0; i < 4; i++) { j++; if (tmp[i] == 0) { for (; j < 4; j++) { if (tmp[j] != 0) { tmp[i] = tmp[j]; tmp[j] = 0; break; } } } } } void moveMerge(void){ //处理合并 每合并一次就推进一次 moveForward(); for (int i = 0; i < 3; i++) { if (tmp[i] == tmp[i + 1]) { tmp[i] *=2; tmp[i + 1] = 0; moveForward(); } } } /* int countZero(void){ int zero = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (!map[i][j]) { zero++; } } } return zero; } */ void restart(void){ for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { map[i][j] = 0; } } gameStart(); loop(); } void loop(void){ for(;;) { getDirection(); printMap(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (!map[i][j]) { //只要有空的格子 就加 randomAdd(); goto go; } } } go: if (checkIfGameOver() == true){ printf("You are lose!"); exit(0); } } } int main() { gameStart(); loop(); return 0; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxzdw.html