c语言 贪吃蛇 程序

Python016

c语言 贪吃蛇 程序,第1张

基本思路:

蛇每吃一个食物蛇身子就增加一格,用UP, DOWN, LEFT, RIGHT控制蛇头的运动,而蛇身子跟着蛇头走,每后一格蛇身子下一步走到上一格蛇身子的位置,以此类推。

#include <stdio.h>

#include <conio.h>

#include <windows.h>

#define BEG_X 2

#define BEG_Y 1

#define WID 20

#define HEI 20

HANDLE hout

typedef enum {UP, DOWN, LEFT, RIGHT} DIR

typedef struct Snake_body

{

COORD pos//蛇身的位置

struct Snake_body *next//下一个蛇身

struct Snake_body *prev//前一个蛇身

}SNAKE, *PSNAKE

PSNAKE head = NULL//蛇头

PSNAKE tail = NULL//蛇尾

//画游戏边框的函数

void DrawBorder()

{

int i, j

COORD pos = {BEG_X, BEG_Y}

for(i = 0i <HEI++i)

{

SetConsoleCursorPosition(hout, pos)

for(j = 0j <WID++j)

{

if(i == 0)//第一行

{

if(j == 0)

printf("┏")

else if(j == WID - 1)

printf("┓")

else

printf("━")

}

else if(i == HEI - 1)//最后一行

{

if(j == 0)

printf("┗")

else if(j == WID - 1)

printf("┛")

else

printf("━")

}

else if(j == 0 || j == WID - 1)//第一列或最后一列

printf("┃")

else

printf("  ")

}

++pos.Y

}

}

//添加蛇身的函数

void AddBody(COORD pos)

{

PSNAKE pnew = (PSNAKE)calloc(1, sizeof(SNAKE))

pnew->pos = pos

if(!head)

{

head = tail = pnew

}

else

{

pnew->next = head//新创建蛇身的next指向原先的蛇头

head->prev = pnew//原先的蛇头的prev指向新创建的蛇身

head = pnew//把新创建的蛇身作为新的蛇头

}

SetConsoleCursorPosition(hout, head->pos)

printf("◎")

}

//蛇身移动的函数

void MoveBody(DIR dir)

{

PSNAKE ptmp

COORD pos = head->pos

switch(dir)

{

case UP:

if(head->pos.Y >BEG_Y + 1)

--pos.Y

else

return

break

case DOWN:

if(head->pos.Y <BEG_Y + HEI - 2)

++pos.Y

else

return

break

case LEFT:

if(head->pos.X >BEG_X + 2)

pos.X -= 2

else

return

break

case RIGHT:

if(head->pos.X <BEG_X + (WID - 2) * 2)

pos.X += 2

else

return

break

}

AddBody(pos)//添加了一个新的蛇头

ptmp = tail//保存当前的蛇尾

tail = tail->prev

if(tail)

tail->next = NULL

SetConsoleCursorPosition(hout, ptmp->pos)

printf("  ")

free(ptmp)

}

int main()

{

int ctrl

DIR dir = RIGHT//初始蛇的方向是向右的

COORD pos = {BEG_X + 2, BEG_Y + HEI / 2}

system("color 0E")

system("mode con cols=90 lines=30")

hout = GetStdHandle(STD_OUTPUT_HANDLE)

printf("    ------------贪吃蛇的移动------------")

DrawBorder()

//自定义几个蛇的身体

AddBody(pos)

pos.X += 2

AddBody(pos)

pos.X += 2

AddBody(pos)

pos.X += 2

AddBody(pos)

pos.X += 2

AddBody(pos)

pos.X += 2

AddBody(pos)

pos.X += 2

AddBody(pos)

//控制蛇的移动

while(ctrl = getch())

{

switch(ctrl)

{

case 'w':

if(dir == DOWN)

continue

dir = UP

break

case 's':

if(dir == UP)

continue

dir = DOWN

break

case 'a':

if(dir == RIGHT)

continue

dir = LEFT

break

case 'd':

if(dir == LEFT)

continue

dir = RIGHT

break

case 'q':

return 0

}

MoveBody(dir)

}

return 0

}

