基于 linux framebuffer 实现五子棋小游戏
项目简介五子棋作为经典双人博弈游戏本项目基于嵌入式Linux FrameBuffer帧缓冲设备使用纯C语言开发不依赖QT、GTK等第三方图形库直接对 /dev/fb0 进行内存映射操作显存完成像素级画面渲染。实现可视化棋盘绘制、方向键光标移动、交替落子、四向胜负判定、BMP图片弹窗结算完整游戏流程适合作为Linux嵌入式入门练手项目。传统的五子棋大多运行在桌面GUI或者命令行字符界面本项目直接操作底层显示设备在无桌面的嵌入式终端上运行占用CPU、内存资源很低完整感受Linux底层图形显示原理同时练习C语言数组、循环算法、Makefile工程编译等开发技能。开发环境- 系统嵌入式Linux虚拟机Linux也可运行- 编程语言C语言- 图形接口FrameBuffer /dev/fb0- 编译工具gcc Makefile- 输入交互终端键盘输入整体功能1. 棋盘绘制渲染绘制网格棋盘把二维数组的数据同步渲染到屏幕上黑白棋子实时刷新。2. 双人交替落子方向键控制光标移动定位落子点空格键确认落子黑白棋手回合自动切换禁止重复在同一位置落子。3. 胜负算法判定落子之后以最新落下的棋子为原点向横、竖、两条斜线四个方向统计连续同色棋子连续≥5颗即判定获胜。4. 游戏结算对局胜利后加载24位BMP图片弹窗展示胜利结果支持棋盘重置开启新一轮对局。核心实现思路1. 棋盘数据模型使用二维数组 int chess_g[15][15] 本项目使用15×15标准五子棋棋盘作为游戏的数据底层数据与显示分离。c0 → 空位1 → 白棋-1 → 黑棋屏幕上看到的棋盘画面全部由这个二维数组生成修改落子的时候只修改数组数值再调用绘图函数刷新屏幕。做到逻辑层和渲染层解耦。2. FrameBuffer底层绘图打开帧缓冲设备文件 /dev/fb0 通过 mmap 把显存映射到进程虚拟地址空间直接操作内存地址修改屏幕像素。封装了一系列绘图工具函数画直线、画实心矩形、画圆、清屏、绘制BMP图片。画圆函数用到 sin() 、 cos() 数学库编译链接时必须增加 ‑lm 链接数学库否则会出现未定义引用报错。3. 光标交互逻辑游戏主循环持续读取键盘输入。上下左右方向键修改光标逻辑坐标再换算成屏幕像素坐标绘制红色光标框标记落子位置按下空格执行落子逻辑。落子前做合法性校验不能落在已有棋子的位置不能超出棋盘边界。4. 胜负判断核心算法check_win优化点不需要遍历整个棋盘只检查刚刚落下的那一颗棋子效率更高。定义方向数组四组方向代表水平、竖直、两条斜线cint dir[4][2] {{0,1},{1,0},{1,1},{1,-1}};拿到刚落子的坐标 row、col 对每一组方向1. 向正方向循环统计连续同色棋子2. 再向反方向循环统计连续同色棋子3. 总数量 正向计数 反向计数 1棋子自身4. 如果计数≥5直接返回当前棋子颜色代表胜利全部方向遍历完毕没有满足条件则返回0继续游戏。这种四向辐射的算法避免扫描整张棋盘每一次落子后只做局部检索时间性能优秀。5. Makefile工程管理项目拆分多个源文件- main.c 程序入口- game.c 游戏主逻辑、光标、落子、游戏循环- check_win.c 五子棋胜负判定函数- framebuffer.c FrameBuffer初始化、所有绘图工具函数- game.h 宏定义、全局变量、函数声明头文件手写Makefile统一管理编译一次性编译全部 .c 文件链接数学库 ‑lm 支持 make clean 清理编译产物替代冗长的gcc手动编译命令练习小型C项目工程化。makefileOBJ a.outSRC main.c game.c check_win.c framebuffer.cCC gcc$(OBJ): $(SRC)$(CC) $(SRC) -o $(OBJ) -lmclean:rm -rf $(OBJ) *.o核心实现思路 关键代码示例1. 棋盘数据模型采用15×15二维数组作为游戏底层数据数据与显示分离修改数组再调用绘图函数刷新屏幕。c// game.h#define CHESS_EMPTY 0 //空位#define CHESS_WHITE 1 //白棋#define CHESS_BLACK -1 //黑棋#define BOARD_SIZE 15extern int chess_board[BOARD_SIZE][BOARD_SIZE];extern int turn; //当前下棋棋手extern int game_over; //游戏是否结束标记c// game.c 初始化棋盘void init_board(void){for(int i 0; i BOARD_SIZE; i){for(int j 0; j BOARD_SIZE; j){chess_board[i][j] CHESS_EMPTY;}}turn CHESS_WHITE; //开局白棋先行game_over 0;}2. FrameBuffer底层绘图framebuffer.c打开帧缓冲设备 mmap 映射显存直接操作内存修改屏幕像素封装基础绘图API。c#include stdio.h#include fcntl.h#include unistd.h#include sys/mman.h#include linux/fb.h#include sys/ioctl.h#include math.h#include game.hint fd_fb;struct fb_var_screeninfo vinfo;unsigned int *fb_mem;//初始化帧缓冲int init_fb(void){fd_fb open(/dev/fb0, O_RDWR);ioctl(fd_fb, FBIOGET_VSCREENINFO, vinfo);int screen_size vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;fb_mem mmap(NULL, screen_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_fb, 0);return 0;}//画一个像素点void draw_point(int x, int y, unsigned int color){if(x 0 || x vinfo.xres || y 0 || y vinfo.yres)return;fb_mem[y * vinfo.xres_virtual x] color;}//画水平线void draw_h_line(int x0, int y0, int len, unsigned int color){for(int i 0; i len; i){draw_point(x0 i, y0, color);}}//画圆绘制棋子用到sin、cos数学函数void draw_circle(int x0, int y0, int r, unsigned int color){for(int angle 0; angle 360; angle){double rad angle * 3.1415926 / 180;int x x0 r * cos(rad);int y y0 r * sin(rad);draw_point(x, y, color);}}⚠️注意 sin() 、 cos() 需要链接数学库Makefile需要增加 ‑lm 参数。3. 棋盘刷新函数示例读取二维数组循环绘制棋盘网格以及黑白棋子。cvoid show_chess_board(void){draw_clear(0x00D2B48C); //棋盘底色浅棕褐色//绘制棋盘网格线for(int i 0; i BOARD_SIZE; i){draw_h_line(40, 40 i*40, 14*40, 0x00000000);draw_v_line(40 i*40,40,14*40, 0x00000000);}//遍历数组绘制棋子for(int row 0; row BOARD_SIZE; row){for(int col 0; col BOARD_SIZE; col){int px_x 40 col *40;int px_y 40 row *40;if(chess_board[row][col] CHESS_WHITE){draw_circle(px_x, px_y,15, 0x00FFFFFF);}else if(chess_board[row][col] CHESS_BLACK){draw_circle(px_x, px_y,15, 0x00000000);}}}}4. 落子逻辑代码示例c//row col棋盘逻辑坐标int place_chess(int row, int col){//边界判断if(row 0 || row BOARD_SIZE || col 0 || col BOARD_SIZE)return -1;//该位置已经有棋子if(chess_board[row][col] ! CHESS_EMPTY)return -1;//落子chess_board[row][col] turn;return 0;}5. 胜负判定核心代码 check_win.c只检测刚刚落下的棋子向四个方向辐射统计不需要遍历整张棋盘效率更高。c#include game.hint check_win(int row, int col){int color chess_board[row][col];if(color CHESS_EMPTY)return 0;//4组方向水平、竖直、斜1、斜2int dir[4][2] {{0,1}, {1,0}, {1,1}, {1,-1}};for(int i 0; i 4; i){int dx dir[i][0];int dy dir[i][1];int cnt 1; //自己这颗棋子初始计数为1//正向延伸int r row dx;int c col dy;while(r 0 r BOARD_SIZE c 0 c BOARD_SIZE chess_board[r][c]color){cnt;r dx;c dy;}//反向延伸r row - dx;c col - dy;while(r 0 r BOARD_SIZE c 0 c BOARD_SIZE chess_board[r][c]color){cnt;r - dx;c - dy;}if(cnt 5){return color; //返回获胜棋子颜色}}return 0; //没有胜利}6. 游戏主循环片段 game.ccvoid begin_game(void){int cur_row 7;int cur_col 7;init_board();show_chess_board();while(!game_over){//绘制光标标记落子位置draw_cursor(cur_row, cur_col);int key getchar();switch(key){case w: cur_row--; break;case s: cur_row; break;case a: cur_col--; break;case d: cur_col; break;case :if(place_chess(cur_row,cur_col) 0){//落子成功判断胜负int ret check_win(cur_row, cur_col);if(ret ! 0){game_over 1;if(ret CHESS_WHITE){draw_bmp(win_white.bmp);}else{draw_bmp(win_black.bmp);}}//切换棋手turn -turn;show_chess_board();}break;}//坐标限制防止越界if(cur_row 0) cur_row 0;if(cur_row BOARD_SIZE) cur_row BOARD_SIZE-1;if(cur_col 0) cur_col 0;if(cur_col BOARD_SIZE) cur_col BOARD_SIZE-1;}}开发踩坑记录1. sin、cos未定义引用math.h 只是提供函数声明编译链接阶段需要追加 ‑lm 参数写在Makefile链接行末尾写在编译 .o 阶段不会生效。2. 胜负判定失效、输赢弹窗黑白颠倒- 计数变量 cnt 初始值要设置为1算上自己这颗棋子初始写0永远达不到五子。- 宏定义黑白棋数值不要写反落子、判赢、切换棋手的顺序不能颠倒正确顺序落子 → 判断胜利 → 切换棋手回合顺序错乱会出现棋手乱跳。- 数组越界while循环内必须增加棋盘边界判断访问超出数组下标会造成内存乱读胜负计数异常。3. undefined reference 未定义的函数引用头文件 #include 只是告诉编译器函数声明如果 .c 源文件没有加到Makefile的SRC编译列表链接器找不到函数实体直接报错。所有用到的c文件都需要参与编译。4. 坐标换算出错棋盘是逻辑坐标0‑14屏幕是像素坐标两套坐标要做好转换很容易出现光标错位、棋子画错位置。5. Makefile语法报错 missing separator规则下面执行命令的行开头必须是Tab不能用空格代替这是Makefile硬性语法。6. BMP图片显示异常必须使用24位真彩色BMP资源图片格式不对会花屏、黑屏图片路径写错无法加载胜利弹窗。项目收获1. 理解Linux FrameBuffer帧缓冲原理学会打开设备、mmap显存映射脱离GUI图形库直接操作屏幕像素搞懂嵌入式底层显示流程。2. 学会用二维数组抽象现实模型把游戏棋盘转化程序数据做到业务逻辑与界面渲染分离的编程思想。3. 练习算法实现把五子棋“五子连珠”的业务规则转化成可执行代码方向向量简化多方向遍历减少重复代码。4. C语言工程化实践项目拆分多 .c 多头文件头文件声明、源文件实现熟练使用Makefile管理多文件项目编译。5. 调试排错能力遇到链接报错、逻辑bug使用打印变量值定位断点解决数组越界、时序逻辑错误等典型问题。后续可优化方向1. 增加简单AI人机对战模式代替双人对战。2. 增加悔棋功能使用栈保存历史落子记录。3. 增加棋盘满盘平局判断。4. 优化输入替换阻塞的getchar实现非阻塞键盘读取。5. 界面美化增加棋盘背景、棋子抗锯齿效果。这个项目非常适合嵌入式Linux入门不追求炫酷界面重在理解底层设备操作、C语言工程组织、简单游戏算法是把课本C语言知识落地的小型综合实战。

