# 系统设计

## 1. 总体设计

本工程采用前后端分离的设计模式，将后端与前端分离从而方便分工并保证程序的逻辑清晰。

## 前后端约定

规定整个程序的全局变量如下：

`char map[][]` 储存地图情况，用0表示空格 1表示蛇 2表示果子。

`int map_len` 表示地图的边长。

`int head_x` 表示蛇头x坐标。

`int head_y` 表示蛇头y坐标。

`int scoer` 表示玩家目前得分。

全局变量还包括一条链表，节点为node类，用来储存蛇身信息。

## 前端

前端负责编写main函数，控制开始界面和地图的定时刷新，渲染地图的实时效果，处理用户的输入与后端的交互。

（1）游戏开始：开始界面的美化；用户输入地图大小，并用while+if判断用户输入的地图大小是否合理（限制在10\~100以内），并提示过大/过小；

（2）主体：使用`Sleep`以及`system("cls")`达到不断刷新界面的目的，模拟蛇的移动；调用来自后端的move()，传入用户控制的方向，并将move返回值作为游戏是否继续的判断（move会返回0和1，while(1)则循环继续）

（3）游戏结束：询问用户是否再玩一次，或者是否查看排行榜（调用跟排行榜相关的函数）

## 后端

后端负责编写游戏的运行逻辑，处理用户输入后的数据分析等等。

* `int move(char c)` 函数

  由前端调用，每帧调用一次，是蛇移动的主要逻辑。

  返回值含义：

  0：游戏结束

  1：正常进行

  参数：经前端处理过的控制指令，为'w'/'a'/'s'/'d'。
* `int judge(int x, int y)` 函数

  判断蛇是否咬到身体或者撞墙或吃到果子。

  参数：

  x：欲判断格子的x坐标

  y：欲判断格子的y坐标

  返回值含义：

  0：目标格子为空，可正常继续；

  1：蛇撞墙或撞到自己，游戏结束；

  2：蛇吃到果子。
* `void generate_fruit()` 函数

  随机生成一个果子。

## 2.模块设计

### `move()` 函数

伪代码表示如下：

```c
int move(char c){
    int target_x = 计算目标x坐标(c,now_x)
    int target_y = 计算目标y坐标(c,now_y)    
    int status = judge(target_x, target_y)
    if(status == 1){
        return 0;
    }    
    链表.在首位置添加节点(target_x,target_y)
    if(status == 2){
        score += 5
        generate_fruit()
    }else{
        int tmp_x = 链表.取末位置节点x
        int tmp_y = 链表.取末位置节点y    
        链表.删除末位置节点()
        map[tmp_x][tmp_y] = 0
    }
    head_x = target_x
    head_y = target_y
    map[x][y] = 1;
    return 1;
}
```

### `judge()`函数
