从原来的贪吃蛇到现在的智能蛇,需要克服几个难关。
1,清屏
#include <windows.h>
system("cls");
2,让蛇自己移动
void snake_move(int direct,int snake[snake_max_length][3])//让蛇移动 direct=1向上 direct=2向下 direct=3向左 direct=4向右
{ int x, y;//作为临时交换的值 head为蛇头
int i;
for (i = 0;i < 5;i++) {
if (snake[i][0] == 1) {
head = i;
break;
}
}
//找到头并将头的坐标保留用于下一个补上来
x = snake[head][1];
y = snake[head][2];
switch (direct){
case 1://向上
snake[head][1]--;//横坐标不变,纵坐标+1
break;
case 2://向下
snake[head][1]++;//横坐标不变,总左边-1
break;
case 3://向左
snake[head][2]--;//纵坐标不变,横坐标-1
break;
case 4://向右
snake[head][2]++;//纵坐标不变,横坐标+1
break;
}
//头已经到了下一个位置,接下来将之前所有的身体放到前一个的位置上
int j;
for (j = head - 1;j >= 0;j--) {
int temp;
temp = x, x = snake[j][1], snake[j][1] = temp;
temp = y, y = snake[j][2], snake[j][2] = temp;
}
}
3,让蛇具有躲避障碍并吞吃食物的智能
char whereGoNext(snake[][],food[][]){//智能重新设置蛇的方向
char moveable[4]={'H','F','K','M'};//方向
int distance[4]={0,0,0,0};//距离
distance[0]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]+1-food[1])*(snake[head][2]+1-food[1]);
if(map[snake[head][1]][snake[head][2]+1]==wall_cell||map[snake[head][1]][snake[head][2]+1]==snake_food){//避免撞到墙和身体
distance[0]=9999;
}
distance[1]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]-1-food[1])*(snake[head][2]-1-food[1]);
if(map[snake[head][1]][snake[head][2]-1]==wall_cell||map[snake[head][1]][snake[head][2]-1]==snake_food){
distance[1]=9999;
}
distance[2]=(snake[head][1]-1-food[0])*(snake[head][1]-1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
if(map[snake[head][1]-1][snake[head][2]]==wall_cell||map[snake[head][1]-1][snake[head][2]]==snake_food){
distance[2]=9999;
}
distance[3]=(snake[head][1]+1-food[0])*(snake[head][1]+1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
if(map[snake[head][1]+1][snake[head][2]]==wall_cell||map[snake[head][1]+1][snake[head][2]]==snake_food){
distance[3]=9999;
}
int min=get_min(distance);//取距离最小的下标
return moveable[min];
}
最终完成品
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#define snake_max_length 20
#define snake_head 'H'
#define snake_body 'X'
#define blank_cell ' '
#define snake_food '$'
#define wall_cell '*'
char map[12][12]= //初始状态的游戏背景
{"************",
"* *",
"* *",
"* * *",
"* * *",
"* * *",
"* * *",
"* * *",
"* *",
"* *",
"* *",
"************"};
int snake[snake_max_length][3];//设定蛇
int head;//设定蛇头位置
int direct=4;//设定初始方向向右
int food[2];
char whereGoNext(snake[][],food[][]){//智能重新设置蛇的方向
char moveable[4]={'H','F','K','M'};//方向
int distance[4]={0,0,0,0};//距离
distance[0]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]+1-food[1])*(snake[head][2]+1-food[1]);
if(map[snake[head][1]][snake[head][2]+1]==wall_cell||map[snake[head][1]][snake[head][2]+1]==snake_food){//避免撞到墙和身体
distance[0]=9999;
}
distance[1]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]-1-food[1])*(snake[head][2]-1-food[1]);
if(map[snake[head][1]][snake[head][2]-1]==wall_cell||map[snake[head][1]][snake[head][2]-1]==snake_food){
distance[1]=9999;
}
distance[2]=(snake[head][1]-1-food[0])*(snake[head][1]-1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
if(map[snake[head][1]-1][snake[head][2]]==wall_cell||map[snake[head][1]-1][snake[head][2]]==snake_food){
distance[2]=9999;
}
distance[3]=(snake[head][1]+1-food[0])*(snake[head][1]+1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
if(map[snake[head][1]+1][snake[head][2]]==wall_cell||map[snake[head][1]+1][snake[head][2]]==snake_food){
distance[3]=9999;
}
int min=get_min(distance);//取距离最小的下标
return moveable[min];
}
int ifReprat(int snake[400][3], int x, int y){//判断生成的食物是否与蛇有重复
int i=0;
for (i = 0;i < 400;i++) {
if (snake[i][0] == 1) break;
if ((snake[i][1] == x&&snake[i][2] == y)) {//有重复
return 1;
}
}
return 0;
}
void makeFood(int food[]){//生成随机数制作一个食物坐标
srand(time(0));
int x = rand() % 49 + 2, y = rand() % 19 + 2;//生成一个1-50的数作为横坐标 1-20的数作为纵坐标
while (ifReprat(snake,x,y)) {//如果有重复就重新生成一个 直到不重复为止
x = rand() % 49 + 2, y = rand() % 19 + 2;
}
food[0] = y;
food[1] = x;
}
int ifEat(int head, int food[2]){//判断食物是否被吃掉
if (snake[head][1] == food[0] && snake[head][2] == food[1])
return 1;
else
return 0;
}
int ifBump(int head){//判断是否会相撞(撞自己或撞墙)
if ((snake[head][2]==0|| snake[head][2] == 51) || (snake[head][1] == 0|| snake[head][1] == 21))//撞墙
return 1;
int i=0;
for (i = 0;i < head-1;i++) {
if ((snake[i][1] == snake[head][1]&&snake[i][2] == snake[head][2])) {//幢自己
return 1;
}
}
return 0;
}
void snake_move(int direct,int snake[snake_max_length][3])//让蛇移动 direct=1向上 direct=2向下 direct=3向左 direct=4向右
{ int x, y;//作为临时交换的值 head为蛇头
int i;
for (i = 0;i < 5;i++) {
if (snake[i][0] == 1) {
head = i;
break;
}
}
//找到头并将头的坐标保留用于下一个补上来
x = snake[head][1];
y = snake[head][2];
switch (direct){
case 1://向上
snake[head][1]--;//横坐标不变,纵坐标+1
break;
case 2://向下
snake[head][1]++;//横坐标不变,总左边-1
break;
case 3://向左
snake[head][2]--;//纵坐标不变,横坐标-1
break;
case 4://向右
snake[head][2]++;//纵坐标不变,横坐标+1
break;
}
//头已经到了下一个位置,接下来将之前所有的身体放到前一个的位置上
int j;
for (j = head - 1;j >= 0;j--) {
int temp;
temp = x, x = snake[j][1], snake[j][1] = temp;
temp = y, y = snake[j][2], snake[j][2] = temp;
}
}
void output(int snake[snake_max_length][3],char map[12][12],int food[]){//打印游戏画面
int i;
int j;
for (i = 0;i <5;i++) {//绘制蛇
if (snake[i][0] == 1) break;
map[snake[i][1]][snake[i][2]] = snake_body;
}
map[snake[i][1]][snake[i][2]] = snake_head;
map[food[0]][food[1]] = snake_food;//绘制食物
for (i = 0;i<12;i++) {//打印游戏画面
for (j = 0;j<12;j++) {
printf("%c", map[i][j]);
}
printf("\n");
}
}
void game_over()//当游戏结束时输出Game Over
{
printf("Game Over");
return;
}
int main()
{
output(snake,map,food);//输出游戏画面
while(1){
system("cls");//清屏
char ch=whereGoNext(snake,food);//智能重新设置蛇的运动方向
switch (ch) {
case 'H'://向上
if (direct != 2)
direct = 1;
break;
case 'P'://向下
if (direct != 1)
direct = 2;
break;
case 'K'://向左
if (direct != 4)
direct = 3;
break;
case 'M'://向右
if (direct != 3)
direct = 4;
break;
}
snake_move(direct,snake[snake_max_length][3]);//让蛇移动
if (!food[0]&&!food[1]) {//食物已经被吃掉--重新生成食物
makeFood(food);//生成食物坐标
}
if (ifBump(head)) {//相撞,游戏结束
break;
}
output(snake,map,food);//输出游戏画面
}
game_over();//输出Game Over
return 0;
}