用C语言编程。。。贪吃蛇。。求助。。刚学了半年C语言。。

2025-01-06 12:37:05
推荐回答(3个)
回答1:

#define N 200
#include
#include
#include
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/*得分*/
int gamespeed=50000;/*游戏速度自己调整*/
struct Food
{
  int x;/*食物的横坐标*/
  int y;/*食物的纵坐标*/
  int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
  int x[N];
  int y[N];
  int node;/*蛇的节数*/
  int direction;/*蛇移动方向*/
  int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)
{
  Init();/*图形驱动*/
  DrawK();/*开始画面*/
  GamePlay();/*玩游戏具体过程*/
  Close();/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
  int gd=DETECT,gm;
  initgraph(&gd,&gm,"c:\\tc");
  cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
  setcolor(11);
  setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
  for(i=50;i<=600;i+=10)/*画围墙*/
  {
     rectangle(i,40,i+10,49); /*上边*/
     rectangle(i,451,i+10,460);/*下边*/
  }
 for(i=40;i<=450;i+=10)
 {
    rectangle(50,i,59,i+10); /*左边*/
    rectangle(601,i,610,i+10);/*右边*/
 }
}
/*玩游戏具体过程*/
void GamePlay(void)
{
  randomize();/*随机数发生器*/
  food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
  snake.life=0;/*活着*/
  snake.direction=1;/*方向往右*/
  snake.x[0]=100;snake.y[0]=100;/*蛇头*/
  snake.x[1]=110;snake.y[1]=100;
  snake.node=2;/*节数*/
  PrScore();/*输出得分*/
  while(1)/*可以重复玩游戏,压ESC键结束*/
  {
     while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
     {
 if(food.yes==1)/*需要出现新食物*/
 {
     food.x=rand()()%400+60;
     food.y=rand()()%350+60;
     while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
 food.x++;
     while(food.y%10!=0)
 food.y++;
 food.yes=0;/*画面上有食物了*/
 }
 if(food.yes==0)/*画面上有食物了就要显示*/
 {
             setcolor(GREEN);
             rectangle(food.x,food.y,food.x+10,food.y-10);
 }
        for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
        {
           snake.x[i]=snake.x[i-1];
    snake.y[i]=snake.y[i-1];
 }
      /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
 switch(snake.direction)
 {
    case 1:snake.x[0]+=10;break;
    case 2: snake.x[0]-=10;break;
    case 3: snake.y[0]-=10;break;
    case 4: snake.y[0]+=10;break;
 }
 for(i=3;i  {
    if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
    {
              GameOver();/*显示失败*/
              snake.life=1;
              break;
    }
       }
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
   snake.y[0]>455)/*蛇是否撞到墙壁*/
{
    GameOver();/*本次游戏结束*/
    snake.life=1; /*蛇死*/
}
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
          break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/
{
          setcolor(0);/*把画面上的食物东西去掉*/
          rectangle(food.x,food.y,food.x+10,food.y-10);
   snake.x[snake.node]=-20;snake.y[snake.node]=-20;
         /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
   snake.node++;/*蛇的身体长一节*/
   food.yes=1;/*画面上需要出现新的食物*/
   score+=10;
   PrScore();/*输出新得分*/
}
setcolor(4);/*画出蛇*/
for(i=0;i    rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
              snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
    }  /*endwhile(!kbhit)*/
   if(snake.life==1)/*如果蛇死就跳出循环*/
       break;
   key=bioskey(0);/*接收按键*/
   if(key==ESC)/*按ESC键退出*/
      break;
   else
      if(key==UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
  snake.direction=3;
      else
  if(key==RIGHT&&snake.direction!=2)
     snake.direction=1;
  else
     if(key==LEFT&&snake.direction!=1)
 snake.direction=2;
     else
 if(key==DOWN&&snake.direction!=3)
    snake.direction=4;
  }/*endwhile(1)*/
}
/*游戏结束*/
void GameOver(void)
{
   cleardevice();
   PrScore();
  setcolor(RED);
  settextstyle(0,0,4);
  outtextxy(200,200,"GAME OVER");
  getch()();
}
/*输出成绩*/
void PrScore(void)
{  
  char str[10];
  setfillstyle(SOLID_FILL,YELLOW);
  bar(50,15,220,35);
  setcolor(6);
  settextstyle(0,0,2);
  sprintf(str,"score:%d",score);
  outtextxy(55,20,str);
}
/*图形结束*/
void Close(void)
{  
   getch()();
   closegraph();
}


回答2:

#include
#include
#include
#include
#define food 7
#define head 5
#define body 6
#define wall 1
#define road 0
#define up 1
#define down 2
#define left 3
#define right 4
#define kuan 25
#define chang 30
int map[kuan][chang],hi,bj,fi,fj,t;//全局变量 地图数组 头部坐标,食物坐标,速度控制参数time
void gotoxy(int x,int y) //移动坐标
{
COORD coord;
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
void hidden()//隐藏光标
{
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
cci.bVisible=0;//赋1为显示,赋0为隐藏
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
}
void paint(int xx,int yy)
{
gotoxy(2*yy,xx);
switch(map[xx][yy])
{
case 0:printf(" ");break;
case 1:printf("□");break;
case 5:printf("◎");break;
case 6:printf("△");break;
case 7:printf("●");break;
}
}
void start()//初始化地图数组信息,随机蛇头位置,第一个食物位置
{
int i,j;
for(i=0;i<=kuan-1;i++)
{
map[i][0]=wall;
map[i][chang-1]=wall;
}
for(j=0;j<=chang-1;j++)
{
map[0][j]=wall;
map[kuan-1][j]=wall;
}
for (i=0;i<=kuan-1;i++)
for (j=0;j<=chang-1;j++)
paint(i,j);
gotoxy(64,2);printf("1.a减速//b加速");
gotoxy(64,4);printf("2.esc暂停");

}
int getkey(int ddd)//接收按键,根据当前方向,按动任意键暂停,不响应与运动方向相反的按键
{
char c;
while(c=getch())
{
switch(c)
{
case 72://1
{
if(ddd==2)
return down;
else
return up;
}
case 80://2
{
if(ddd==1)
return up;
else
return down;
}
case 75://3
{
if(ddd==4)
return right;
else
return left;
}
case 77://4
{
if(ddd==3)
return left;
else
return right;
}
case 27:continue;//esc暂停,a减速,d加速
case 97:{t+=10;return ddd;}
case 100:{t-=10;return ddd;}
default:{
return ddd;
}
}
return 0;
}
}
void game()
{
int fd=0,len=1,direction=4,a[100000],b[100000],k,m,kk=0,aa=0,bb=0,i;
t=250;//全局变量在这里赋值
//在一定范围随机蛇头初始位置,身子为左侧3个格子(可以拓展写入game里面)
hi=rand()%(kuan-7)+6;bj=rand()%(chang-8)+5;map[hi][bj]=head;paint(hi,bj);

a[3]=hi;b[3]=bj;//存放到 a b数组中第四项中

for (i=0;i<3;i++)
{map[hi][bj-1-i]=body;paint(hi,bj-i-1);a[2-i]=hi;b[2-i]=(bj-i-1);}//存放到 0 1 2 项中

k=4;m=4;//数组之后从第四位开始存放蛇头坐标

while(1)
{
while(!kbhit()&&len!=0)//当没有按键输入并且没有撞到墙使得len=0时候进入循环(防止撞到墙后没有按键输入仍终止不了)
{
while (!fd)//如果fd=0 则进入循环随机刷新一个新果实
{
do
{
fi=rand()%(kuan-3)+1;fj=rand()%(chang-3)+1;}
while(map[fi][fj]>0);//不在墙或者蛇的身体内
map[fi][fj]=food;paint(fi,fj);fd=1;
}
switch(direction)
{
case 1: {map[hi][bj]=body;paint(hi,bj);hi--;break;}
case 2: {map[hi][bj]=body;paint(hi,bj);hi++;break;}
case 3: {map[hi][bj]=body;paint(hi,bj);bj--;break;}
case 4: {map[hi][bj]=body;paint(hi,bj);bj++;break;}
}
if (map[hi][bj]==body)//在画出新的头部时刻先判断即将画出的位置是不是map上坐标为身子的位置。是则失败
{gotoxy(30,12);printf("失败了!");len=0;break;}

map[hi][bj]=head;paint(hi,bj);//接上,不是则执行这一步画出头部
a[k++]=hi;b[m++]=bj;kk++;//另设置两个数组记录头部经过的坐标,kk代表头部运行的次数
if (hi==0||hi==(kuan-1)||bj==0||bj==(chang-1))
{gotoxy(30,12);printf("失败了!");len=0;break;}
if (hi==fi&&bj==fj)//吃到了果实fd=0
{fd=0;len++;}
if(kk>(len-1))//头部每走一步,kk++,删除之前的轨迹坐标所对应的身子,即尾巴。若吃到食物则尾巴保留一次,带头部再次运动则删除。
{
map[a[aa]][b[bb]]=road;
paint(a[aa],b[bb]);
aa++;bb++;
kk--;
}
Sleep(t-4*len);//速度算法有待改进!!!!!!!!
}
if (len==0)//撞墙退出,退出while(1)总循环
break;
direction=getkey(direction);//按键按一下,getch提取并删除输入的字符,所以仍能继续进入while(!kbhit())中循环;
}
}
main()
{
srand(time(NULL));
hidden();
start();
game();
gotoxy(0,0);//锁定屏幕显示
getchar();
}
这个是我以前写的,没有区分难度,这个很简单不是关键难点。贪吃蛇的难点在于 如何实现移动中的控制与局部蛇身刷新! 希望你好好体会一下(我这个是自己学了半年后用数组写的,并没有用什么指针什么的,适合新手阅读。如果不懂可以提问)

另外,如果想深入学习,可以上C语言吧,搜我以前发的(变态版本贪吃蛇)

回答3:

、、、、、、、、、、、、、、、这是头文件、、、、、、、、、、、

//头文件防止被重复引用
#ifndef _SNAKE__H_
#define _SNAKE__H_

#include
/************************************************************************/
/* 界面大小的定义 */
/************************************************************************/
#define UI_WIDTH 96
#define UI_HIGH 34 /*界面高度*/

#define UI_MENU_XOFFSET 28 /*信息提示菜单相当外围的偏移量*/
#define UI_MENU_YOFFSET 24
#define UI_MENU_WIDTH 40
/*************************** 界面上坐标点定义 ********************************/
#define UI_COORDINATE_0_X 2 /*界面起始位置坐标*/
#define UI_COORDINATE_0_Y 2
#define UI_COORDINATE_1_X UI_COORDINATE_0_X
#define UI_COORDINATE_1_Y (UI_COORDINATE_0_Y+UI_HIGH)//定义的外围框架的高度
#define UI_COORDINATE_2_X (UI_COORDINATE_0_X+UI_MENU_XOFFSET)
#define UI_COORDINATE_2_Y (UI_COORDINATE_0_Y+UI_HIGH)
#define UI_COORDINATE_3_X (UI_COORDINATE_0_X+UI_MENU_XOFFSET)
#define UI_COORDINATE_3_Y (UI_COORDINATE_0_Y+UI_MENU_YOFFSET)
#define UI_COORDINATE_4_X (UI_COORDINATE_0_X+UI_MENU_XOFFSET+UI_MENU_WIDTH)
#define UI_COORDINATE_4_Y (UI_COORDINATE_0_Y+UI_MENU_YOFFSET)
#define UI_COORDINATE_5_X (UI_COORDINATE_0_X+UI_MENU_XOFFSET+UI_MENU_WIDTH)
#define UI_COORDINATE_5_Y (UI_COORDINATE_0_Y+UI_HIGH)
#define UI_COORDINATE_6_X (UI_COORDINATE_0_X+UI_WIDTH)
#define UI_COORDINATE_6_Y (UI_COORDINATE_0_Y+UI_HIGH)
#define UI_COORDINATE_7_X (UI_COORDINATE_0_X+UI_WIDTH)
#define UI_COORDINATE_7_Y (UI_COORDINATE_0_Y)
/*********************** 界面上信息提示起始点定义 ****************************/

//gotoxy的调用!
#include
void gotoxy(int x, int y);
int food_f(void);
#endif /*_SNAKE__H_*/

、、、、、、、这是移动、、、、、、、、
#include
#include "../Header Files/snake.h"
#include
#include
extern int fx;
extern int fy;
int leng = 4;
int move(void)
{
int ch = 4;
int ma = 4;
int arr[2][521] = {{UI_COORDINATE_3_X - 1,UI_COORDINATE_3_X - 2,UI_COORDINATE_3_X - 3,UI_COORDINATE_3_X - 4},
{UI_COORDINATE_3_Y - 4,UI_COORDINATE_3_Y - 4,UI_COORDINATE_3_Y - 4,UI_COORDINATE_3_Y - 4}};
int i = 0;

/***************限制时候用的变量************************/
int key = ma;
gotoxy(arr[0][0],arr[1][0]);
printf("@");
gotoxy(arr[0][1],arr[1][1]);
printf("*");

gotoxy(arr[0][2],arr[1][2]);
printf("*");
gotoxy(arr[0][3],arr[1][3]);
printf("*");
food_f();
/************************** 死循环 **********************/
while (1)
{
//判断是否吃到食物,是则让蛇长一节
if(fx == arr[0][0] && fy == arr[1][0])
{
leng++;
food_f();
}
/************************** 判断 食物 是否打印在了蛇的身上*****************************/
for (i=0; i < leng;i++)//如果在蛇身上!break;!
{
if (fx == arr[0][i] && fy == arr[1][i])
{
break;
}
}
//判断i是否结束! 也就是判断蛇身是否遍历!
if (i < leng)
{
food_f();
}
/******************** 判断是否有键盘输入 ********************/
if (_kbhit()) //如果有键盘输入!
{
ch = _getch(); //在缓冲读入键盘数据
fflush(stdin);
/**************************** 选择走哪一个 **********************************/
if ('W' == ch || 'w' == ch)
{
ma = 1;
}
else if ('S' == ch || 's' == ch)
{
ma = 2;
}
else if ('A' == ch || 'a' == ch)
{
ma = 3;
}
else if ('D' == ch || 'd' == ch)
{
ma = 4;
}
}

/********************不允许直接进行相反地操作**********************************/
if((3 != (ma + key))&&( 7 !=(key + ma)))
{
key = ma ;
}
else
{
ma = key ;
}
/************************************************************************/
/************************************************************************/
for (i = leng-1 ; i >= 0 ; i--)
{
arr[0][i+1] = arr[0][i]; // 把蛇的前一个坐标给后一个!
arr[1][i+1] = arr[1][i];
}
/************************* 控制蛇的方向 ************************************/
switch (ma)
{
//控制蛇运行的方向
case 4: arr[0][0]++ ;
break; //向右移动
case 3: arr[0][0]-- ;
break; //向左移动
case 2: arr[1][0]++ ;
break; //向下移动
case 1: arr[1][0]-- ;
break; //向上移动
}
for(i = 0 ; i < leng; i++)
{
gotoxy(arr[0][i],arr[1][i]);
//打印蛇
if (0 == i)
{
putchar('@');
}
else
{
putchar('*');
}
}
/********************* 如果是末尾清空 ************************/
gotoxy(arr[0][leng],arr[1][leng]);
putchar(0);
/************************* 限制条件 ***********************************/
if((arr[0][0] > UI_COORDINATE_0_X+UI_WIDTH - 1)
|| (arr[1][0] > UI_COORDINATE_1_Y - 1))
{
goto _out;
}
if ((arr[0][0] < UI_COORDINATE_0_X + 1)
|| (arr[1][0] < UI_COORDINATE_0_Y + 1))
{
goto _out;
}
if ((arr[1][0] > UI_COORDINATE_3_Y - 1)&& (arr[0][0] > UI_COORDINATE_3_X - 1)
&& (arr[0][0] < UI_COORDINATE_4_X - 1))
{
goto _out;
}
/****************判断蛇如果相接就死亡!************************/
for (i = 1;i {
if(arr[0][0] == arr[0][i] && arr[1][0] == arr[1][i])
{
goto _out;
}
}
speed();
}
_out:
gotoxy(UI_COORDINATE_3_X + 15,UI_COORDINATE_3_Y - 12);
printf("Game Over");
return 0;
}
/************************************************************************/
/* 蛇的级别,也就速度快慢 */
/************************************************************************/
#include
#include
#include
#include "../Header Files/snake.h"
extern int leng;
int speed(void)
{
int i = 0;
//蛇的初始速度
if(leng <= 5)
{
gotoxy(UI_COORDINATE_3_X + 14 ,UI_COORDINATE_3_Y + 7);
printf(" 第一关!");
Sleep(250);
}
else if (leng <= 8)
{
gotoxy(UI_COORDINATE_3_X + 14 ,UI_COORDINATE_3_Y + 7);
printf(" 第二关!");
Sleep(125);
}
else if (leng <= 10)
{
gotoxy(UI_COORDINATE_3_X + 14 ,UI_COORDINATE_3_Y + 7);
printf(" 第三关!");
Sleep(120);
}
else if (12 == leng)
{
Sleep(521);
system("cls");
gotoxy(UI_COORDINATE_3_X + 15,UI_COORDINATE_3_Y - 12);
printf("恭喜玩家通关~~~~可以去吃饭了!");
}

/************************障碍物的产生!******************************/
/*
for (i = 0;i < 1;i++)
{
if(leng == 8)
{

for (k = 0; k < 0x3ffffff; k++);

for (j = 0; j < 10; j++)
{
for (k = 0; k < 0x3ffffff; k++);
system("pause");
break;
}
}*/

return 0;
}

/************************************************************************/
/* 蛇的食物! */
/************************************************************************/

#include
#include "../Header Files/snake.h"
#include
int fy = 0;
int fx = 0;
int food_f(void)
{
//随机打印食物
do
{
(fx = rand() % 95);
} while (fx < 2);
do
{
(fy = rand() % 32);
} while (fy < 2);
//判断食物是否在可执行边框内!
if ((fx < UI_COORDINATE_0_X + 1)
|| (fy < UI_COORDINATE_0_Y + 1))
{
do
{
(fx = rand() % 95);
} while (fx < 2);
do
{
(fy = rand() % 32);
} while (fy < 2);
}
if ((fy > UI_COORDINATE_3_Y - 1)&& (fx > UI_COORDINATE_3_X - 1)
&& (fx < UI_COORDINATE_4_X - 1))
{
do
{
(fx = rand() % 95);
} while (fx < 2);
do
{
(fy = rand() % 32);
} while (fy < 2);
}
//打印食物!
gotoxy(fx,fy);
printf("%c",'!');
return 0;
}