前期准备:
使用软件:vscode
使用函数库:ncurses
安装ncurses
绘图库
sudo apt-get install libncurses5-dev
设计思路
要实现 2048 游戏目前有两个关键点:
- 在满足条件情况下消除方块
- 允许在游戏主界面(16 宫格)中任意一格输出数据
其中第二点借助 ncurses
库可以较容易实现,但是第一点要稍微麻烦些。
第一点的实现思路是,我们创建一个与游戏地图相同维数的数组矩阵,通过数组矩阵来维护 2048 游戏中每个格子的数据与状态,从而玩家的移动操作都可以映射为对数组矩阵的操作。
绘制窗格
添加需要的头文件和全局变量
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <unistd.h>
#include <time.h>
void init(void);//初始化
void draw_grid(void);//绘制窗格(游戏界面)
void draw_one(int x, int y);//绘制单个数字 传入数组的坐标
void play(void);//游戏运行
int cnt_one(int x, int y);
void cnt_value(int* new_x,int* new_y);
int game_over(void);//游戏结束
int board[4][4] = {
0};//用来充当棋盘 4*4 16宫格 0表示空格子
int empty;//用来标记剩余空格子的数量(标记是否有相同的数字合并 有则+1)
int old_x, old_y;//用来标记避免在同一位置生成新数字
绘制5行横线,每行由21个-
组成;绘制5列竖线,每列由7个|
组成;
//绘制窗格
void draw_grid(void){
int m, n, x, y;
clear();//将整个屏幕清除
//绘制横线 m行 n列
for(m = 0; m < 9; m += 2){
for(n = 0; n < 21; n++){
move(m,n);//将光标移动至 m,n 的位置.
addch('-');//在当前光标位置输入单个字符,并将光标右移一位。
refresh();//刷新屏幕,使绘制即时生效
}
}
//绘制竖线
for (n = 0; n < 22; n += 5){
for(m = 1; m < 8; m++){
move(m,n);
addch('|');
refresh();
}
}
//绘制数组中的全部数字
for (x = 0; x < 4; x++){
for(y = 0; y < 4; y++)
draw_one(x, y);//绘制单个数字
}
}
//绘制单个数字
void draw_one(int x, int y){
int i, k, j, m=0;
char c[5] = {
0x00};
i = board[x][y];
while(i > 0){
j = i % 10;//取出个位
c[m++] = j + '0';//将数字转化为字符型
i = i / 10;//去掉个位,剩下的继续循环 依次转化为字符型 c[5]倒序存入数字
}
m=0;
k=(y + 1) * 5 - 1;
while(c[m] != 0x00){
move(2*x+1, k);//移动光标到格子中
addch(c[m++]);//将字符取出画在屏幕上 并m++移到下一位字符
k--;//使画出的数字变为正序
}
}
//初始化
void init(void){
int x, y;
initscr();//开启 curses 模式
cbreak();//开启后, 除了 DELETE 或 CTRL 等仍被视为特殊控制字元外一切输入的字元将立刻被一一读取
noecho