当前位置:首页>Linux>C 语言在 Linux 控制台实现一个开心消消乐

C 语言在 Linux 控制台实现一个开心消消乐

  • 2026-10-11 07:32:10
C 语言在 Linux 控制台实现一个开心消消乐
先看效果
一、项目目标

我们这次要实现的是一个 Linux 控制台版 V1 原型,功能包括:

  • 固定大小二维棋盘

  • 随机生成初始棋盘,且没有初始三连

  • 控制台打印棋盘

  • 给每个格子标记索引,用户通过索引交换方块

  • 仅允许交换相邻方块

  • 支持横向三连及以上检测

  • 支持纵向三连及以上检测

  • 支持同时多处消除

  • 支持消除后清空格子

  • 支持重力下落

  • 支持顶部随机补块

  • 支持自动连锁消除

  • 支持多轮连续操作

  • 支持输入 q 退出程序

这篇文章讲解的是“核心玩法逻辑”,不包含:

  • 图形界面

  • 鼠标操作

  • 动画特效

  • 音效

  • 特殊方块

  • 分数系统

  • 关卡系统

二、棋盘应该怎么表示

这个项目最核心的数据结构就是棋盘。

我们使用一个二维数组表示它:

int board[ROWS][COLS];

比如定义一个 8x8 棋盘:

#define ROWS 8#define COLS 8

每个格子里存一个整数:

  • 1 ~ 5:表示 5 种不同类型的方块

  • 0:表示空格子

三、给每个格子编号,方便玩家输入

因为我们现在还没有鼠标点击操作,所以让用户直接输入“行列坐标”会稍微麻烦。 更简单的方法是:

给每个格子分配一个一维索引。

例如 8x8 棋盘,共有 64 个格子,索引范围就是:

0 ~ 63

索引和二维坐标的转换公式是:

row = index / COLS;col = index % COLS;

例如:

  • index = 10

  • row = 10 / 8 = 1

  • col = 10 % 8 = 2

所以索引 10 对应的是第 1 行第 2 列。

我们还会在控制台打印出类似这样的内容:

[12:3]

它的含义是:

  • 这个格子的索引是 12

  • 它当前的方块类型是 3

这样玩家就可以输入:

12 13

表示交换索引 12 和索引 13 的方块。

四、交换规则怎么实现

玩家输入两个索引之后,我们先要判断两件事:

第一,这两个索引是否合法。 第二,这两个格子是否相邻。

合法索引的判断很简单:

index >= 0 && index < ROWS * COLS

相邻则只允许两种情况:

  • 同一行,列差为 1

  • 同一列,行差为 1

也就是说,只有上下左右可以交换,斜着不行。

五、如何检测三连

我们的目标是找出所有满足以下条件的格子:

  • 横向连续 3 个及以上相同

  • 纵向连续 3 个及以上相同

注意,不是只找一处,而是:

一次扫描要找出整个棋盘上所有可消除的位置。

为此,我们引入另一个二维数组:

int marks[ROWS][COLS];

它的作用是“标记哪些位置应该被消除”。

规则是:

  • marks[r][c] = 1:这个格子要消除

  • marks[r][c] = 0:这个格子不消除


1. 横向扫描思路

以每一行为单位,从左往右扫描。 找到一段连续相同数字的区间。

例如某一行:

2 2 2 4 5 5 5 5

那么:

  • 前面 2 2 2 是一段长度为 3 的连续区间

  • 后面 5 5 5 5 是一段长度为 4 的连续区间

只要长度大于等于 3,就把整段都标记为 1。


2. 纵向扫描思路

纵向扫描和横向扫描完全类似,只是把“行”和“列”交换一下。

例如某一列:

33312

前 3 个格子组成纵向三连,那么把它们在 marks 中标记出来。


3. 为什么要先标记,再统一消除

一边扫描,一边直接把匹配位置清空。

这样容易导致问题,因为一旦你提前把某个位置改成 0,后续扫描的结果就会受到影响。

正确做法是分两步:

第一步:只负责“找出所有该消除的位置”,写入 marks。 第二步:根据 marks 统一执行消除。

六、如何执行消除

当 marks 标记完成后,消除就很简单了。

遍历整个棋盘:

  • 如果 marks[r][c] == 1

  • 就把 board[r][c] = EMPTY

七、重力下落是怎么实现的

这是整个项目里另一个很有代表性的算法。

当某些格子被消除后,棋盘里会出现空位。 这时每一列都要执行“方块向下掉落”。

例如一列数据可能原本是:

10302

下落之后应该变成:

00132

也就是说:

  • 所有非空方块向下集中

  • 空位集中到顶部

八、顶部补块怎么实现

下落之后,棋盘顶部会留下空位。 为了让棋盘重新填满,我们只需要遍历整个棋盘:

  • 如果某个位置是 EMPTY

  • 就生成一个新的随机方块

九、什么是自动连锁

三消游戏最有趣的地方之一,就是“连锁”。

意思是:

  • 你交换一次方块,触发第一轮消除

  • 第一轮消除后,方块下落

  • 下落后又形成了新的三连

  • 又触发第二轮消除

  • 补块后可能还会继续形成第三轮……

这种连续自动触发的消除,就叫连锁。

十 源码
game.c
main.c

最新文章

随机文章