数组版贪吃蛇

论坛 期权论坛 脚本     
已经匿名di用户   2022-5-29 19:37   3983   0

关于数组贪吃蛇移动思路,由于蛇身是数组,因此用数组的下标能够很好
的移动到需要操作的位置,每次移动的时候让蛇尾先移动,之后读取下一位
置的坐标再移动,直到数组[1]的位置,(为什么不到[0]因为[0]是蛇头的
位置,我们需要用它来移动位置)之后让[0]自加,(蛇就会移动了)


关于制造食物的思路,需要特别考虑的一点,不要把食物生成到蛇身的坐标
里面,因此,每当产生了新的食物的坐标,我们都要循环一偏蛇身,检测是
否与神身的坐标相同的,如果有则重新产生新的坐标,如果没有则结束循环


关于方向键的思路,先定义两个变量CH1,CH2。其中CH1用爱接受用户的按键
信息,CH2用来作为主函数的实参(它是传给方向函数,操作小蛇的方向)
首先给CH2赋一个向右移动的值,之后我们判断如果CH2向右边移动,那么输入
CH1的值若是向左边就不执行CH2=CH1。

编译器:VC6


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <conio.h>


int v=200;      //小蛇的移动速度
int foodx;      //食物的坐标
int foody;
int snakeleng=2;    //蛇身的长度(注意数组坐标从0开始)
int count=0;     //计算分数


struct body
{
 int x;
 int y;
};
struct body snake_body[500]; //蛇身的长度




void gotoxy(int x,int y)
{
 HANDLE app;        //定义句柄
 COORD pos;        //定义坐标
 pos.X=x;        //修改X坐标,使X移动
 pos.Y=y;        //修改Y坐标,使Y移动
 app=GetStdHandle(STD_OUTPUT_HANDLE); //获取句柄
 SetConsoleCursorPosition(app,pos);  //将获取的句柄移动,坐标是POS 
}


void initsnake()   //初始化小蛇
{
 int i,temp=7;


 for(i=0;i<3;i++,temp-=2)
 {
  snake_body[i].x=temp;
  snake_body[i].y=10;


  gotoxy(temp,10);
  printf("■");
 }
}


void direct(char ch)  //小蛇移动方向函数
{
  if(ch=='s'||ch=='S')//支持大小写按键
   snake_body[0].y=snake_body[0].y+1; 


  if(ch=='w'||ch=='W')
   snake_body[0].y=snake_body[0].y-1;


  if(ch=='a'||ch=='A')
   snake_body[0].x=snake_body[0].x-2;


  if(ch=='d'||ch=='D')
   snake_body[0].x=snake_body[0].x+2;
}


void make_food()     //制造食物(有问题,怎么避免把食物生成在蛇身里?)
{
 int i,flag=1;     //此处是flag用于记录蛇身坐标与食物坐标是否相等


 srand((unsigned)time(NULL));


 while(flag)
 {
  foodx=rand()%53+2;
  if(foodx%2==0)    //将食物的X轴坐标变为奇数
   foodx++;


  foody=rand()%22+2;
 
  for(i=snakeleng;i>=0;i--) //遍历蛇身
  { //如果产生的食物坐标与蛇身的任意位置相等
   if(snake_body[i].x==foodx && snake_body[i].y==foody)
   {
    flag=1;    //坐标相等则再重新产生新的坐标
    break;    //跳出循环
   }
   else
    flag=0;
  }
  
 }
 gotoxy(foodx,foody);   //画出食物
 printf("●");
}


