这篇文章主要介绍怎么用C语言完整实现2048游戏,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
一、游戏思路
程序开始时出现菜单,让玩家选择开始游戏或者退出游戏。
玩家选择开始游戏后,出现棋盘,通过方向键选择移动的方向。
移动后会将所有方块向该方向移动直至补全空格,同样数字的方块合并成它们的和,还会生成一个随机位置的2或4。
当出现“2048”时,游戏胜利;当棋盘满且无法消除时,游戏失败。
二、游戏框架
1.菜单界面
菜单
void menu(){printf("**************************\n");printf("*****按 1 开 始 游 戏*****\n");printf("*****按 0 退 出 游 戏*****\n");printf("**************************\n");}
菜单的选择
int main(){int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:game2048(); break;case 0:printf("退出游戏,客官常来玩呀~)\n");break;default:printf("给你一次重新选择的机会\n");break;}} while (input);return 0;}
实际效果
菜单我觉得还是挺顺眼的,就是有点丑,毕竟是初学者就不要要求太高了。
2.游戏主体
1.初始化界面:
生成一个4行4列的数组(此处的行数和列数已在头文件中用#define宏定义)。
并且打印出来。
void DisplayBoard(int board[ROW][COL],int row, int col){ int i = 0; int j = 0; for (int j = 0; j < COL; j++) printf("+-----"); printf("+\n"); for (int i = 0; i < ROW; i++) { for (int j= 0; j < COL; j++) { printf("|"); if (board[i][j]!=0) printf("%5d", board[i][j]); else printf(" "); } printf("|\n"); for (int j = 0; j < COL; j++) { printf("+-----"); } printf("+\n"); } }
效果如下:
方吗?方就对了,方就是个好界面!
2.随机生成初始数字
游戏的界面我们现在已经有了,接下来要做的就是加入两个随机位置的”2"。
void get_num(int board[ROW][COL]){int x, y;x = rand() % ROW;y = rand() % COL;board[x][y] = 2;//一开始随机的数为2x = rand() % ROW;y = rand() % COL;while (board[x][y] == 2) {x = rand() % ROW;y = rand() % COL;}board[x][y] = 2; system("cls"); //清屏,美观界面return;}
(这里照例还是使用了时间戳获取随机数的方法)
可以看到每一次出现的两个位置都是随机的。
3.实现移动
这里我们以向上为例,我们要实现移动,以及判定两个方块数字相同就合并成为它们的和,并且当合并后存在空格时继续向上移动。
简单来说,就是 移动 → 合并 → 再次移动补空。其他三个方向也是一样的道理,只需要改变其中的数值便可实现。
void up(int board[ROW][COL]){int i = 0; int j = 0;int x = 0;int y = 0;for (i = 0; i < ROW; i++){//移动j = 0;y = 0;while (j < COL-1 && y < COL-1 ){if (board[j][i] == 0) {for (x = j; x < ROW-1; x++)board[x][i] = board[x + 1][i];board[ROW-1][i] = 0;y++;}elsej++; }//合并for (j = 0; j < COL-1; j++)if (board[j][i] == board[j + 1][i] && board[j][i] != 0) { board[j][i] = board[j][i] * 2; //和board[j + 1][i] = 0;}//再次移动补空j = 0;y = 0;while (j < COL - 1 && y < COL - 1){if (board[j][i] == 0) {for (x = j; x < ROW - 1; x++)board[x][i] = board[x + 1][i];board[ROW - 1][i] = 0;y++;}elsej++;}}}
4.增加新数字
每次移动会在随机位置出现一个新的数字,可能是2,可能是4。
通过查询网上资料得知,随机到2的概率约为 9/10,随机到4的概率约为 1/10。
void put_num(int board[ROW][COL]){int x = 0;int y = 0; int z = 0;x = rand() % ROW;y = rand() % COL;while (board[x][y] !=0){x = rand() % ROW;y = rand() % COL;}z = rand() % 10; if (z<9)board[x][y] = 2;elseboard[x][y] = 4;return;}
5.判定胜负
当出现2048时胜利,当格子满了且无法消除时失败。
int is_fail(int board[ROW][COL]){int i = 0; int j = 0;for (i = 0; i < ROW; i++){for (j = 0; j < COL; j++){if (board[i][j] == 0)return 0;if (i > 0){if (board[i - 1][j] == board[i][j])return 0;}if (j > 0){if (board[i][j - 1] == board[i][j])return 0;}}}return 1;} int is_win(int board[ROW][COL]){int i = 0;int j = 0;int num = 0;for (i = 0; i < ROW; i++)for (j = 0; j < COL; j++){if (board[i][j] > num)num = board[i][j];}if (num >= 2048)return 1;elsereturn 0;}
6.游戏函数
将上述代码结合起来
void game2048(){int board[ROW][COL] = { {0} };int control = 0;DisplayBoard(board); init_num(board);system("cls"); //清屏,美观界面DisplayBoard(board);while ((control = _getch()) != 0x1b){ switch (control){case 0xe0:switch (control = getch()){ case 72: up(board); break; case 80: down(board); break; case 75: left(board); break; case 77: right(board); break; default: break;}system("cls");DisplayBoard(board);if (is_win(board) == 1){printf("恭喜你赢了!"); }if (is_fail(board) == 1){printf("哈哈哈哈哈哈哈好菜\n");}}}}
三、游戏运行
已知目前游戏存在bug,当格子满了的时候假定一个方向可以消除,另一个方向不可以消除,按了那个不可以消除的方向的话,就会无法操作了,鉴于本人目前初学者并未能够想到很好的解决方法。若有大佬有好的方法也可指点一下。
我太菜了玩了好久都玩不到2048,最高只有512,1024还是舍友打出来的。
更新:修复了bug
先判断数组是否相同再选择是否添加新的随机位置的数字。
在此感谢各位帮助我测试的朋友,无论成功与否,当然特别感谢提供了这张图片的朋友。
四、所有代码
game2048.h
#pragma once #include <stdio.h>#include <time.h>#include <stdlib.h>#include <windows.h>#include<conio.h> #define ROW 4#define COL 4const int copy[ROW][COL]; //初始化并打印游戏界面void DisplayBoard(int board[ROW][COL]);//开局随机生成两个2void init_num(int board[ROW][COL]);//在移动后随机放置数字2或4void put_num(int board[ROW][COL]);//移动void up(int board[ROW][COL]);void down(int board[ROW][COL]);void left(int board[ROW][COL]);void right(int board[ROW][COL]);//判定胜负int is_win(int board[ROW][COL]);int is_fail(int board[ROW][COL]);
game2048.c
#define _CRT_SECURE_NO_WARNINGS 1#include "game2048.h" void DisplayBoard(int board[ROW][COL]){ int i = 0; int j = 0; printf("tip:*方向键控制方块移动*ESC键返回菜单*\n"); for (int j = 0; j < COL; j++) printf("+-----"); printf("+\n"); for (int i = 0; i < ROW; i++) { for (int j= 0; j < COL; j++) { printf("|"); if (board[i][j]!=0) printf("%5d", board[i][j]); else printf(" "); } printf("|\n"); for (int j = 0; j < COL; j++) { printf("+-----"); } printf("+\n"); } } void init_num(int board[ROW][COL]){int x, y;x = rand() % ROW;y = rand() % COL;board[x][y] = 2;//随机在一个位置生成2x = rand() % ROW;y = rand() % COL;while (board[x][y] == 2) {x = rand() % ROW;y = rand() % COL;}board[x][y] = 2; return;} void put_num(int board[ROW][COL]){int x = 0;int y = 0; int z = 0;x = rand() % ROW;y = rand() % COL;while (board[x][y] !=0){x = rand() % ROW;y = rand() % COL;}z = rand() % 10;if (z<9)board[x][y] = 2;elseboard[x][y] = 4;return;}void up(int board[ROW][COL]){int i = 0; int j = 0;int x = 0;int y = 0;for (i = 0; i < ROW; i++){//移动j = 0;y = 0;while (j < COL-1 && y < COL-1 ){if (board[j][i] == 0) {for (x = j; x < ROW-1; x++)board[x][i] = board[x + 1][i];board[ROW-1][i] = 0;y++;}elsej++; }//合并for (j = 0; j < COL-1; j++)if (board[j][i] == board[j + 1][i] && board[j][i] != 0) { board[j][i] = board[j][i] * 2;board[j + 1][i] = 0;}//再次移动补空j = 0;y = 0;while (j < COL - 1 && y < COL - 1){if (board[j][i] == 0){for (x = j; x < ROW - 1; x++)board[x][i] = board[x + 1][i];board[ROW - 1][i] = 0;y++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;} void down(int board[ROW][COL]){int i = 0;int j = 0;int x = 0;int y = 0;for (i = 0; i < ROW; i++){j = COL-1;y = 0;while (j > 0 && y < COL-1){if (board[j][i] == 0){for (x = j; x > 0; x--)board[x][i] = board[x - 1][i];board[0][i] = 0;y++;}else j--;}for (j = COL-1; j > 0; j--)if (board[j][i] == board[j - 1][i] && board[j][i] != 0){board[j][i] = board[j][i] * 2;board[j - 1][i] = 0;}j = COL - 1;y = 0;while (j > 0 && y < COL - 1){if (board[j][i] == 0){for (x = j; x > 0; x--)board[x][i] = board[x - 1][i];board[0][i] = 0;y++;}elsej--;}}if (contrast(board) == 0)put_num(board);elsereturn;}void left(int board[ROW][COL]){int i = 0;int j = 0;int x = 0;int y = 0;for (i = 0; i < ROW; i++){j = 0; y = 0;while (j < 3 && y < 3 ){if (board[i][j] == 0){for (x = j; x < ROW-1; x++)board[i][x] = board[i][x + 1];board[i][COL-1] = 0;y++;}elsej++;}for (j = 0; j < 3; j++)if (board[i][j] == board[i][j + 1] && board[i][j] != 0){board[i][j] = board[i][j] * 2;board[i][j + 1] = 0;}j = 0; y = 0;while (j < 3 && y < 3){if (board[i][j] == 0){for (x = j; x < ROW - 1; x++)board[i][x] = board[i][x + 1];board[i][COL - 1] = 0;y++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;} void right(int board[ROW][COL]){int i = 0;int j = 0;int x = 0;int y = 0;for (i = 0; i < 4; i++){j = COL-1;y = 0;while (j>0 && y < COL-1){if (board[i][j] == 0){for (x = j; x > 0; x--)board[i][x] = board[i][x - 1];board[i][0] = 0;y++;}else j--;}for (j = 3; j > 0; j--)if (board[i][j] == board[i][j - 1] && board[i][j] != 0){board[i][j] = board[i][j] * 2;board[i][j - 1] = 0;}j = COL - 1;y = 0;while (j > 0 && y < COL - 1){if (board[i][j] == 0){for (x = j; x > 0; x--)board[i][x] = board[i][x - 1];board[i][0] = 0;y++;}else j--;}}if (contrast(board) == 0)put_num(board);elsereturn;} int is_fail(int board[ROW][COL]){int i = 0; int j = 0;for (i = 0; i < ROW; i++){for (j = 0; j < COL; j++){if (board[i][j] == 0)return 0;if (i > 0){if (board[i - 1][j] == board[i][j])return 0;}if (j > 0){if (board[i][j - 1] == board[i][j])return 0;}}}return 1;} int is_win(int board[ROW][COL]){int i = 0;int j = 0;int num = 0;for (i = 0; i < ROW; i++)for (j = 0; j < COL; j++){if (board[i][j] > num)num = board[i][j];}if (num >= 2048)return 1;elsereturn 0;} void copyboard(int board[ROW][COL],int copy[ROW][COL]){int i = 0;int j = 0;for (i = 0; i < ROW; i++)for (j = 0; j < COL; j++)copy[i][j] = board[i][j];} int contrast(int board[ROW][COL]){int i = 0;int j = 0;for (i = 0; i < 4; i++)for (j = 0; j < 4; j++)if (copy[i][j] != board[i][j])return 0;return 1;}
test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "game2048.h" void menu(){printf("**************************\n");printf("*****按 1 开 始 游 戏*****\n");printf("*****按 0 退 出 游 戏*****\n");printf("**************************\n");} void game2048(){int board[ROW][COL] = { {0} };int control = 0;DisplayBoard(board); init_num(board);system("cls"); //清屏,美观界面DisplayBoard(board);while ((control = _getch()) != 0x1b){ switch (control){case 0xe0:switch (control = getch()){ case 72: copyboard(board, copy); up(board); break; case 80: copyboard(board, copy); down(board); break; case 75: copyboard(board, copy); left(board); break; case 77: copyboard(board, copy); right(board); break; default: break;}system("cls");DisplayBoard(board);if (is_win(board) == 1){printf("恭喜你赢了!\n");}if (is_fail(board) == 1){printf("哈哈哈哈哈哈哈好菜\n");}}}} int main(){int input = 0;srand((unsigned int)time(NULL));do{menu(); printf("请选择:"); scanf("%d", &input);switch (input){ case 1: game2048(); break; case 0: printf("退出游戏,客官常来玩呀~)\n"); break; default: printf("给你一次重新选择的机会\n"); break;}} while (input);return 0;}
以上是“怎么用C语言完整实现2048游戏”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!