经过一天的学习研究,终于实现了c语言dos版本的2048游戏,通过wsad控制方向,esc,q键退出,空格键重新开始,实现了计分板功能,代码如下:
#include <stdio.h> #include <conio.h> #include <stdlib.h> // for rand() and srand() and exit() #include <windows.h> // for system() #include <string.h> //字符串操作函数 #include <sys/time.h> //系统时间 void welcome(void);//欢迎界面 void cls(void);//清屏 void init(void);//初始化元素 void draw(void);//绘制图形 int mt_rand(int, int);//随机数专用 void play(void);//游戏中 void addNumber(void);//新增数字 void keyUp(void);//向上事件; void keyDown(void);//向下事件; void keyLeft(void);//向左事件; void keyRight(void);//向右事件; void gameOver(int);//结束事件; void isGameOver(void);//判断游戏是否结束; int map\[4\]\[4\]; int emptyNum = 16;//地图元素为空数量 int scores = 0; void main(void) { srand(time(0));//随机数播种 welcome(); init(); cls(); draw(); while (1) { // printf("%d\\n",getch()); isGameOver(); play(); Sleep(100); } } /** * 欢迎界面 */ void welcome(void) { printf("****************************\\n"); printf(" 2048 doc版 \\n"); printf(" 通过w/s/a/d控制 \\n"); printf(" 通过字母q或esc退出游戏 \\n"); printf(" 通过空格键可重新开始 \\n"); printf(" 请按任意键开始游戏 \\n"); printf("****************************\\n"); getch();//阻塞方式等待按键 } /** * 初始化界面元素 */ void init(void) { int x, y; emptyNum = 16; scores=0; for (x = 0; x < 4; ++x) { for (y = 0; y < 4; ++y) { map\[x\]\[y\] = 0; } } x = mt_rand(1, 4) % 4; y = mt_rand(1, 4) % 4; // x = 1; // y = 3; map\[x\]\[y\] = 2; emptyNum--;//为空数量减一 } /** * 运行游戏 */ void play(void) { //检测em //监听按键 int key = getch(); switch (key) { case 119: // 向上移动 case 87: keyUp(); cls(); addNumber(); draw(); break; case 115: // 向下移动 case 83: keyDown(); cls(); addNumber(); draw(); break; case 97: // 向左移动 case 65: keyLeft(); cls(); addNumber(); draw(); break; case 100: // 向右移动 case 68: keyRight(); cls(); addNumber(); draw(); break; case 27: // 退出游戏 case 113: case 81: cls(); printf("****************************\\n"); printf(" 确定退出? \\n"); printf(" Enter确定,其他键取消 \\n"); printf("****************************\\n"); int key = getch(); if (key == 13) { gameOver(1); } else { cls(); draw(); } break; case 32: cls(); printf("****************************\\n"); printf(" 确定重新开始? \\n"); printf(" Enter确定,其他键取消 \\n"); printf("****************************\\n"); key = getch(); cls(); if (key == 13) { init(); } draw(); break; default: cls(); draw(); printf("按键错误,请重新输入\\n"); break; } } /** * 随机增加2,4字母 */ void addNumber(void) { int temp, number; int x, y; if (emptyNum > 0) { // 找出空格 do { x = mt_rand(1, 4) % 4; y = mt_rand(1, 4) % 4; } while (map\[x\]\[y\] != 0); number = mt_rand(1, 2); temp = number % 2; if (temp == 1) { // 判断是生成数字2,还是数字4 map\[x\]\[y\] = 2; emptyNum--; } if (temp == 0) { map\[x\]\[y\] = 4; emptyNum--; } } } /** * 判断游戏是否结束 */ void isGameOver(void) { if (emptyNum == 0) { for (int x = 0; x < 4; ++x) { for (int y = 0; y < 4; ++y) { //判断右边和下边的是否相等 if (map\[x\]\[y\] != map\[x + 1\]\[y\] && map\[x\]\[y\] != map\[x\]\[y + 1\]) { gameOver(2); } } } } } /** * 游戏结束处理 * @param overType */ void gameOver(int overType) { switch (overType) { case 1: cls(); //正常结束 printf("****************************\\n"); printf(" 已退出... \\n"); printf("****************************\\n"); Sleep(1); exit(0); case 2: cls(); init(); printf("****************************\\n"); printf(" 游戏结束,分数:%d \\n",scores); printf(" 是否重新开始游戏? \\n"); printf(" Enter继续游戏,Esc退出 \\n"); printf("****************************\\n"); int key = getch(); cls(); switch (key) { case 27: gameOver(1); break; case 13: welcome(); break; } } } void keyUp(void) { int x, y, i; //先合并相同的方块 //通过y轴,上下合并 for (y = 0; y < 4; y++) { for (x = 0; x < 4; ++x) { if (map\[x\]\[y\] != 0) { for (i = y + 1; i < 4; ++i) { if (map\[x\]\[y\] == map\[x\]\[i\]) { map\[x\]\[y\] = map\[x\]\[y\] * 2; scores+=map\[x\]\[y\]; map\[x\]\[i\] = 0; emptyNum++; break; } else if (map\[x\]\[i\] != 0) { break; } else { continue; } } } } } //向上移动数字 for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { if (map\[x\]\[y\] == 0) { for (i = y + 1; i < 4; ++i) { if (map\[x\]\[i\] != 0) { map\[x\]\[y\] = map\[x\]\[i\]; map\[x\]\[i\] = 0; break; } } } } } } void keyDown(void) { int x, y, i; //先合并相同的方块 //通过y轴,上下合并 for (y = 3; y >= 0; y--) { for (x = 0; x < 4; ++x) { if (map\[x\]\[y\] != 0) { for (i = y - 1; i >= 0; i--) { if (map\[x\]\[y\] == map\[x\]\[i\]) { map\[x\]\[y\] += map\[x\]\[i\]; scores+=map\[x\]\[y\]; map\[x\]\[i\] = 0; emptyNum++; break; } else if (map\[x\]\[i\] != 0) { break; } else { continue; } } } } } //向下移动数字 for (y = 3; y >= 0; y--) { for (x = 0; x < 4; x++) { if (map\[x\]\[y\] == 0) { for (i = y - 1; i >= 0; i--) { if (map\[x\]\[i\] != 0) { map\[x\]\[y\] = map\[x\]\[i\]; map\[x\]\[i\] = 0; break; } } } } } } void keyLeft(void) { int x, y, i; //先合并相同的方块 //通过x轴,左右合并 for (x = 0; x < 4; x++) { for (y = 0; y < 4; ++y) { if (map\[x\]\[y\] != 0) { for (i = x + 1; i < 4; ++i) { if (map\[x\]\[y\] == map\[i\]\[y\]) { map\[x\]\[y\] = map\[x\]\[y\] * 2; scores+=map\[x\]\[y\]; map\[i\]\[y\] = 0; emptyNum++; break; } else if (map\[i\]\[y\] != 0) { break; } else { continue; } } } } } //向左移动数字 for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++) { if (map\[x\]\[y\] == 0) { for (i = x + 1; i < 4; ++i) { if (map\[i\]\[y\] != 0) { map\[x\]\[y\] = map\[i\]\[y\]; map\[i\]\[y\] = 0; break; } } } } } } void keyRight(void) { int x, y, i; //先合并相同的方块 //通过x轴,左右合并 for (x = 3; x >= 0; x--) { for (y = 0; y < 4; ++y) { if (map\[x\]\[y\] != 0) { for (i = x - 1; i >= 0; i--) { if (map\[x\]\[y\] == map\[i\]\[y\]) { map\[x\]\[y\] += map\[i\]\[y\]; scores+=map\[x\]\[y\]; map\[i\]\[y\] = 0; emptyNum++; break; } else if (map\[i\]\[y\] != 0) { break; } else { continue; } } } } } //向右移动数字 for (x = 3; x >= 0; x--) { for (y = 0; y < 4; y++) { if (map\[x\]\[y\] == 0) { for (i = x - 1; i >= 0; i--) { if (map\[i\]\[y\] != 0) { map\[x\]\[y\] = map\[i\]\[y\]; map\[i\]\[y\] = 0; break; } } } } } } /** * 绘制游戏界面 */ void draw(void) { int x, y; //绘制第一行横线 printf(" ___________________"); printf("\\n"); for (y = 0; y < 4; ++y) { // 一个方格由三根竖线组成 for (x = 0; x < 4; ++x) { // 第一排竖线 每个竖线之间占5个格 printf("| "); } printf("|\\n"); for (x = 0; x < 4; ++x) { // 第二排竖线与数字 if (map\[x\]\[y\] == 0) { printf("| "); } else { printf("|%4d", map\[x\]\[y\]); } } printf("|\\n"); for (x = 0; x < 4; ++x) { // 第三排竖线加底线 printf("|____"); } printf("|\\n"); } //输出分数 printf("分数:%d \\n", scores); } /** * 清屏 */ void cls(void) { system("cls"); } /** * 根据区间随机 * @param start * @param end * @return */ int mt_rand(int start, int end) { return rand() % (end + 1 - start) + start; /*生成一个\[start,end)区间内的整数*/ }
游戏截图如下: