纯C语言2048,超详细

您所在的位置:网站首页 2048c语言简易源代码 纯C语言2048,超详细

纯C语言2048,超详细

2024-07-14 17:28| 来源: 网络整理| 查看: 265

前言:

突然想写2048,就模仿人家写的2048,写了2048,但有所改良😁(改良了一点小毛病,但绝大部分都一样)

一、编译器

我用的时vs2022的版本,其他版本没试过,但我估计devc++是可以的

二、2048的代码 头文件、全局变量

代码如下:

#include #include #include #include //提供getch()函数 //全局变量 int map[4][4] = { 0 }; //游戏地图 int score = 0; //分数 int movenum = -1; //移动次数 char input; //控制方向 int gameover = 1; //判断游戏是否结束,0结束 int change = 1; //判断数组是否改变,0不变 main函数

代码如下:

int main() { text(); //转折一下😎     //输了以后会打印以下内容 printf(" Game Over\n"); printf(" 你的得分为:%d\n", score); printf(" 你的移动次数为:%d\n", movenum); return 0; } text()函数

代码如下:

void text() { srand((unsigned int)time(NULL)); //设置随机数种子,(unsigned int) int看你们自己设置的类型 while (gameover == 1) //当gameover=1时就继续,等于0时就结束了 { RandInitNum(); //在数组里随机寻找map[i][j]=0并赋值2或4 menu(); //菜单以及棋盘 move(); //移动 over(); //判断是否结束 } } 在数组里随机寻找map[i][j]=0并赋值2或4

代码如下:

void RandInitNum() { int i, j, n; if (change == 1) //一开始设置为1,进行第一次判断 {         //对i和j进行随机数分配 do { i = ((unsigned int)rand()) % 4; j = ((unsigned int)rand()) % 4; } while (map[i][j] != 0); n = ((unsigned int)rand()) % 2; //n随机生成0或1,以便产生2或4,就是说当n=0时+2就为2,当n=1时+3就为4 if (n == 0) { map[i][j] = n + 2; } if (n == 1) { map[i][j] = n + 3; } movenum++; //对地图赋值之后说明肯定对数组移动了,所以这里的步数加一。 } } 菜单以及棋盘

代码如下:

{     //这里看起来没有对齐,但是vs经过编译后就是对齐的 system("CLS"); //每显示一次清屏之前的重新打印 printf("*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*\n"); printf("** W—上 * S—下 * A—左 * D—右 **\n"); printf("** 退出游戏请按0,再次确定请按y **\n"); printf("** 移动次数:%d 分数:%d **\n", movenum, score); printf("*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*—*\n"); //打印棋盘 printf("*———————————————*\n"); for (int i = 0; i < 4; i++) { printf("|"); for (int j = 0; j < 4; j++) { if(map[i][j]==0) //mao[i][j]=0时不打印 { printf(" |"); } else //map[i][j] != 0时打印map[i][j] { printf("%3d|", map[i][j]); } } printf("\n"); printf("*———————————————*\n"); } } 进行上下左右的移动 #move()函数

代码如下:

void move() { input = _getch(); //从键盘读取 change = 0; switch (input) { case'0': //退出游戏 { printf("你是否想要退出?(y/n):"); input = _getch(); if (input == 'y' || input == 'Y') { printf("退出成功\n"); exit(-1); } break; } case'w': case'W': { up(); break; } case's': case'S': { down(); break; } case'a': case'A': { left(); break; } case'd': case'D': { right(); break; } default: { printf("输入错误,请重新输入\n"); break; } } } 向上

代码如下:

int up() { int now = 0, next = 0; //now为所选的元素,next为now的下一个元素 int k = 0; //第一个for语句是把当前控制方向的数组里相同的数合并,其他方向的都是一样 初步对每一列的数进行合并 for (int j = 0; j < 4;j++) {   (列)                                  for (int i = 0; i < 4; i++) { (行) now = map[i][j]; if (now != 0) { //如果now不为0就判断now下面的元素是否有和now相等的元素,相等就加起来 k = i + 1; //从now的下一个元素开始 while (k < 4) { next = map[k][j]; if (next != 0) { //下一个元素不等于0才可以进行比较 if (now == next) { change = 1; score += map[k][j]; //计分 map[i][j] = 2 * map[k][j]; //相加后now就为之前的两倍 map[k][j] = 0; //相加后next就要变为0 } k = 4; 直接退出while循环,使用break也可以 } k++; //如果下一个元素为0或者与now不相等就在下一个 } } }         //第二个for循环是对每一列的相等元素的最终合并,与第一个for循环一摸一样 for (int i = 0; i < 4; i++) { //行 now = map[i][j]; if (now != 0) { k = i + 1; while (k < 4) { next = map[k][j]; if (next != 0) { if (now == next) { change = 1; score += map[k][j]; map[i][j] = 2 * map[k][j]; map[k][j] = 0; } k = 4; } k++; } } } }     //第三个for语句是把当前控制方向的非零元素移动当前方向的前面 for (int j = 0; j < 4;j++) { (列) for (int i = 0; i < 4; i++) { (行) now = map[i][j]; if (now == 0) { //如果now为0,next不为0,就将next移动到now的位置 k = i + 1; //从now的下一个元素开始 while (k < 4) { next = map[k][j]; if (next != 0) { change = 1; map[i][j] = next; //now就为next map[k][j] = 0; //next就应该为0 k = 4; //应该now已经被next的值占据,不可以在被其他值占据,所以退出while循环 } k++; //如果下一个元素为0就在下一个 } } } } return change; 返回change,change是否等于1影响要不要在进行生成随机数 }

为什么需要两层for循环:

向下

代码如下:

与向上大同小异,就是向下需要从最后一行开始,向上遍历

int down() { int now = 0, next = 0; int k = 0; for (int j = 0; j < 4; j++) { for (int i = 3; i >= 0; i--) { now = map[i][j]; if (now != 0) { k = i - 1; while (k >= 0) { next = map[k][j]; if (next != 0) { if (next == now) { change = 1; score += map[k][j]; map[i][j] = map[k][j] * 2; map[k][j] = 0; } k = -1; } k--; } } } for (int i = 3; i >= 0; i--) { now = map[i][j]; if (now != 0) { k = i - 1; while (k >= 0) { next = map[k][j]; if (next != 0) { if (next == now) { change = 1; score += map[k][j]; map[i][j] = map[k][j] * 2; map[k][j] = 0; } k = -1; } k--; } } } } for (int j = 0; j < 4; j++) { for (int i = 3; i >= 0; i--) { now = map[i][j]; if (now == 0) { k = i - 1; while (k >= 0) { next = map[k][j]; if (next != 0) { change = 1; map[i][j] = map[k][j]; map[k][j] = 0; k = -1; } k--; } } } } return change; } 向左

代码如下:

都差不多,第一层循环改为从行开始,第二层循环从列开始,因为是向左移动,是从第一列开始

int left() { int now = 0, next = 0; int k = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { now = map[i][j]; if (now != 0) { k = j + 1; while (k < 4) { next = map[i][k]; if (next != 0) { if (now == next) { change = 1; score += map[i][k]; map[i][j] = map[i][k] * 2; map[i][k] = 0; } k = 4; } k++; } } } for (int j = 0; j < 4; j++) { now = map[i][j]; if (now != 0) { k = j + 1; while (k < 4) { next = map[i][k]; if (next != 0) { if (now == next) { change = 1; score += map[i][k]; map[i][j] = map[i][k] * 2; map[i][k] = 0; } k = 4; } k++; } } } } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { now = map[i][j]; if (now == 0) { k = j + 1; while (k < 4) { next = map[i][k]; if (next != 0) { change = 1; map[i][j] = map[i][k]; map[i][k] = 0; k = 4; } k++; } } } } return change; } 向右

代码如下:

都差不多,第一层循环改为从行开始,第二层循环从列开始,因为是向右移动,是从最后一列开始

int right() { int now = 0, next = 0; int k = 0; for (int i = 0; i < 4; i++) { for (int j = 3; j >= 0; j--) { now = map[i][j]; if (now != 0) { k = j - 1; while (k >= 0) { next = map[i][k]; if (next != 0) { if (next == now) { change = 1; score += map[i][k]; map[i][j] = map[i][k] * 2; map[i][k] = 0; } k = -1; } k--; } } } for (int j = 3; j >= 0; j--) { now = map[i][j]; if (now != 0) { k = j - 1; while (k >= 0) { next = map[i][k]; if (next != 0) { if (next == now) { change = 1; score += map[i][k]; map[i][j] = map[i][k] * 2; map[i][k] = 0; } k = -1; } k--; } } } } for (int i = 0; i < 4; i++) { for (int j = 3; j >= 0; j--) { now = map[i][j]; if (now == 0) { k = j - 1; while (k >= 0) { next = map[i][k]; if (next != 0) { change = 1; map[i][j] = map[i][k]; map[i][k] = 0; k = -1; } k--; } } } } return change; } 7.判断是否结束

代码如下:

void over() { gameover = 0; //将gameover设置为0 如果以下循环不能使gameover变为1就结束游戏 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (map[i][j] == 0) { //还存在0就可以继续 gameover = 1; } if (i >= 1) { //i>=1是因为i-1要>=0 if (map[i][j] == map[i - 1][j]) { //如果上下相邻元素右相等的就继续 gameover = 1; } } if (j >= 1) { //j>=1是因为j-1要>=0 if (map[i][j] == map[i][j - 1]) { //如果左右相邻元素右相等的就继续 gameover = 1; } } } } } 三、总结

2048就这么多了,第一次随机数在边界(下图在右边),第一次按D是没有用的,只能按上下左

有什么好的解决方法可以提出来,不想 想了



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3