扩展资料:

实现逻辑

1,可以设置光标,就能实现制定位置打印制定符号。

2,涉及一个结构体,包含两个元素坐标元素和一个结构体指针。

3,结构体串联形成链表,遍历获取成员坐标,打印符号得到蛇身。

4,不断的加头,去尾,重新遍历坐标,再打印形成蛇的移动。

5,食物产生的位置判定,不能越界,也不能与蛇身体重合。

6,蛇的转向判定,一条规则,不允许倒退。

7,转向的实现,跟行进方向决定新的关节坐标(当前头的上下左右)

8,死亡检测,是否头节点坐标是否与墙壁重合,是否与身体其他关节重合。

9,加速减速,设置刷新休眠时间实现。

参考资料来源:百度百科-C语言

 

//******友情提示:如想速度快点,请改小_sleep(500)函数中参数*****  

#include <stdio.h>  

#include <stdlib.h>  

#include <conio.h>  

#include <string.h>  

#include <time.h>  

const int H = 8   //地图的高  

const int L = 16  //地图的长  

char GameMap[H][L]   //游戏地图  

int  key  //按键保存  

int  sum = 1, over = 0  //蛇的长度, 游戏结束(自吃或碰墙)  

int  dx[4] = {0, 0, -1, 1}  //左、右、上、下的方向  

int  dy[4] = {-1, 1, 0, 0}  

struct Snake   //蛇的每个节点的数据类型  

{  

 int x, y  //左边位置  

 int now   //保存当前节点的方向, 0,1,2,3分别为左右上下  

}Snake[H*L]  

const char Shead = '@'  //蛇头  

const char Sbody = '#'  //蛇身  

const char Sfood = '*'  //食物  

const char Snode = '.'  //'.'在地图上标示为空  

void Initial()  //地图的初始化  

void Create_Food() //在地图上随机产生食物  

void Show()   //刷新显示地图  

void Button()  //取出按键,并判断方向  

void Move()   //蛇的移动  

void Check_Border()  //检查蛇头是否越界  

void Check_Head(int x, int y)   //检查蛇头移动后的位置情况  

int main()   

{  

 Initial()  

 Show()  

 return 0  

}  

void Initial()  //地图的初始化  

{  

 int i, j  

 int hx, hy  

 system("title 贪吃蛇")  //控制台的标题  

 memset(GameMap, '.', sizeof(GameMap))  //初始化地图全部为空'.'  

 system("cls")  

 srand(time(0))   //随机种子  

 hx = rand()%H    //产生蛇头  

 hy = rand()%L  

 GameMap[hx][hy] = Shead  

 Snake[0].x = hx  Snake[0].y = hy  

 Snake[0].now = -1  

 Create_Food()   //随机产生食物  

 for(i = 0 i < H i++)   //地图显示  

 {   

  for(j = 0 j < L j++)  

   printf("%c", GameMap[i][j])  

  printf("\n")  

 }  

     

 printf("\n小小C语言贪吃蛇\n")  

 printf("按任意方向键开始游戏\n")  

    

 getch()   //先接受一个按键,使蛇开始往该方向走  

 Button()  //取出按键,并判断方向  

}  

void Create_Food()  //在地图上随机产生食物  

{  

 int fx, fy  

 while(1)  

 {  

  fx = rand()%H  

     fy = rand()%L  

     

  if(GameMap[fx][fy] == '.')  //不能出现在蛇所占有的位置  

  {   

   GameMap[fx][fy] = Sfood  

      break  

  }  

 }  

}  

void Show()  //刷新显示地图  

{  

 int i, j  

 while(1)  

 {    

  _sleep(500) //延迟半秒(1000为1s),即每半秒刷新一次地图  

  Button()   //先判断按键在移动  

  Move()  

  if(over)  //自吃或碰墙即游戏结束  

  {   

   printf("\n**游戏结束**\n")  

   printf("     >_<\n")  

   getchar()  

      break  

  }  

  system("cls")   //清空地图再显示刷新吼的地图  

  for(i = 0 i < H i++)   

  {   

   for(j = 0 j < L j++)  

    printf("%c", GameMap[i][j])  

   printf("\n")  

  }  

     

  printf("\n小小C语言贪吃蛇\n")  

  printf("按任意方向键开始游戏\n")  

 }  

}  

