2048_C_code

用C语言编写的2048

1

要实现我们的 2048 小游戏,需要涉及一些数据结构的知识,以及一些 Linux 的系统调用。此外,为了方便在屏幕上使用字符绘图,我们还需要使用一个文本界面的屏幕绘图库 ncurses ,具体到操作就是在编译的时候需要加上 -lcurses 选项。
安装ncurses库:
sudo apt-get install libncurses5-dev

设计思路

要实现 2048 游戏目前有两个关键点:

  1. 在满足条件情况下消除方块
  2. 允许在游戏主界面(16 宫格)中任意一格输出数据
    其中第二点借助 ncurses 库可以较容易实现,但是第一点要稍微麻烦些。第一点的实现思路是,我们创建一个与游戏地图相同维数的数组矩阵,通过数组矩阵来维护 2048 游戏中每个格子的数据与状态,从而玩家的移动操作都可以映射为对数组矩阵的操作。

基础工作

  1. 引头文件
    编写自己的头文件head.h。
    添加库函数头文件:
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
  1. 创建函数
void draw(); //用于绘制游戏界面
void play(); //游戏运行的逻辑主体
void init(); //初始化函数,用于完成一些必要的初始化操作
void draw_one(int y, int x); //绘制单个数字
void cnt_value(int *new_y, int *new_x);
int game_over(); //结束游戏
int cnt_one(int y, int x);
  1. 编写函数
    创建函数文件head.c。
    添加函数的内容。
#include "head.h"
int a[4][4] = {0};
int empty;
int old_y, old_x;
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);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 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] = 1;move = 1;}}}break;case 100:   //右移 dcase 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:   //下移 scase 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();}
}
void init()
{int x, y;initscr();cbreak();noecho();curs_set(0);empty = 15;srand(time(0));x = rand() % 4;y = rand() % 4;a[y][x] = 2;draw();
}
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 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++){// 如果(y, 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);endwin();exit(0);
}
int cnt_one(int y, int x)
{int value = 0;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;}
  1. 编写主函数game_2048.c
#include "head.h"
int main()
{init();play();endwin();return 0;
}
  1. 编写makefile文件
test:game_2048.o head.ogcc game_2048.o head.o -o test -lcurses
game_2048.o:game_2048.cgcc -c -Wall game_2048.c -o game_2048.o -lcurses
head.o:head.cgcc -c -Wall head.c -o head.o -lcurses.PHONY:clean
clean:rm *.o test
  1. 编译
    make
  2. 结果

    [外链图片转存失败(img-NpvIMnir-1565955275134)(picture/2.png)]

2

也可以用Game_2048.c一个文件进行编译

gcc Game_2048.c -o 2048 -lcurses


代码地址:
Github地址
参考:

实验楼->C 语言制作 2048
C 语言制作 2048

用C语言编写2048游戏相关推荐

  1. 2048游戏c语言linux简易代码,C语言实现2048游戏代码

    本文实例为大家分享了C语言实现2048游戏具体代码,供大家参考,具体内容如下 效果图: 使用文本界面的屏幕绘图库 ncurses. 设计思路: 在满足条件情况下消除方块 允许在游戏主界面(16 宫格) ...

  2. 用c语言编写的打字母游戏,用C语言编写小游戏——“井字棋”

    原标题:用C语言编写小游戏--"井字棋" 作者:Milo Yip 来源:知乎 原文链接:https://zhuanlan.zhihu.com/p/39581573 在 Milo Y ...

  3. C语言编写扫雷游戏,超简单

    C语言编写扫雷游戏,超简单 1.扫雷游戏的流程 2.代码编写 3.总结 通过学习C语言的基础知识,基本上是理解了大部分内容,现在就通过所学的知识,写个简单的扫雷游戏,加深对基础知识的理解,正所谓实践是 ...

  4. 如何用c语言编写军旗游戏

    今天教大家如何用C语言编写军旗游戏 ~ 1.效果图: 2.主要代码: #include <graphics.h> #include <time.h>#define CHESIZ ...

  5. C语言编写2048小游戏

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/104992424 2 ...

  6. C语言实现2048游戏(Windows版)

    本文是Windows版的C语言实现2048小游戏,嵌入式版的请移步 C语言实现2048小游戏-粤嵌GE6818嵌入式系统实训 C语言实现电子音乐相册-粤嵌GE6818嵌入式系统实训 一.游戏介绍 所谓 ...

  7. 【C++FunCode】基于Funcode使用C++语言编写小游戏(小鲨鱼历险记)

    一.前言 大一暑假参加了山东省软件设计大赛,基于FunCode平台使用C++语言编写了大鱼吃小鱼游戏,其美名曰小鲨鱼历险记,哈哈.比赛成绩惨烈,只拿了一个省三,赛后也进行了分析总结,主要还是太不重视比 ...

  8. 用c语言编写最大最小值_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

  9. c++扫雷游戏代码_C语言学习教程,用C语言编写扫雷游戏

    本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...

最新文章

  1. 20145317《网络对抗》shellcode注入Return-to-libc攻击深入
  2. Micropython TPYBoard v102 自动浇花实验
  3. 章磊回答: 姚期智提出的百万富翁难题被破解? 多方安全计算MPC到底是个什么鬼?
  4. 百度搜索打不开第二页_如何查询百度关键词精准收录位置以及收录量(附代码)...
  5. numpy 创建加一行_数据科学|可视化图解Python科学计算包Numpy
  6. zuul在zuulFilter获取返回值后,接口获取不到数据
  7. 基于HLS流媒体协议的视频加密方案
  8. python中组合与继承的区别_python类与对象的组合与继承
  9. POJ 1745 Divisibility DP
  10. 程序员面试金典 - 面试题 03.06. 动物收容所(队列)
  11. python import os.path_Python常用模块os.path——文件及路径操作
  12. 一男子蒙冤入狱10天,竟是 AI 认错了!
  13. 28天肝完阿里面试通关宝典,含答案解析
  14. mysql 内连接、自然连接、外连接的区别
  15. 文本特征提取之TF-IDF算法(原理+Python代码)
  16. python网课 知乎_如何看待风变编程的 Python 网课
  17. 可以边下边看的BT资源搜索下载工具:Tribler免费版
  18. 人工智能AI实训平台
  19. nian shi ti是什么鬼????
  20. 北风网课程开放下载第一季

热门文章

  1. 200smart_PLC如何实现可调频率可调占空比PWM输出
  2. html5 boilerplate 教程,HTML5 Boilerplate
  3. 华为手机用计算机怎么充电,华为手机怎么关闭充电声音怎么办
  4. 华容道的求解算法重写
  5. verilog编写RoundRobinArbiter的一些小错误摘录
  6. hypermill五轴再加工_【秒杀】hyperMILL2018三四五轴基础到高级编程视频教程,带你快速熟悉五轴编程...
  7. linux服务器上执行 rm -rf/*
  8. 计算机毕业设计Springboot+vue的宠物销售商城网站(源码+系统+mysql数据库+Lw文档)
  9. linux设备文件,Linux 文件系统与设备文件
  10. 暴强人工智能加持的音频人声/伴奏提取工具