相关新闻

字节面试题:多智能体(Multi-Agent)是什么?团队作战AI,小白也能学会

字节面试题:多智能体(Multi-Agent)是什么?团队作战AI,小白也能学会

本文以字节面试题“什么是Multi-Agent?”为切入点,用通俗易懂的语言解释了多智能体系统的概念,即多个Agent分工协作完成任务。文章指出单个Agent受限于context窗口大小和专业度,而Multi-Agent通过专业分工和并行执行,能…

2026/10/10 14:53:49 阅读更多 →
Linux 终端命令速查表 --10 JSON 速查表

Linux 终端命令速查表 --10 JSON 速查表

简介 jq 是标准的命令行 JSON 处理器:它从文件或标准输入读取 JSON,应用过滤器,然后打印结果。最简单的过滤器 . 仅用于美化打印。 jq "." file.json curl -s https://api.github.com/users/torvalds | jq "." echo {"name": "Linux&q…

2026/10/9 19:46:11 阅读更多 →
一次 CDN 厂商切换引发的血案:从华为云到火山引擎的 gzip 填坑实录

一次 CDN 厂商切换引发的血案:从华为云到火山引擎的 gzip 填坑实录

标签:CDN 运维排障 日期:2026-08-12 阅读时长:约 10 分钟 声明:本文所有域名、IP、路径均已脱敏,仅为排查过程演示。 一、问题现象:切完 CDN 后资源下载全线失败 某游戏资源 CDN 域名(下称 cdn-game.example.com)从华为云切到火山引擎后,Android 客户端在下载热更资…

