View on GitHub

Homework Space

Homework Space for Introduction to Software Engineering

智能蛇实验报告

本报告包括:

1.Linux环境

  ·搭建Linux环境

2.体验Linux IO

  ·初次体验清屏函数以及VT100 终端标准

  ·贪吃蛇融入kbhit()函数

3.智能蛇

搭建Linux环境(Ubuntu 18.04)

(上述Ubuntu为微软商店下载的终端版本)

编辑环境 Vim(Ubuntu自带)

编译环境 gcc 7.3.0

root@LAPTOP-BQ574H8H:~# sudo apt-get update //此用于更新,提高安装gcc的概率
root@LAPTOP-BQ574H8H:~# sudo apt-get install gcc

安装成功后,通过下列指令查看版本号

root@LAPTOP-BQ574H8H:~# gcc -v

安装成功,则在显示信息的最下方出现如下:

gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

注意,也可通过VMware构建虚拟机Ubuntu桌面版,实现文件共享会更简单,同样,需要上述指令构建gcc


初次体验清屏函数以及VT100 终端标准

VT100 颜色输出

VT100 的颜色输出分为,前景色和背景色可以分别输出,如果不需要之前所有的设置可以用\033[0m取消。

1. 字背景颜色范围:40----49
    40:黑
    41:深红
    42:绿
    43:黄色
    44:蓝色
    45:紫色
    46:深绿
    47:白色
    2. 字前景颜色范围:30----39
    30:黑
    31:红
    32:绿
    33:黄
    34:蓝色
    35:紫色
    36:深绿
    37:白色
    3. 输出一个字符串( something here )有前景色和背景色代码如下:
    printf("\033[41;36m something here \033[0m");

代码及效果如下:

sin函数动态图sinDemo示例(清屏函数)

使用vi将代码敲完后,运行效果如下所示:

注意,此处在编译时可能出现如下问题:

解决方法如下:

为啥?点我进入解释


字符蛇融入kbhit()函数

温馨提示:加载完成后播放效果流畅

源码在这里

注意啦

  其实,第一次跑融入kbhit()的贪吃蛇时,编译正常,但是,在按下按钮之后蛇不会动, (我曾怀疑是kbhit()的问题),后来问过学长之后发现,windows的dev下Sleep()函数是为毫秒为单位的,而linux下sleep()函数是以秒为单位的,后将我的sleep()函数改为usleep()函数后,将参数扩大1000倍,运行效果则正常(usleep()函数参数以微妙为单位)。


智能蛇设计

效果如下:(智能的时候)

(智障的“瞬间”)

代码:智能蛇

思路?

首先,先不考虑距离,判断w、a、s、d四方向的可行性,设一数组possible_move[4] = {1,1,1,1} (注意,数组元素依次对应 w、a、s、d,比如,第一个元素下标是0,对应w方向的可行性),若不可行,将不可行方向的对应的下标导引的元素值从0变为1;

第二步,经过上一轮的筛选,再考虑距离,在put_food()函数里改变food[2]数组的值,下标0导引的元素值对应食物x坐标,下标1导引的元素值对应食物y坐标。创建cur_distance[4]数组,如下所示赋值:


int cur_distance[4];
		
cur_distance[0] = abs(headx - 1 - food[0]) + abs(heady - food[1]);//w

cur_distance[1] = abs(headx - food[0]) + abs(heady - 1 - food[1]);//a

cur_distance[2] = abs(headx + 1 - food[0]) + abs(heady - food[1]);//s

cur_distance[3] = abs(headx - food[0]) + abs(heady + 1 - food[1]);//d

第三步,在可行的方向中选择最小距离的那个方向作为下一次移动的方向。

以下就是具体的如何选择移动方向的函数设计

int possible_move[4] = {1,1,1,1};

printf("\033[2J");//清屏 
int xx[4] = {-1,0,1,0};
int yy[4] = {0,-1,0,1};
for(int i = 0;i < 4;i ++) {
	if(map_playgame[headx+xx[i]][heady+yy[i]] == WALL_CELL || map_playgame[headx+xx[i]][heady+yy[i]] == SNAKE_BODY)
	possible_move[i] = 0;
}
		
int cur_distance[4];
		
cur_distance[0] = abs(headx - 1 - food[0]) + abs(heady - food[1]);//w
cur_distance[1] = abs(headx - food[0]) + abs(heady - 1 - food[1]);//a
cur_distance[2] = abs(headx + 1 - food[0]) + abs(heady - food[1]);//s
cur_distance[3] = abs(headx - food[0]) + abs(heady + 1 - food[1]);//d
		
char next_direction;

int k;
for(k = 0;k < 4;k ++) {
	if(possible_move[k] == 1) 
        break;//随机选取一个可行方向
	}

int min = cur_distance[k];
int min_pos = k;
for(int i = 0;i < 4;i ++) {
	if( possible_move[i] == 1 && cur_distance[i] < min) 
		{
			min = cur_distance[i];
			min_pos = i;
		}
}
		
switch(min_pos) {
			
	case 0: next_direction = 'w';break;
	case 1: next_direction = 'a';break;
	case 2: next_direction = 's';break;
	case 3: next_direction = 'd';break;
			
}
		
direction = next_direction;
		
switch(direction) {
			
	case 'w': snake_move(-1,0,food);break;
	case 'a': snake_move(0,-1,food);break;
	case 's': snake_move(1,0,food);break;
	case 'd': snake_move(0,1,food);break;
			
}
print_map_playgame();//打印进行一次snake_move后的地图 

实验总结

  经过这次Linux体验以及智能蛇的设计,感觉自己很智障,我感受到了命令行的魅力,感受到了开发游戏AI的困难而有趣,在这次实验中,我还遇到了不少问题,比方说windows下Sleep(a)函数参数的单位与Linux下sleep(a)函数参数的单位的不同,前者是毫秒,后者是秒;也遇到了平时编程的基础问题,获益匪浅。

  感谢这次实验,让我体验到亲身投入游戏制作的有趣以及魅力。pml无敌