# GreedySnake
**Repository Path**: Erick0412/GreedySnake
## Basic Information
- **Project Name**: GreedySnake
- **Description**: 用C写的贪吃蛇小游戏。
- **Primary Language**: C
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-07-01
- **Last Updated**: 2025-12-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# **C语言贪吃蛇项目 - 技术学习文档**
**版本:** 1.14
**作者:** 小火龙Erick
**前言**
本篇文档旨在为C语言初学者提供一份详尽的“贪吃蛇”项目开发指南。通过学习本项目的实现,你将了解如何综合运用C语言基础知识,并结合特定的系统API,构建一个功能完整的控制台应用程序。文档将系统性地拆解项目的功能模块、技术选型与核心算法,帮助你理解代码背后的设计思想。
## 1. 项目功能概述 (Functionality Overview)
- **核心玩法**: 遵循经典的贪吃蛇规则,玩家通过键盘控制蛇的移动,吞食随机出现的食物以获得分数和长度增长。
- **图形化控制台界面**: 利用字符在控制台进行绘制,实现了包含游戏区域、墙壁、实时计分板和操作指南的图形用户界面 (GUI)。
- **实时交互与动态调速**: 通过 `↑ ↓ ← →` 方向键精确控制蛇的移动方向。支持在游戏过程中使用 `F1`/`F2` 键动态调整蛇的移动速度。
- **高分持久化存储**: 程序会自动记录并保存历史最高分。当玩家本次得分超过记录时,系统会进行提示并更新最高分记录。
- **完整的游戏流程管理**: 程序包含了从欢迎界面、游戏说明、主游戏循环、暂停机制到游戏结束界面的完整流程,提供了流畅的用户体验。
## 2. 技术实现方案 (Technical Implementation)
本项目基于标准的C语言,并依赖于Windows平台提供的特定头文件来实现图形、颜色及非阻塞输入等高级功能。
| 依赖头文件 | 主要功能 |
| --- | --- |
| `stdio.h` | 负责标准输入输出,如使用 `printf` 在屏幕上打印字符,以及通过 `fopen`, `fprintf`, `fscanf` 等函数进行文件读写(用于保存最高分)。 |
| `stdlib.h` | 提供多种通用功能函数。本项目中主要使用 `rand()` 生成随机数(用于食物定位)和 `system()` 执行系统命令(如 `system("cls")` 清屏)。 |
| `time.h` | 使用 `time()` 函数获取系统时间,并将其作为 `rand()` 函数的随机数种子,以确保每次游戏食物出现的位置具有不可预测性。 |
| `string.h` | 提供字符串处理函数,本项目使用 `strlen()` 来计算文本的显示长度,以实现精确的居中对齐。 |
| `windows.h` | **(关键知识点)** 提供了访问Windows API(应用程序接口)的能力,是实现图形化界面的核心。本项目主要使用了两个API函数:
- `SetConsoleCursorPosition(handle, coord)`: 将光标定位到控制台的任意(x, y)坐标。我们将其封装为 `gotoxy(x, y)` 函数,用于在指定位置绘制界面元素。
- `SetConsoleTextAttribute(handle, color)`: 设置后续从控制台输出文本的前景色和背景色,我们封装为 `setColor(color)` 函数,用于实现多彩界面。 |
| `conio.h` | **(关键知识点)** 提供了Windows平台下的控制台I/O功能。本项目主要使用了两个重要的非阻塞键盘输入函数:
- `_kbhit()`: 检测当前是否有键盘按键被按下。此函数会立即返回结果而不会导致程序阻塞,是实现流畅游戏循环的关键。
- `_getch()`: 在键盘有输入时,直接获取按键的ASCII码,无需用户按回车键确认。 |
**实现概要**:以C语言为基础,通过调用Windows API来增强控制台的表现力与交互性,从而构建一个动态、多彩的游戏环境。
## 3. 核心原理剖析 (Core Principles)
游戏的主体逻辑由一个名为 `gameLoop` 的函数驱动,其内部包含一个核心的 `while` 循环。在游戏运行期间,该循环不断执行,每一轮循环处理以下几个核心任务:
1. **处理用户输入 (`if (_kbhit())`)**: 检查键盘输入,若有,则根据按键更新蛇的移动方向,或执行暂停、调速等操作。
2. **更新游戏状态 (`moveSnake()`函数)**: 根据当前方向,计算并更新蛇的位置。这是游戏动画的核心。
3. **执行碰撞检测 (`checkCollision()`函数)**: 在蛇移动后,立即检测蛇头是否与墙壁或自身发生碰撞。
4. **控制游戏节奏 (`Sleep(speed)`)**: 在每轮循环末尾,使程序休眠一小段时间。休眠时长由 `speed` 变量控制,从而决定了蛇的移动速度。
下面,我们将深入探讨几个关键的设计要点:
### 3.1 动态数据结构——蛇的身体实现 (`SnakeNode` 结构体)
由于蛇的长度在游戏过程中是动态变化的,使用固定大小的数组来存储蛇的身体节点并不理想。因此,我们采用了一种更灵活的数据结构——**单向链表**。
我们定义了 `SnakeNode` 结构体来表示蛇的每一节身体:
```c
typedef struct SnakeNode {
int x, y; // 当前节点的坐标
struct SnakeNode* next; // 指向下一节点的指针
} SnakeNode;
```
`next` 指针是链表的精髓,它将所有 `SnakeNode` 节点串联起来,形成一个有序的序列。
**蛇头 -> 身体节点1 -> 身体节点2 -> ... -> 蛇尾 (其next指针为NULL)**
通过这种方式,我们仅需一个指向蛇头的指针 `snake`,便可以遍历并访问整条蛇。
### 3.2 蛇的移动逻辑:头增尾删法 (`moveSnake`函数)
蛇在屏幕上的移动效果,其底层实现并非整体平移,而是采用了一种高效的“头增尾删”算法:
1. **头增 (Head Insertion)**: 根据当前移动方向,在原蛇头的前方位置创建一个新的节点(新蛇头)。
2. **链接 (Linking)**: 将新蛇头节点的 `next` 指针指向旧的蛇头,并将全局的蛇头指针 `snake` 更新为指向这个新节点。
3. **判断与处理**: 检查新蛇头的坐标是否与食物重合。
- **吃到食物**: 如果重合,则**不执行删除蛇尾的操作**。这样,链表的总长度就增加了一节,实现了蛇身体的增长。随后,生成新的食物。
- **未吃到食物**: 为了维持蛇的长度不变,需要找到并删除链表的最后一个节点(蛇尾),并释放其占用的内存。
这个过程模拟了尺蠖的移动方式,实现了高效的位置更新。
### 3.3 碰撞检测机制 (`checkCollision`函数)
该函数是判定游戏是否结束的关键。它负责检测两种游戏失败的条件:
1. **撞墙检测**: 检查蛇头节点的坐标 `(x, y)` 是否超出了预设的墙壁边界。
2. **撞自身检测**: 从蛇头的下一个节点开始,遍历整个链表,检查是否存在某个身体节点的坐标与当前蛇头的坐标完全相同。如果存在,则判定为蛇头与身体碰撞。
### 3.4 内存管理:动态内存的释放 (`freeSnake`函数)
在C语言中,通过 `malloc()` 动态分配的内存必须由程序员手动使用 `free()` 释放,否则会导致**内存泄漏** (Memory Leak)。
`freeSnake` 函数承担了内存回收的职责。当游戏结束或重新开始时,该函数会被调用。它会从蛇头开始,沿着链表逐个释放所有 `SnakeNode` 节点所占用的内存。这是一种保证程序健壮性的重要编程实践。
## 4. 编译与运行指南 (Build & Run)
1. **环境要求**: Windows操作系统,并已安装C语言编译环境,如 Dev-C++ 或配置了MinGW的VSCode。
2. **保存文件**: 将源代码保存为 `.c` 格式的文件,例如 `snake.c`。
3. **编译命令**: 打开命令行终端(CMD或PowerShell),导航至文件所在目录,执行以下命令进行编译:
```bash
gcc snake.c -o snake.exe
```
4. **运行程序**: 编译成功后,当前目录下会生成 `snake.exe` 可执行文件。输入以下命令运行游戏:
```bash
.\snake.exe
```
## 5. 项目扩展方向 (Future Work)
本项目具备良好的扩展性,如果你希望进一步提升,可以考虑实现以下功能:
- **增加障碍物**: 在地图上随机或固定生成障碍物,蛇碰到障碍物同样会导致游戏结束。
- **功能性食物**: 设计不同类型的食物,例如:提供更高分数的食物、能短暂加速/减速的食物,或者能让蛇临时拥有特殊能力(如穿墙)的食物。
- **双人对战模式**: 实现支持两名玩家同时游戏的模式,增加了竞技性和复杂性。