2026/10/5 19:07:15 阅读更多 →

最新新闻

WinSxS文件夹清理指南:用DISM安全释放系统盘空间

WinSxS文件夹清理指南:用DISM安全释放系统盘空间

1. 先搞清楚 WinSxS 到底是个什么东西很多人第一次打开C:\Windows\WinSxS这个文件夹,看到属性里显示十几个 G,甚至二十几个 G,第一反应就是:这玩意儿是不是垃圾?能不能直接删掉腾空间?我当年也是这么想的&a…

2026/10/10 14:54:00 阅读更多 →
Kettle(PDI)安装配置完全指南:版本匹配与避坑实践

Kettle(PDI)安装配置完全指南:版本匹配与避坑实践

简介:面向数据集成初学者、数据分析师及需要快速搭建ETL环境的开发人员,这是一份以Pentaho Data Integration(PDI)下载安装与基础配置为核心的PDF速查教程。Kettle作为开源ETL工具,常用于多平台数据抽取、转换与加载&a…

2026/10/10 14:54:00 阅读更多 →
Clude安装流程全解析:四步跑通本地AI命令行工作台

Clude安装流程全解析:四步跑通本地AI命令行工作台

前阵子有个朋友跑来问我,说手里的AI工具一直停留在网页聊天框的阶段,想要找个能接进本地工作流的方式,问我有没有推荐的方案。我直接丢给他一款叫Clude的开源个人AI工作台——它跟那种只能在浏览器里对话的产品不太一样,装好之后你…