void drawmap()      //地图函数
{
 int i;


 for(i=1;i<=30;i++)
  printf("□");


 printf("\n");


 for(i=1;i<=23;i++)
 {
  printf("□\t\t\t\t\t\t\t  □");
  printf("\n");
 }


 for(i=1;i<=30;i++)
  printf("□");
 
 gotoxy(66,4);
 printf("贪吃蛇内测");
 gotoxy(65,5);
 printf("软件开发二班");


 gotoxy(64,7);
 printf("======");
 gotoxy(64,8);
 printf("‖玩家得分‖");
 gotoxy(64,9);
 printf("‖\t  ‖");
 gotoxy(64,10);
 printf("======");


 gotoxy(64,13);
 printf("======");
 gotoxy(64,14);
 printf("‖游戏说明 ‖");
 gotoxy(64,15);
 printf("‖w向上移动‖");
 gotoxy(64,16);
 printf("‖s向下移动‖");
 gotoxy(64,17);
 printf("‖a向左移动‖");
 gotoxy(64,18);
 printf("‖d向右移动‖");
 gotoxy(64,19);
 printf("======");
}


int add_snake_body()   //增加蛇身的函数
{
 if(snake_body[0].x==foodx && snake_body[0].y==foody) //如果食物坐标和蛇头坐标相等,说明蛇已经吃到食物了
 {
  gotoxy(foodx,foody); //擦去蛇的食物
  printf("■");


  snakeleng++;   //增加蛇的长度
  count++;    //每吃一个食物增加一分
  v--;


  gotoxy(66,9);   //打印得分
  printf("%5d",count);


  snake_body[snakeleng].x=snake_body[snakeleng-1].x;  //增加新的身体,读取下个位置的坐标
  snake_body[snakeleng].y=snake_body[snakeleng-1].y;
   
  return 1;    //记录蛇已经吃了食物
 }
 else
  return 0;
}


void read_next_coord()   //下一位置坐标函数
{
 int i;


 for(i=snakeleng;i>0;i--) //循环读取下一个位置的坐标
  {
   if(i==snakeleng) //如果i等于蛇尾(snakeleng最先初始化为2,那么2是蛇尾)
   {
    gotoxy(snake_body[i].x,snake_body[i].y);  //擦除蛇尾
    printf("  ");
   }


   snake_body[i].x=snake_body[i-1].x;     
   snake_body[i].y=snake_body[i-1].y; 
 }
}


void snake_death()    //判断蛇死亡的函数
{
 int i;


 if( (snake_body[0].x<2 || snake_body[0].x>55) || (snake_body[0].y<1 || snake_body[0].y>23)) //检测左右两边是否碰墙,检测上下两边是否碰墙
 {
  printf("撞墙了!游戏结束!");
  exit(0);
 }


 for(i=snakeleng;i>=4;i--)     //能否避免遍历所有数组?
 {
  if(snake_body[0].x==snake_body[i].x && snake_body[0].y==snake_body[i].y)
  {
   printf("咬到身体了!");
   exit(0);
  }
 }
}


int main(void)
{
 int flag=1;      //标记食物是否被吃
 char ch2='d',ch1='a';


 system("color b");    //改变颜色


 drawmap();      //初始化地图
 
 initsnake();     //初始化蛇身


 while(1)
 {
  if(flag)
  {
   make_food();
   flag=0;
  }


  read_next_coord();   //蛇身读取下一个位置的坐标
 
  if(kbhit())     //接受键盘输入的方向
   ch1=getch();
  
  if(ch1!='a' && ch1!='s' && ch1!='w' && ch1!='d')//此语句是为了避免用户按下非a,s,w,d键
   ch1=ch2;    //将上次移动的方向键赋值(如果错误按下,然默认为按原来方向移动)


  if((ch2=='d' && ch1!='a')||(ch2=='w' && ch1!='s')||(ch2=='s' && ch1!='w')||(ch2=='a' && ch1!='d'))
  {
   ch2=ch1;    //此语句要来判断小蛇不往相反方向移动 
  }


  direct(ch2);    //调用方向函数 
  
  gotoxy(snake_body[0].x,snake_body[0].y);    //画出新的蛇头
  printf("■");
  Sleep(v);     //控制蛇的速度


  flag=add_snake_body();  //判断蛇是否吃了食物


  snake_death();    //判断蛇是否死亡
 } 
 return 0;
}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP