c语言实现2048游戏
温馨提示:
本文最后更新于 2019年03月12日,已超过 2,017 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
经过一天的学习研究,终于实现了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)区间内的整数*/
}
游戏截图如下:
正文到此结束
- 本文标签: 编程语言
- 本文链接: https://www.php20.cn/article/175
- 版权声明: 本文由仙士可原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权