WillKen's Blog.

字符游戏-智能蛇

Word count: 980Reading time: 4 min
2017/12/27 Share

字符游戏-智能蛇

  智能蛇是字符串版贪吃蛇的升级版。在这篇文章中,我将记录我的学习过程,起到同大家分享、交流的目的。
  本次项目的任务是让蛇有一定的智能,能通过算法具有 “感知 - 决策 - 行动” 的能力。开发环境为Linux。

这里写图片描述

  在编写前,首先要掌握如何在终端上实现清屏。在字符终端上完成“清屏”“修改光标位置”“设置字符前景和背景色”等操作,是通过输出 esc序列实现的。对于 VT100 终端, printf(“\033[2J”) 就实现了清屏。详细内容参见, C语言与VT100控制码编程
  其次,我们需要实现 kbhit()。这对我们初学者来说较难,好在老师给出了参考代码,我们只需将自己的代码融入其中就OK。代码来源:Linux下非阻塞地检测键盘输入的方法 (整理)

  明确智能蛇程序设计框架(伪代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
输出字符矩阵
WHILE not 游戏结束 DO
wait(time)
ch=whereGoNext(Hx,Hy,Fx,Fy)
CASE ch DO
‘A’:左前进一步,break
‘D’:右前进一步,break
‘W’:上前进一步,break
‘S’:下前进一步,break
END CASE
输出字符矩阵
END WHILE
输出 Game Over!!!

  接下来,最重要的就是设计蛇智能运行的算法了。

伪代码:

1
2
3
4
5
6
7
8
9
10
11
// Hx,Hy: 头的位置
// Fx,Fy:食物的位置
function whereGoNext(Hx,Hy,Fx,Fy) {
// 用数组movable[3]={“a”,”d”,”w”,”s”} 记录可走的方向
// 用数组distance[3]={0,0,0,0} 记录离食物的距离
// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
// 例如:假设输入”a” 则distance[0] = |Fx – (Hx-1)| + |Fy – Hy|
// 如果 Hx-1,Hy 位置不是Blank,则 distance[0] = 9999
// 选择distance中存最小距离的下标p,注意最小距离不能是9999
// 返回 movable[p]
}

C语言实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
char whereGoNext(int Hx,int Hy,int Fx,int Fy)
{
char moveable[4] = { 'a','d','w','s' };// 用数组movable[3]={“a”,”d”,”w”,”s”} 记录可走的方向
int distance[4]={0};// 用数组distance[3]={0,0,0,0} 记录离食物的距离
distance[0] = abs(Fy - Hy) + abs(Fx - Hx+1);// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
if (map[Hy][Hx-1] !=BLANK_CELL&&map[Hy][Hx-1] != SNAKE_FOOD)
distance[0] = 9999;// 如果 Hy,Hx-1 位置不是Blank,则 distance[0] = 9999

distance[1] = abs(Fy - Hy) + abs(Fx -Hx-1) ;// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
if (map[Hy][Hx+1] != BLANK_CELL&&map[Hy][Hx+1] != SNAKE_FOOD)
distance[1] = 9999;// 如果 Hy,Hx+1 位置不是Blank,则 distance[0] = 9999

distance[2] = abs(Fy - Hy+1) + abs(Fx - Hx) ;// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
if (map[Hy-1][Hx] != BLANK_CELL&&map[Hy-1][Hx]!=SNAKE_FOOD)
distance[2] = 9999;// 如果 Hy-1,Hx 位置不是Blank,则 distance[0] = 9999

distance[3] = abs(Fy - Hy-1) + abs(Fx -Hx) ;// 分别计算蛇头周边四个位置到食物的距离。H头的位置,F食物位置
if (map[Hy+1][Hx] != BLANK_CELL&&map[Hy+1][Hx] != SNAKE_FOOD)
distance[3] = 9999;// 如果 Hy+1,Hx 位置不是Blank,则 distance[0] = 9999

// 选择distance中存最小距离的下标p,注意最小距离不能是9999
int min=0;
for (int i = 0; i <= 3; i++)
{
if (distance[i] < distance[min] && distance[i] != 9999)
min = i;
}
return moveable[min];// 返回 movable[p]
}

  这种算法的缺点是——没有考虑蛇尾、轨迹等位置,导致蛇会自己被自己走死。

效果动画

这里写图片描述

  虽然这蛇经常把自己”走死”,但好歹是一条可以自己走的蛇。在今后的学习中,需要学习更好的算法,来让贪吃蛇更加智能。

CATALOG
  1. 1. 字符游戏-智能蛇
    1. 1.0.0.1. 伪代码:
    2. 1.0.0.2. C语言实现:
    3. 1.0.0.3. 效果动画