使用c语言标准库和windows.h,conio.h实现一个cmd 2048游戏

来源:互联网 发布:fastjson解析嵌套数组 编辑:程序博客网 时间:2024/05/24 05:23

使用C在windows下实现一个cmd 2048游戏

因为我从来没写过游戏之类的东西,所以借鉴了一篇博客(https://www.cnblogs.com/wanghuizhao/p/6012429.html)的主要思路,不过代码还算是自己写的

2048游戏界面,通过不断的清屏,打印来实现游戏的动态效果(这个是借鉴的人家的思想)



下边是代码,有注释

#include<stdio.h>#include<time.h>//time()#include<stdlib.h>//srand() rand()#include<Windows.h>//system("command")//执行dos命令“command”#include<conio.h>//getch();//从键盘读取字符并返回,但不显示在屏幕上typedef struct x_y {//用来存放一个坐标int x;int y;}x_y;static x_y get_xy();int a[4][4];int empty;//数组中空格的数目void init();//初始化数组void show();//打印4X4方格及数组数据void to_up();//接收键盘输入,来控制数据移动方向void to_down();void to_left();void to_right();void add_num();//随机添加一个数字到数组void play();int main(void){printf("++++++++++++++++++++++++++++\n");printf("            2048            \n\n");printf("Control by:\n"" w/s/a/d or W/S/A/D\n");printf("press q or Q quit game!\n");printf("++++++++++++++++++++++++++++\n");printf("Any key to continue . . .\n");getch();system("cls");init();show();while(1)play();return 0;}void init(){int i,j;for (i = 0; i < 4; i++)for (j = 0; j < 4; j++)a[i][j] = 0;srand(time(NULL));i = rand()%4;j = rand()%4;a[i][j] = 2;empty = 15;}void show(){int i ,j;for (i = 0; i < 4; i++){for (j = 0; j < 4; j++)printf("|     ");printf("|\n");for (j = 0; j < 4; j++)if (a[i][j] ==0)printf("|     ");elseprintf("|%5d", a[i][j]);printf("|\n");for (j = 0; j < 4; j++)printf("|_____");printf("|\n");}}void play(){switch (getch()){case 'W':case 'w':system("cls");//cls命令清空屏幕to_up();add_num();show();break;case 'A':case 'a':system("cls");to_left();add_num();show();break;case 'S':case 's':system("cls");to_down();add_num();show();break;case 'D':case 'd':system("cls");to_right();add_num();show();break;case 'q':case 'Q':puts("quiting");exit(EXIT_FAILURE);default:printf("\nwrong type!!!\n\n");printf("please type :\n");printf("w/s/a/d or W/S/A/D\n");break;}}//to_up(),将4x4方格阵向上移,并将相邻的大小相等的数据相加合并void to_up(){int i, j,tmp; //i为行数,j为列数,tmp为中间变量int lasti, lastj;//思路://向上移动,则每一列为一个单元,每次操作,只考虑一列//对于一列,考虑第一个元素为当前元素,//如果当前元素为0,直接赋值为第一个相邻元素值,并置0该相邻元素//如果下一个元素(此时为第二个)为0,则,考虑下一个//如果下一个元素,与它相等,则相加合并(下一个元素要置0),//如果下一个元素,与它不等,则将它移到当前元素的相邻位置for (j = 0; j < 4; j++){lasti = 0;lastj = j;//当前元素坐标for (i = 1; i < 4; i++)if (a[i][j] == 0)//考虑下一个continue;else {if (a[lasti][lastj] == 0) {//当前元素为0a[lasti][lastj] = a[i][j];a[i][j] = 0;}else if (a[lasti][lastj] == a[i][j]) {//当前元素与下一个相等a[lasti][lastj] *= 2;a[i][j] = 0;empty += 1;}else {//当前元素与第一个非0相邻元素不等tmp = a[i][j];a[i][j] = 0;a[++lasti][lastj] = tmp;//置当前元素的相邻位(此时已被赋值)为当前元素}}}}//void to_up(void) {//网上的另一种方法,多重循环造成的时间代价很大//int x, y, i;////for (y = 0; y < 4; ++y) {     // 从上向下合并相同的方块 //for (x = 0; x < 4; ++x) {//if (a[x][y] == 0)//;//else {//for (i = x + 1; i < 4; ++i) {//if (a[i][y] == 0)//;//else if (a[x][y] == a[i][y]) {//a[x][y] += a[i][y];//a[i][y] = 0;//++empty;//x = i;//break;//}//else {////x = i - 1;//break;//}//}//}//}//}////for (y = 0; y < 4; ++y)    // 向上移动箱子//for (x = 0; x < 4; ++x) {//if (a[x][y] == 0)//;//else {//for (i = x; (i > 0) && (a[i - 1][y] == 0); --i) {//a[i - 1][y] = a[i][y];//a[i][y] = 0;//}//}//}//}void to_down(){int i, j, tmp; //i为行数,j为列数,tmp为中间变量int lasti, lastj;for (j = 0; j < 4; j++){lasti = 3;lastj = j;//当前元素坐标for (i = 2; i >-1; i--)if (a[i][j] == 0)//考虑下一个continue;else {if (a[lasti][lastj] == 0) {//当前元素为0a[lasti][lastj] = a[i][j];a[i][j] = 0;}else if (a[lasti][lastj] == a[i][j]) {//当前元素与下一个相等a[lasti][lastj] *= 2;a[i][j] = 0;empty += 1;}else {//当前元素与第一个非0相邻元素不等tmp = a[i][j];a[i][j] = 0;a[--lasti][lastj] = tmp;//置当前元素的相邻位(此时已被赋值)为当前元素}}}}void to_left(){int i, j, tmp; //i为行数,j为列数,tmp为中间变量int lasti, lastj;for (i = 0; i < 4; i++){lasti = i;lastj = 0;//当前元素坐标for (j = 1; j < 4; j++)if (a[i][j] == 0)//考虑下一个continue;else {if (a[lasti][lastj] == 0) {//当前元素为0a[lasti][lastj] = a[i][j];a[i][j] = 0;}else if (a[lasti][lastj] == a[i][j]) {//当前元素与下一个相等a[lasti][lastj] *= 2;a[i][j] = 0;empty += 1;}else {//当前元素与第一个非0相邻元素不等tmp = a[i][j];a[i][j] = 0;a[lasti][++lastj] = tmp;//置当前元素的相邻位(此时已被赋值)为当前元素}}}}void to_right(){int i, j, tmp; //i为行数,j为列数,tmp为中间变量int lasti, lastj;for (i = 0; i < 4; i++){lasti = i;lastj = 3;//当前元素坐标for (j = 2; j>-1; j--)if (a[i][j] == 0)//考虑下一个continue;else {if (a[lasti][lastj] == 0) {//当前元素为0a[lasti][lastj] = a[i][j];a[i][j] = 0;}else if (a[lasti][lastj] == a[i][j]) {//当前元素与下一个相等a[lasti][lastj] *= 2;a[i][j] = 0;empty += 1;}else {//当前元素与第一个非0相邻元素不等tmp = a[i][j];a[i][j] = 0;a[lasti][--lastj] = tmp;//置当前元素的相邻位(此时已被赋值)为当前元素}}}}void add_num(){x_y i_j;i_j=get_xy();if (i_j.x == -1){return 0;}srand(time(NULL));a[i_j.x][i_j.y]= (rand()%2)?2:4;empty--;}static x_y get_xy(){int count, newxy, i, j;x_y i_j;if (empty == 0){i_j.x = -1;i_j.y = -1;return i_j;}srand(time(NULL));count = -1;newxy = rand() % empty;//表示应在第几个空添加新元素,newxy从0开始for (i = 0; i < 4; (i)++) {for (j = 0; j < 4; (j)++) {if (a[i][j] == 0) {count++;if (count == newxy){i_j.x = i;i_j.y = j;return i_j;}}}}}

大笑