C语言的贪吃蛇源代码

Python019

C语言的贪吃蛇源代码,第1张

 

//******友情提示:如想速度快点,请改小_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  

}

基本思路:

蛇每吃一个食物蛇身子就增加一格,用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语言

#include<stdio.h>

#include<stdlib.h>

#include<Windows.h>

#include<conio.h>

#include<time.h>

char gamemap[20][40]//游戏地图大小 20*40

int score=0//当前分数

//记录蛇的结点

int x[800]//每个结点的行编号

int y[800]//每个结点的列编号

int len = 0//蛇的长度

//记录水果信息

int fx=0//食物的横坐标

int fy=0//食物的纵坐标

int fcount=0//食物的数目

//主要函数操作

void createfood()//生成食物

void PrintgameMap(int x[],int y[])//画游戏地图

void move(int x[],int y[])//移动蛇

int main()

{

srand(time(NULL))

//初始化蛇头和身体的位置,默认刚开始蛇长为2

x[len] = 9

y[len] = 9

len++

x[len] = 9

y[len] = 8

len++

createfood()

PrintgameMap(x,y)

move(x,y)

return 0

}

void createfood()

{

if(0==fcount)

{

int tfx=rand()%18+1

int tfy=rand()%38+1

int i,j

int have=0//为0表示食物不是食物的一部分

for(i=0i<leni++)

{

for(j=0j<lenj++)

{

if(x[i]==fx&&y[j]==fy)

{

have=1

break

}

else

{

have=0

}

}

if(1==have)//若为蛇的一部分,执行下一次循环

{

continue

}

else//否则生成新的水果

{

fcount++

fx=tfx

fy=tfy

break

}

}

}

}

//游戏地图

void PrintgameMap(int x[],int y[])

{

int snake = 0,food=0

int i, j

//画游戏地图,并画出蛇的初始位置

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

{

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

{

if (i == 0 &&j >= 1 &&j <= 38)

{

gamemap[i][j] = '='

}

else if (i == 19 &&j >= 1 &&j <= 38)

{

gamemap[i][j] = '='

}

else if (j == 0 || j == 39)

{

gamemap[i][j] = '#'

}

else

{

gamemap[i][j] = ' '

}

//判断蛇是否在当前位置

int k

for ( k = 0k <lenk++)

{

if (i == x[k]&&j == y[k])

{

snake = 1

break

}

else

{

snake = 0

}

}

{

if(fcount&&fx==i&&fy==j)

{

food=1

}

else

{

food=0

}

}

//若蛇在当前位置

if (1==snake )

{

printf("*")

}

else if(1==food)

{

printf("f")

}

//若蛇不在当前位置并且当前位置没有水果

else

{

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

}

}

printf("\n")

}

printf("score:%d",score)

}

//移动

void move(int x[],int y[])

{

char s

s=getch()

int move=0,beat=0

while (1)

{

int cx[800]

int cy[800]

memcpy(cx, x, sizeof(int)*len)

memcpy(cy, y, sizeof(int)*len)

//头

if (s=='w')

{

x[0]--

move=1

if(x[0]<=0)

{

printf("Game over\n")

break

}

}

else if (s=='s')

{

x[0]++

move=1

if(x[0]>=19)

{

printf("Game over\n")

break

}

}

else if (s=='a')

{

y[0] --

move=1

if(y[0]<=0)

{

printf("Game over\n")

break

}

}

else if (s=='d')

{

y[0]++

move=1

if(y[0]>=39)

{

printf("Game over\n")

break

}

}

//身体

int i

for ( i = 1i <leni++)

{

x[i] = cx[i - 1]

y[i] = cy[i - 1]

}

for(i=1i<leni++)//要是咬到了自己

{

if(x[0]==x[i]&&y[0]==y[i])

{

beat=1

}

else

{

beat=0

}

}

if(1==beat)

{

printf("Game over\n")

break

}

if(1==move)

{

if(fcount&&x[0]==fx&&y[0]==fy)//如果吃到了果子

{

//拷贝当前蛇头地址到第二个结点

memcpy(x+1,cx,sizeof(int)*len)

memcpy(y+1,cy,sizeof(int)*len)

len++

fcount--

fx=0

fy=0

score++

createfood()

}

Sleep(70)

system("cls")

PrintgameMap( x, y)

}

else

continue

if(kbhit())//判断是否按下按键

{

s=getch()

}

}

}