C语言控制台打砖块游戏实现原理与代码解析
本文展示如何使用C语言和二维数组在控制台环境中构建一个简单的“打砖块”互动程序。通过对网格状态的更新、连接性检测以及重力模拟,实现了基础的交互逻辑。
设计目标与准备条件
本示例旨在演示如何利用简单的数据结构和循环逻辑处理二维网格中的动态状态变化。主要涉及以下技术点:
- 数据存储:使用 10x10 的整型二维数组表示游戏地图。
- 视觉渲染:通过嵌套循环将数组状态转换为字符界面输出。
- 核心逻辑:包括用户坐标输入、指定位置破坏、未支撑砖块的掉落判定。
完整源代码
以下是完整的 C 语言源码,可直接在 Visual Studio 或 GCC 等环境中编译运行。请注意,`#include "stdafx.h"`为特定环境依赖,在非 VS 环境中可能需要移除。
#include <stdio.h>
#include <stdlib.h>
// 全局游戏地图数据:0-空, 1-稳固砖块, 3-悬浮待检测砖块
int a[10][10] = {
{ 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 0, 1, 1, 0 },
{ 0, 0, 0, 0, 1, 1, 0, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } };
void down(int a[10][10]) {
// 控制被标记为3的砖块向下落,直到碰到地面(第9行)或值为1的稳固方块
for (int i = 9; i >= 0; i--) {
for (int j = 0; j < 10; j++) {
if (a[i][j] == 3) {
int m = i, n = j;
while (a[m + 1][n] != 1 && m != 9) {
a[m + 1][n] = 1; // 落下的瞬间视为1,便于后续逻辑判断
a[m][n] = 0; // 原位置清空
m++;
}
}
}
}
}
void freshen(int a[10][10]) {
// 核心算法:检查砖块支撑关系
// 1. 将所有存在的砖块临时标记为3
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
if (a[i][j] == 1) a[i][j] = 3;
// 2. 边界修复:将与墙壁直接相连的部分重新赋值为稳固状态1
// 左墙
for (i = 0; i < 10; i++) {
j = 0;
while (a[i][j] != 0) { a[i][j] = 1; j++; }
}
// 右墙
for (i = 0; i < 10; i++) {
j = 9;
while (a[i][j] != 0) { a[i][j] = 1; j--; }
}
// 上墙
for (j = 0; j < 10; j++) {
i = 0;
while (a[i][j] != 0) { a[i][j] = 1; i++; }
}
// 下墙(地面)
for (j = 0; j < 10; j++) {
i = 9;
while (a[i][j] != 0) { a[i][j] = 1; i--; }
}
// 3. 连接传播:执行4次全图遍历,查找与稳固砖块相邻的3状态砖块
// 这一部分通过重复迭代来处理复杂的连通分量支撑问题
for (int round = 0; round < 4; round++) {
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
if (a[i][j] == 1) {
if (a[i - 1][j] == 3) a[i - 1][j] = 1;
else if (a[i + 1][j] == 3) a[i + 1][j] = 1;
else if (a[i][j - 1] == 3) a[i][j - 1] = 1;
else if (a[i][j + 1] == 3) a[i][j + 1] = 1;
}
}
}
}
}
void view(int a[10][10]) {
printf(" ");
for (int j = 0; j < 10; j++) printf("%d ", j);
printf("\n");
for (int i = 0; i < 10; i++) {
printf("%d: ", i);
for (int j = 0; j < 10; j++) {
if (a[i][j] == 1) printf("* ");
else printf(" ");
}
printf("\n");
}
}
void beat(int a[10][10], int i, int j) {
a[i][j] = 0;
}
int main() {
int p, q;
view(a);
// 允许进行18次操作
for (int w = 0; w < 18; w++) {
printf("请输入要打击的横坐标 p: ");
scanf_s("%d", &p);
printf("请输入要打击的纵坐标 q: ");
scanf_s("%d", &q);
beat(a, p, q);
freshen(a);
down(a);
view(a);
}
system("pause");
return 0;
}本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