void Button()  //取出按键,并判断方向  

{  

 if(kbhit() != 0) //检查当前是否有键盘输入,若有则返回一个非0值,否则返回0  

 {   

  while(kbhit() != 0)  //可能存在多个按键,要全部取完,以最后一个为主  

      key = getch() //将按键从控制台中取出并保存到key中  

  switch(key)  

  {   //左  

   case 75:  Snake[0].now = 0  

          break  

            //右  

            case 77:  Snake[0].now = 1       

          break  

            //上  

   case 72:  Snake[0].now = 2  

          break  

            //下  

   case 80:  Snake[0].now = 3  

          break  

  }  

 }  

}  

void Move()   //蛇的移动  

{  

 int i, x, y  

    int t = sum  //保存当前蛇的长度  

 //记录当前蛇头的位置,并设置为空,蛇头先移动  

 x = Snake[0].x  y = Snake[0].y  GameMap[x][y] = '.'  

 Snake[0].x = Snake[0].x + dx[ Snake[0].now ]  

 Snake[0].y = Snake[0].y + dy[ Snake[0].now ]  

 Check_Border()   //蛇头是否越界  

 Check_Head(x, y)  //蛇头移动后的位置情况,参数为: 蛇头的开始位置  

 if(sum == t)  //未吃到食物即蛇身移动哦  

    for(i = 1 i < sum i++)  //要从蛇尾节点向前移动哦,前一个节点作为参照  

 {  

  if(i == 1)   //尾节点设置为空再移动  

   GameMap[ Snake[i].x ][ Snake[i].y ] = '.'  

     

  if(i == sum-1)  //为蛇头后面的蛇身节点,特殊处理  

  {  

   Snake[i].x = x  

         Snake[i].y = y  

      Snake[i].now = Snake[0].now  

  }  

  else   //其他蛇身即走到前一个蛇身位置  

  {  

   Snake[i].x = Snake[i+1].x  

         Snake[i].y = Snake[i+1].y  

      Snake[i].now = Snake[i+1].now  

  }  

      

  GameMap[ Snake[i].x ][ Snake[i].y ] = '#' //移动后要置为'#'蛇身   

 }  

}  

void Check_Border()  //检查蛇头是否越界  

{  

 if(Snake[0].x < 0 || Snake[0].x >= H  

 || Snake[0].y < 0 || Snake[0].y >= L)  

     over = 1  

}  

void Check_Head(int x, int y)  //检查蛇头移动后的位置情况  

{  

    

 if(GameMap[ Snake[0].x ][ Snake[0].y ] == '.')  //为空  

  GameMap[ Snake[0].x ][ Snake[0].y ] = '@'  

 else 

  if(GameMap[ Snake[0].x ][ Snake[0].y ] == '*')  //为食物  

  {  

   GameMap[ Snake[0].x ][ Snake[0].y ] = '@'    

   Snake[sum].x = x   //新增加的蛇身为蛇头后面的那个  

      Snake[sum].y = y  

      Snake[sum].now = Snake[0].now  

         GameMap[ Snake[sum].x ][ Snake[sum].y ] = '#'   

   sum++  

   Create_Food()  //食物吃完了马上再产生一个食物  

  }  

  else 

   over = 1  

}

#include<conio.h>#include<graphics.h>#include<time.h>#include<string.h>#include<malloc.h>#include<stdio.h>int grade=5,point=0,life=3void set(),menu(),move_head(),move_body(),move(),init_insect(),left(),upon(),right(),down(),init_graph(),food_f(),ahead(),crate()struct bug { int xint ystruct bug *laststruct bug *next}struct fd { int xint yint judge}food={0,0,0}struct bug *head_f=NULL,*head_l,*p1=NULL,*p2=NULLvoid main() { char chinitgraph(800,600)set()init_insect()while(1) { food_f()Sleep(grade*10)setcolor(BLACK)circle(head_l->x,head_l->y,2)setcolor(WHITE)move_body()if(kbhit()) { ch=getch()if(ch==27) { ahead()set()} else if(ch==-32) { switch(getch()) { case 72:upon()breakcase 80:down()breakcase 75:left()breakcase 77:right()break} } else ahead()} else { ahead()} if(head_f->x==food.x&&head_f->y==food.y) { Sleep(100)crate()food.judge=0point=point+(6-grade)*10if(food.x<30||food.y<30||food.x>570||food.y>570) life++menu()} if(head_f->x<5||head_f->x>595||head_f->y<5||head_f->y>595) { Sleep(1000)life--food.judge=0init_graph()init_insect()menu()} for(p1=head_f->nextp1!=NULLp1=p1->next) { if(head_f->x==p1->x&&head_f->y==p1->y) { Sleep(1000)life--food.judge=0init_graph()init_insect()menu()break} } if(life==0) { outtextxy(280,300,"游戏结束!")getch()return} move()}} void init_graph() { clearviewport()setlinestyle(PS_SOLID,1,5)rectangle(2,2,600,598)setlinestyle(PS_SOLID,1,1)} void set() { init_graph()outtextxy(640,50,"1、开始 / 返回")outtextxy(640,70,"2、退出")outtextxy(640,90,"3、难度")outtextxy(640,110,"4、重新开始")switch(getch()) { case '1': menu()setcolor(GREEN)circle(food.x,food.y,2)setcolor(WHITE)returncase '2': exit(0)breakcase '3': outtextxy(700,90,":1 2 3 4 5")grade=getch()-48set()breakcase '4': food.judge=0,grade=5point=0life=3init_insect()menu()breakdefault: outtextxy(250,300,"输入错误!")set()break} } void menu() { char str[20],str1[]={"分数:"},str2[]={"难度:"},str3[]={"生命值:"}init_graph()sprintf(str,"%d",point)strcat(str1,str)outtextxy(640,50,str1)sprintf(str,"%d",grade)strcat(str2,str)outtextxy(640,70,str2)sprintf(str,"%d",life)strcat(str3,str)outtextxy(640,90,str3)outtextxy(640,110,"设置:ESC")} void init_insect() { head_f=(struct bug *)malloc(sizeof(struct bug))head_f->last=NULLhead_f->x=300head_f->y=300p2=head_f->next=p1=(struct bug *)malloc(sizeof(struct bug))p1->last=head_fp1->x=295p1->y=300p1=p1->next=(struct bug *)malloc(sizeof(struct bug))p1->next=NULLp1->x=290p1->y=300p1->last=p2head_l=p1} void move() { for(p1=head_fp1!=NULLp1=p1->next) { circle(p1->x,p1->y,2)} } void move_head() { } void move_body() { for(p1=head_l,p2=p1->lastp2!=NULLp1=p2,p2=p2->last) { p1->x=p2->xp1->y=p2->y} } void ahead() { p1=head_fp2=p1->nextp2=p2->nextif(p1->x==p2->x) { if(p1->y>p2->y) head_f->y+=5else head_f->y-=5} else { if(p1->x>p2->x) { head_f->x+=5} else head_f->x-=5} } void upon() { p1=head_f->nextp1=p1->nexthead_f->y-=5if(p1->x==head_f->x&&p1->y==head_f->y) { head_f->y+=5ahead()} } void down() { p1=head_f->nextp1=p1->nexthead_f->y+=5if(p1->x==head_f->x&&p1->y==head_f->y) { head_f->y-=5ahead()} } void left() { p1=head_f->nextp1=p1->nexthead_f->x-=5if(p1->x==head_f->x&&p1->y==head_f->y) { head_f->x+=5ahead()} } void right() { p1=head_f->nextp1=p1->nexthead_f->x+=5if(p1->x==head_f->x&&p1->y==head_f->y) { head_f->x-=5ahead()} } void food_f() { if(!food.judge) { food.x=(rand()%117+1)*5food.y=(rand()%117+1)*5food.judge=1if(food.x<30||food.y<30||food.x>570||food.y>570) { setcolor(RED)circle(f