2026/10/10 14:54:00 阅读更多 →
Kettle(PDI)安装与启动实战:从下载到跑通第一个转换

Kettle(PDI)安装与启动实战:从下载到跑通第一个转换

简介:Kettle(Pentaho Data Integration,简称 PDI)是一款开源 ETL 工具,面向需要进行数据抽取、转换与加载的开发者,重点解决该工具在 Windows、Linux、macOS 等平台下的获取、安装与基础配置难题。资料以单…

2026/10/10 14:54:00 阅读更多 →
AIRI 浏览器本地语音识别(Browser Local ASR/STT):当前状态、WIP 占位实现与可用替代方案

AIRI 浏览器本地语音识别(Browser Local ASR/STT):当前状态、WIP 占位实现与可用替代方案

AI 应用人工智能大模型数字人AI Agent语音前端后端 【免费下载链接】airi 💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capa…

2026/10/10 14:54:00 阅读更多 →
统一登录与单点登录实战:网关与认证中心的搭建全解

统一登录与单点登录实战:网关与认证中心的搭建全解

这段时间我一直在折腾一件事:把我们内部几个各自为战的业务系统,统一到一个登录入口底下。项目代号倒是很形象,sward 负责守门,soular 负责认人。说白了,sward 是一个网关层,soular 是一个身份认证中心&…

2026/10/10 14:52:58 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →