企业网站备案网址,有什么网站可以做编程题,深圳建站公司的小技巧,合肥网站建设2048是众所周知的一款经典游戏#xff0c;在曾经没有智能电脑和手机的年代#xff0c;也陪伴了我们许多年。那今天就让我们用C语言来回顾一下这款游戏吧~
一、游戏2048的思路
2048游戏的玩法是在初始的时候#xff0c;给玩家一个4*4格子的#xff0c;其中内容全为空的棋盘…2048是众所周知的一款经典游戏在曾经没有智能电脑和手机的年代也陪伴了我们许多年。那今天就让我们用C语言来回顾一下这款游戏吧~
一、游戏2048的思路
2048游戏的玩法是在初始的时候给玩家一个4*4格子的其中内容全为空的棋盘。每过一回合棋盘上就会在随机位置生成一个数字2而2就是2048游戏中最小的数字。在每一回合中玩家需要输入WSAD来移动棋盘中现有的数字。W代表上移S代表下移A代表左移D代表右移。而在数字的移动过程中如果有两个数字大小相同并且在移动过程中发生了碰撞那么就会将两个数字合成为一个值为两数之和的数字。当棋盘中所有格子都被装满时则游戏结束。
以上就是游戏2048的规则啦那么让我们把这些规则一条条理清顺序再对各个规则逐一击破吧~
1.打印游戏菜单
首先我们需要创造一个可以选择开始游戏和退出游戏的菜单。打印游戏菜单就没什么过多的要求符合自己的审美自己喜欢就好啦~
2.将4*4格内数据初始化
想要在每一个格子中填充数据需要对每一个格子内的值进行初始化。
3.在棋盘随机位置生成一个2
想要游戏正常运行通过使用生成随机数的rand()函数使棋盘每一回合生成一个2是不可或缺的条件。
4.打印游戏棋盘
我们需要创造一个能够容纳4*4格子内所有数值并且又不失美观的棋盘。
5.实现WSAD移动数字功能
我们需要构建一个能够使输入WSAD时使棋盘中的数字进行相应的移动。
6.判断游戏是否结束
创造一个判断游戏结束的函数。
二、游戏2048的文件
实现游戏2048需要分成头文件game.h源文件game.c源文件test.c三个文件。
他们的作用分别是
game.h作为头文件它用来存放创造游戏所需要的各种类型的全局变量并且也用来实现编写代码使所必需的函数说明。game.c 存放各种实现游戏功能所需要的函数。test.c作为编译的主程序存放主函数编写实现游戏功能的主要思想。
三、实现游戏的各种函数
①打印游戏菜单
void GameInte()
{printf(**********************************\n);printf(--**--**- 游 戏 2 0 4 8 -**--**--\n);printf(**********************************\n);printf(***-*-*-*-* 1.play *-*-*-*-***\n);printf(***-*-*-*-* 0.quit *-*-*-*-***\n);printf(************----------************\n);printf(是否游玩?请输入:);
}
我们需要将菜单函数GameInte在源文件game.c中进行创建和定义然后再在头文件game.h中对函数进行声明。就像这个样子 给大家看一下game.h头文件中宏定义的数值和定义的全局变量这样方便后期对数值修改并且修改代码时也比较方便
②棋盘的数据初始化
因为是4*4的数据所以我们在上面定义了一个全局变量board[Row][Col]用来存放这4*4个的数值。定义成int型方便后续接收整形数据也方便数值的打印。在这里我们将棋盘数据的初始值都设置成0。
void BoardCreate(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row; i){for (j 0; j col; j){board[i][j] 0;}}
}③打印游戏棋盘
因为在上面我们定义的用于记录数据的二维数组中存放的数据为int型所以没办法像创造其他棋盘一样也用 来代表空格子 所以在打印游戏棋盘的时候我们可以使用一个if...else选择语句使当格子中数值为0时不打印格子中的数据。
void PrintBoard(int board[Row][Col], int row, int col)
{system(CLS);//清空上一回合的屏幕printf(\n);int i 0;int j 0;printf( ----------2048 游戏----------\n);printf(-*-*-*-*-*- 0-exit -*-*-*-*-*- \n);printf( --------------------\n);for (i 0; i row; i){printf( |);for (j 0; j col; j){if (board[i][j] 0)printf( |);elseprintf(%4d |, board[i][j]);}printf(\n --------------------\n);}printf(w-up s-down a-left d-right\n);printf( ----------2048 游戏----------\n);
}
游戏棋盘可以按照自己的意愿随意更改我这只是一个参考打印出来是这个样子的
④在棋盘随机位置生成一个2
在棋盘的随机位置生成2就需要用到生成随机数的函数rand()和使rand()变成真正随机数的srand()了。我们需要在test.c文件的主函数中输入srand((unsigned int)time(NULL))其作用是使生成随机数的rand()随时间变化而时刻变化。然后我们再在生成随机数的函数中使用int a rand() % row; int b rand() % col来创造两个随机的坐标再将对应坐标中的值改变为2。(如果坐标已经有数字则使用goto语句跳转回去重新生成坐标)
void TwoFind(int board[Row][Col], int row, int col)
{again:int a rand() % row;int b rand() % col;if (board[a][b] 0){board[a][b] 2;}elsegoto again;
}我们调试两次代码可以发现2生成的位置并不相同这就代表功能的实现成功了。
⑤实现通过WSAD选择上下左右
我们通过使用for循环嵌套的方式来遍历数组中的全部元素通过WSAD对应的上下左右移动判断要移动的元素的上下左右是否为0如果为0则将元素向着对应的位置移动如果不为0则判断两元素是否相等如果两元素相等则将靠近此次移动方向的元素加倍另一个元素则减少成0如果两元素不相等则不对两元素进行移动处理。
1.实现按W向上移动
void Wup(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i row - 1; i 0; i--){for (j col - 1; j 0; j--)//必须设成0,否则j失去了0的情况,会导致第一列无法正常移动{while (board[i][j] ! 0 board[i - 1][j] 0){board[i - 1][j] board[i][j];board[i][j] 0;}}}for (i row - 1; i 0; i--){for (j col - 1; j 0; j--){while (board[i][j] board[i - 1][j]board[i][j]!0board[i-1][j]!0){board[i - 1][j] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}
或许有人会问为什么for循环的遍历要逆向遍历呢其实我最开始也是按照从头到尾的顺序遍历的但是写完代码却发现每一次只能够将元素移动一个格子后来我才发现
比如此时我们想把第三行的元素挪到第一行如果是从前往后依次遍历数组当我们把第三行的挪到第二行之后紧接着就去遍历第四行了不能再找到已经上移的元素所以就只能够实现一次移动。但如果我逆向遍历的话当我将第三行的元素挪到了第二行紧接着我就会遍历第二行然后找到这个元素再把它挪到第一行这样就实现了按W上移的功能了。
通过这两张图来进行解释可能会更加的一目了然。 之后我们进行WSAD四种方向的移动时也需要对照遍历的四种方向来选取正序遍历和逆序遍历。看了这两张图你应该就能明白我的意思啦~那么接下来让我们看看是否成功实现了W向上移动的功能看来成功实现了移动的功能~再让我们看看将元素数值合并和不相同的元素堆叠的功能是否实现吧看来也成功实现啦~
2.实现按S向下移动
和上面Wup的代码其实大同小异只是向上移动时是当前元素与头顶的元素进行判断是否为0和比较大小而向下移动则是当前元素与下方的元素进行判断是否为0和比较大小。
通过刚才的两张图想必大家应该知道实现按S向下移动是正序遍历还是逆序遍历了吧~没错就是正序遍历
void Sdown(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row - 1; i)//必须设置成row - 1,防止while循环中越界访问{for (j 0; j col; j){while (board[i][j] ! 0 board[i 1][j] 0){board[i 1][j] board[i][j];board[i][j] 0;}}}for (i 0; i row - 1; i){for (j 0; j col; j){while (board[i][j] board[i 1][j] board[i][j] ! 0 board[i 1][j] ! 0){board[i 1][j] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}看来向下移动功能也实现啦~
3.实现按A向左移动
接下来的按A向左移动和按D向右移动跟上面的W向上移动和S向下移动基本上是相同的东西只要懂了上面两个代码这两个自然也就懂了。那么我就不多废话直接将代码奉上啦~
void Aleft(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i row - 1; i 0; i--){for (j col - 1; j 0; j--)//必须设成0,否则j失去了0的情况,会导致第一列无法正常移动{while (board[i][j] ! 0 board[i][j - 1] 0){board[i][j - 1] board[i][j];board[i][j] 0;}}}for (i row - 1; i 0; i--){for (j col - 1; j 0; j--){while (board[i][j] board[i][j - 1] board[i][j] ! 0 board[i][j - 1] ! 0){board[i][j - 1] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}
4.实现按D向右移动
void Dright(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row; i){for (j 0; j col - 1; j){while (board[i][j] ! 0 board[i][j 1] 0){board[i][j 1] board[i][j];board[i][j] 0;}}}for (i 0; i row; i){for (j 0; j col - 1; j){while (board[i][j] board[i][j 1] board[i][j] ! 0 board[i][j 1] ! 0){board[i][j 1] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}
5.选择上下左右
这个函数就是我们前四个函数的总和我们需要利用switch语句来判断键盘上输入的WSAD从而来通过case充当下一步函数的调用的过程。(在switch语句中可以添加一些其他的功能比如说你想退出游戏就加一个case 0的按键然后写出对应功能的代码就可以啦这里我只适配了退出游戏的case 0其余的就交给小伙伴们自行探索啦~)
void ChooseMove(int board[Row][Col], int row, int col)
{again:char a getch();switch(a){case W:case w:Wup(board, Row, Col);break;case S:case s:Sdown(board, Row, Col);break;case A:case a:Aleft(board, Row, Col);break;case D:case d:Dright(board, Row, Col);break;case 0:{printf(你确定要退出游戏吗?\n);printf(如果退出请输入0,继续游戏请按任意键\n);int choose;scanf(%d, choose);if (choose 0){printf(退出游戏\n);exit(0);//程序正常结束执行}else{printf(返回游戏:\n);goto again;}break;}}
} 到了这里我们的2048游戏基本上就能够进行游玩啦~
⑥判断游戏是否结束
判断游戏结束我们只需要创造一个计数器统计4*4棋盘中非零元素的数量当非零元素的数量正好等于4*4时那么游戏也就结束啦。
void over(int board[Row][Col], int row, int col)
{int i 0;int j 0;int sum 0;for (i 0; i row; i){for (j 0; j col; j){if (board[i][j] ! 0)sum;}}if (sum row * col){PrintBoard(board, Row, Col);printf(对不起,格子已满,游戏到此为止了!!!\n);exit(0);}
} 好啦~至此我们的C语言游戏2048就基本完成啦~这个也是比较初阶版适合刚入门的小伙伴们来刷题用~那么废话不多说这就将完整代码双手奉上
四、游戏2048完整代码
1.game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#includestdio.h
#includestdlib.h
#include time.h
#include windows.h
#define Row 4
#define Col 4
int board[Row][Col];
//游戏菜单
void GameInte();//4*4格内数据初始化
void BoardCreate(char board[Row][Col], int row, int col);//在棋盘随机位置生成一个2
void TwoFind(char board[Row][Col], int row, int col);//打印游戏界面
void PrintBoard(char board[Row][Col], int row, int col);//实现按W键向上移动
void Wup(char board[Row][Col], int row, int col);//实现按S键向下移动
void Sdown(int board[Row][Col], int row, int col);//实现按A键向左移动
void Aleft(int board[Row][Col], int row, int col);//实现按D键向右移动
void Dright(int board[Row][Col], int row, int col);//实现通过WSAD选择上下左右
void ChooseMove(int board[Row][Col], int row, int col);//判断游戏是否结束
void over(int board[Row][Col], int row, int col);
2.game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include game.hvoid GameInte()
{printf(**********************************\n);printf(--**--**- 游 戏 2 0 4 8 -**--**--\n);printf(**********************************\n);printf(***-*-*-*-* 1.play *-*-*-*-***\n);printf(***-*-*-*-* 0.quit *-*-*-*-***\n);printf(************----------************\n);printf(是否游玩?请输入:);
}
void BoardCreate(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row; i){for (j 0; j col; j){board[i][j] 0;}}
}void TwoFind(int board[Row][Col], int row, int col)
{again:int a rand() % row;int b rand() % col;if (board[a][b] 0){board[a][b] 2;}elsegoto again;
}void PrintBoard(int board[Row][Col], int row, int col)
{system(CLS);//清屏上一次的棋盘printf(\n);int i 0;int j 0;printf( ----------2048 游戏----------\n);printf(-*-*-*-*-*- 0-exit -*-*-*-*-*- \n);printf( --------------------\n);for (i 0; i row; i){printf( |);for (j 0; j col; j){if (board[i][j] 0)printf( |);elseprintf(%4d |, board[i][j]);}printf(\n --------------------\n);}printf(w-up s-down a-left d-right\n);printf( ----------2048 游戏----------\n);
}void Wup(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i row - 1; i 0; i--){for (j col - 1; j 0; j--)//必须设成0,否则j失去了0的情况,会导致第一列无法正常移动{while (board[i][j] ! 0 board[i - 1][j] 0){board[i - 1][j] board[i][j];board[i][j] 0;}}}for (i row - 1; i 0; i--){for (j col - 1; j 0; j--){while (board[i][j] board[i - 1][j]board[i][j]!0board[i-1][j]!0){board[i - 1][j] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}void Sdown(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row - 1; i)//必须设置成row - 1,防止while循环中越界访问{for (j 0; j col; j){while (board[i][j] ! 0 board[i 1][j] 0){board[i 1][j] board[i][j];board[i][j] 0;}}}for (i 0; i row - 1; i){for (j 0; j col; j){while (board[i][j] board[i 1][j] board[i][j] ! 0 board[i 1][j] ! 0){board[i 1][j] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}void Aleft(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i row - 1; i 0; i--){for (j col - 1; j 0; j--)//必须设成0,否则j失去了0的情况,会导致第一列无法正常移动{while (board[i][j] ! 0 board[i][j - 1] 0){board[i][j - 1] board[i][j];board[i][j] 0;}}}for (i row - 1; i 0; i--){for (j col - 1; j 0; j--){while (board[i][j] board[i][j - 1] board[i][j] ! 0 board[i][j - 1] ! 0){board[i][j - 1] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}void Dright(int board[Row][Col], int row, int col)
{int i 0;int j 0;for (i 0; i row; i){for (j 0; j col - 1; j){while (board[i][j] ! 0 board[i][j 1] 0){board[i][j 1] board[i][j];board[i][j] 0;}}}for (i 0; i row; i){for (j 0; j col - 1; j){while (board[i][j] board[i][j 1] board[i][j] ! 0 board[i][j 1] ! 0){board[i][j 1] * 2;board[i][j] 0;}}}PrintBoard(board, Row, Col);
}void ChooseMove(int board[Row][Col], int row, int col)
{again:char a getch();switch(a){case W:case w:Wup(board, Row, Col);break;case S:case s:Sdown(board, Row, Col);break;case A:case a:Aleft(board, Row, Col);break;case D:case d:Dright(board, Row, Col);break;case 0:{printf(你确定要退出游戏吗?\n);printf(如果退出请输入0,继续游戏请按任意键\n);int choose;scanf(%d, choose);if (choose 0){printf(退出游戏\n);exit(0);}else{printf(返回游戏:\n);goto again;}break;}}
}void over(int board[Row][Col], int row, int col)
{int i 0;int j 0;int sum 0;for (i 0; i row; i){for (j 0; j col; j){if (board[i][j] ! 0)sum;}}if (sum row * col){PrintBoard(board, Row, Col);printf(对不起,格子已满,游戏到此为止了!!!\n);exit(0);}
}
3.test.c
#includegame.h
void game()
{//初始化4*4格子内数据//BoardCreate(board, Row, Col);//打印游戏界面PrintBoard(board, Row, Col);//实现按W键向上移动//Wup(board, Row, Col);//实现按S键向下移动//Sdown(board,Row,Col);//实现按A键向左移动//Aleft(board, Row, Col);//实现按D键向右移动//Dright(board,Row,Col);//实现通过WSAD选择上下左右ChooseMove(board, Row, Col);//在棋盘随机位置生成一个2TwoFind(board, Row, Col);over(board, Row, Col);
}
int main()
{srand((unsigned int)time(NULL));GameInte();BoardCreate(board, Row, Col);int a 0;do{scanf(%d, a);if (a 1){game();}else if (a 0){printf(退出游戏\n);break;}else{printf(输入错误,重新输入:\n);}} while (a);return 0;
}那么关于用C语言来实现游戏2048就讲解到这里啦~如果有说的不够充分或者有错误的地方还希望各位能在评论区积极指出我也会积极学习的我们下期再见啦ヾ(•ω•)o