c语言实现2048

来源:互联网 发布:淘宝客服外包协议 编辑:程序博客网 时间:2024/04/28 21:50

效果图:

此处输入图片的描述


使用文本界面的屏幕绘图库 ncurses.

设计思路:

  1. 在满足条件情况下消除方块
  2. 允许在游戏主界面(16 宫格)中任意一格输出数据
实现代码:
#include <stdio.h>#include <stdlib.h>#include <curses.h>#include <unistd.h>#include <signal.h>#include <time.h>void draw();  // 用于绘制游戏界面void play();  // 游戏运行的逻辑主体void init();  // 初始化函数,用于完成一些必要的初始化操作void draw_one(int y, int x);  // 绘制单个数字void cnt_value(int *new_y, int *new_x);  //统计(y, x)对应的格子周围一圈的空格的个数int game_over();  // 结束游戏int cnt_one(int y, int x);  //统计(y, x)对应的格子周围一圈的空格的个数// 游戏主界面是一个 4*4 的 16 宫格,使用二维数组进行表示,用 0 表示空格int a[4][4] = { 0 };// 16 宫格中空格的个数int empty;int old_y, old_x;int main(){init();play();endwin();return 0;}void init(){int x, y;initscr(); //开启curses模式cbreak(); //开启cbreak模式,除 DELETE 或 CTRL 等仍被视为特殊控制字元外一切输入的字元将立刻被一一读取noecho();  //echo() and noecho(): 此函式用来控制从键盘输入字元时是否将字元显示在终端机上curs_set(0); //设置光标模式empty = 15;srand(time(0));x = rand() % 4;y = rand() % 4;a[y][x] = 2;draw();}void draw(){int n, m, x, y;char c[4] = {'0', '0', '0', '0'};clear(); //清除终端屏幕for(n = 0; n < 9; n += 2){for(m = 0; m < 21; m++){move(n, m);//将游标移动至 x,y 的位置addch('-');//在当前位置画字符'-'refresh();//将做清除萤幕的工作}}for(m = 0; m < 22; m += 5){for(n = 1; n < 8; n++){move(n, m);addch('|');refresh();}}for(y = 0; y < 4; y++){for(x = 0; x < 4; x++){draw_one(y, x);}}}void draw_one(int y, int x){int i, m, k, j;char c[5] = {0x00};i = a[y][x];m = 0;while(i > 0){j = i % 10;c[m++] = j + '0';i = i / 10;}m = 0;k = (x + 1) * 5 - 1;while(c[m] != 0x00){move(2 * y + 1, k);addch(c[m++]);k--;}}void play(){int x, y, i, new_x, new_y, temp;int old_empty, move;char ch;while(1){move = 0;old_empty = empty;ch = getch();switch(ch){case 97:  //左移  acase 104: // hcase 68:  // 左移方向键for(y = 0; y < 4; y++)for(x = 0; x < 4; ){if(a[y][x] == 0){x++;continue;}else{for(i = x + 1; i < 4; i++){if(a[y][i] == 0){continue;}else{if(a[y][x] == a[y][i]){a[y][x] += a[y][i];a[y][i] = 0;empty++;break;}else{break;}}}x = i;}}for(y = 0; y < 4; y++)for(x = 0; x < 4; x++){if(a[y][x] == 0){continue;}else{for(i = x; (i > 0) && (a[y][i - 1] == 0); i--){a[y][i - 1] = a[y][i];a[y][i] = 0;move = 1;}}}break;case 100:  //右移 d case 108:  // lcase 67:   //右移方向键for(y = 0; y < 4; y++)for(x = 3; x >= 0; ){if(a[y][x] == 0){x--;continue;}else{for(i = x - 1; i >= 0; i--){if(a[y][i] == 0){continue;}else if(a[y][x] == a[y][i]){a[y][x] += a[y][i];a[y][i] = 0;empty++;break;}else{break;}}x = i;}}for(y = 0; y < 4; y++)for(x = 3; x >= 0; x--){if(a[y][x] == 0){continue;}else{for(i = x; (i < 3) && (a[y][i + 1] == 0); i++){a[y][i + 1] = a[y][i];a[y][i] = 0;move = 1;}}}break;case 119:  //上移 wcase 107:  //kcase 65:   //上移方向键for(x = 0; x < 4; x++)for(y = 0; y < 4; ){if(a[y][x] == 0){y++;continue;}else{for(i = y + 1; i < 4; i++){if(a[i][x] == 0){continue;}else if(a[y][x] == a[i][x]){a[y][x] += a[i][x];a[i][x] = 0;empty++;break;}else{break;}}y = i;}}for(x = 0; x < 4; x++)for(y = 0; y < 4; y++){if(a[y][x] == 0){continue;}else{for(i = y; (i > 0) && (a[i - 1][x] == 0); i--){a[i - 1][x] = a[i][x];a[i][x] = 0;move = 1;}}}break;case 115:  //下移 s case 106:  //jcase 66:   //下移方向键for(x = 0; x < 4; x++)for(y = 3; y >= 0; ){if(a[y][x] == 0){y--;continue;}else{for(i = y - 1; i >= 0; i--){if(a[i][x] == 0){continue;}else if(a[y][x] == a[i][x]){a[y][x] += a[i][x];a[i][x] = 0;empty++;break;}else{break;}}y = i;}}for(x = 0; x < 4; x++)for(y = 3; y >= 0; y--){if(a[y][x] == 0){continue;}else{for(i = y; (i < 3) && (a[i + 1][x] == 0); i++){a[i + 1][x] = a[i][x];a[i][x] = 0;move = 1;}}}break;case 'Q':case 'q':game_over();break;default:continue;break;}if(empty <= 0)game_over();if((empty != old_empty) || (move == 1)){do{new_x = rand() % 4;new_y = rand() % 4;}while(a[new_y][new_x] != 0);cnt_value(&new_y, &new_x);do{temp = rand() % 4;}while(temp == 0 || temp == 2);a[new_y][new_x] = temp + 1;empty--;}draw();}}int cnt_one(int y, int x){int value = 1;if(y - 1 > 0)a[y - 1][x] ? 0 : value++;if(y + 1 < 4)a[y + 1][x] ? 0 : value++;if(x - 1 >= 0)a[y][x - 1] ? 0 : value++;if(x + 1 < 4)a[y][x + 1] ? 0 : value++;if(y - 1 >= 0 && x - 1 >= 0)a[y - 1][x - 1] ? 0 : value++;if(y - 1 >= 0 && x + 1 < 4)a[y - 1][x + 1] ? 0 : value++;if(y + 1 < 4 && x - 1 >= 0)a[y + 1][x - 1] ? 0 : value++;if(y + 1 < 4 && x + 1 < 4)a[y + 1][x + 1] ? 0 : value++;return value;}void cnt_value(int *new_y, int *new_x){int max_x, max_y, x, y, value;int max = 0;max = cnt_one(*new_y, *new_x);for(y = 0; y < 4; y++)for(x = 0; x < 4; x++){if(!a[y][x]){value = cnt_one(y, x);if(value > max && old_y != y && old_x != x){*new_y = y;*new_x = x;old_x = x;old_y = y;break;}}}}int game_over(){sleep(1); //暂停1秒endwin(); //关闭curses并重置tty(结束curses编程时,最后调用的一个函数)exit(0);}

参考:实验楼

0 0
原创粉丝点击