在写完了贪吃蛇后,发觉用C语言做这样的简单东西还蛮有意思。虽然在dalao看来有点没水准,但自我感觉还是蛮好的。
首先是先用上写的贪吃蛇代码,然后再加上一个控制蛇的移动方向的代码。
其中出现过许多状况,比如蛇吃着吃着把墙吃了,又或者是把自己吃了,更让人无奈的是有时它有时还会一直转圈。特别是设置了额外的障碍时,蛇更是经常性地进入转圈的死循环。
那我们要怎么让蛇自动寻路呢,这里我们需要知道蛇头及食物的坐标,通过计算蛇头将要到达的下一个位置哪个离食物比较近,从而获得移动方向。那怎么避免撞墙或撞到自己的身体呢?只要用个if语句应该就差不多了。
这个算法其实还是蛮低级的,蛇经常会。。。。。。出些幺蛾子。但是对于我这一个变成小白来说,算比较OK了。
这里代码的一些开头就先省去了。
int len = 5;
int life = 0;
int food = 0;
int Fx = 0, Fy = 0;//食物坐标
int Hx = 1, Hy = 5;//蛇头坐标
int X[SNAKE_MAX_LENGTH]={1,1,1,1,1};//sanke
int Y[SNAKE_MAX_LENGTH]={1,2,3,4,5};//snake
char map[12][12] = {"************",
"*XXXXH *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"************",};
void snakeMove(int x, int y) {
char ch;
int i;
if ((X[len - 1] - X[len - 2] == -x && Y[len - 1] == Y[len - 2]) || (Y[len - 1] - Y[len - 2] == -y && X[len - 1] == X[len - 2])) {
return;
}//若键盘输入的方向与蛇头方向相反,则什么事都不发生
if (map[X[len - 1] + x][Y[len - 1] + y] == WALL_CELL || map[X[len - 1] + x][Y[len - 1] + y] == SNAKE_BODY) {
life++;
}//若碰到墙壁或者自己就死掉
if (map[X[len - 1] + x][Y[len - 1] + y] == SNAKE_FOOD) {
map[X[len - 1]][Y[len - 1]] = SNAKE_BODY;
map[X[len - 1] + x][Y[len - 1] + y] = SNAKE_HEAD;
len++;
X[len - 1] = X[len - 2] + x;
Y[len - 1] = Y[len - 2] + y;
Hx = X[len - 1];
Hy = Y[len - 1];
food--;
}//碰到食物就增长
else {
map[X[0]][Y[0]] = BLANK_CELL;
for (i = 0; i < len - 1; i++) {
X[i] = X[i + 1];
Y[i] = Y[i + 1];
}
X[len - 1] += x;
Y[len - 1] += y;
Hx = X[len - 1];
Hy = Y[len - 1];
map[Hx][Hy] = SNAKE_HEAD;
for (i = 0; i < len - 1; i++) {
map[X[i]][Y[i]] = SNAKE_BODY;
}
}//没碰到食物
}
void put_money(void) {
if (food == 0) {
srand(time(NULL));
Fx = rand() % 9 + 1;
Fy = rand() % 9 + 1;
if (map[Fx][Fy] == BLANK_CELL) {
map[Fx][Fy] = SNAKE_FOOD;
food++;
}
}
}
void output(void) {
int i, j;
for (i = 0; i < 12; i++) {
for (j = 0; j < 12; j++)
printf("%c", map[i][j]);
printf("\n");
}
}
void gameover(void) {
printf ("GAME OVER!!!");
return;
}
char whereGoNext(int Hx, int Hy, int Fx, int Fy) {
int i;
int temp = 0;
int min = 10000;
char moveble[4] = "WASD";
int distance[4]={0, 0, 0, 0};
distance[0] = abs(Fx - (Hx - 1)) + abs(Fy - Hy);
distance[1] = abs(Fx - Hx) + abs(Fy - (Hy - 1));
distance[2] = abs(Fx - (Hx + 1)) + abs(Fy - Hy);
distance[3] = abs(Fx - Hx) + abs(Fy - (Hy + 1));
if (map[Hx - 1][Hy] == '*' || map[Hx - 1][Hy] == 'X')
distance[0] = 9999;
if (map[Hx][Hy - 1] == '*' || map[Hx][Hy - 1] == 'X')
distance[1] = 9999;
if (map[Hx + 1][Hy] == '*' || map[Hx + 1][Hy] == 'X')
distance[2] = 9999;
if (map[Hx][Hy + 1] == '*' || map[Hx][Hy + 1] == 'X')
distance[3] = 9999;
//
printf("%d %d %d %d \n",distance[0], distance[1], distance[2], distance[3]);
//
for (i = 0; i < 4; i++) {
if (min > distance[i]) {
temp = i;
min = distance[i];
}
else continue;
}
printf("%d\n", min);
return moveble[temp];
}
int main() {
put_money();
output();
while (1) {
put_money();
char ch = whereGoNext(Hx, Hy, Fx, Fy);
//
printf("%d %d %d %d ",Hx, Hy, Fx, Fy);
printf("%c", whereGoNext(Hx, Hy, Fx, Fy));
//
Sleep(100);
switch (ch) {
case 'A':
snakeMove(0, -1); break;
case 'S':
snakeMove(1, 0); break;
case 'D':
snakeMove(0, 1); break;
case 'W':
snakeMove(-1, 0); break;
}
system("cls");
if (life != 0) {
gameover();
break;
}
if (len == 20) {
printf("you win!!!");
break;
}
output();
}
}`
代码中有一些printf语句是用来检测那些量有没有逻辑上的计算错误的。
终于在我的调整下,那只蛇终于会吃东西了。虽然基本上吃几个就会把自己困死。
但是偶尔也会吃完二十个。
哦,对了,为了让蛇不要一下运行完,这里可以用一个sleep()函数。在Dev cpp上运行发现当s是小写时,括号中数字的单位是秒,大写时单位则变成了毫秒。
这就是一条简单的智能(zhizhang)蛇了。