本文目录一览:
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;
}
c语言 贪吃蛇 程序
基本思路: 蛇每吃一个食物蛇身子就增加一格,用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 = 0; i < HEI; ++i)
{
SetConsoleCursorPosition(hout, pos);
for(j = 0; j < 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;
}
扩展资料: 实现逻辑
- 可以设置光标,就能实现制定位置打印制定符号。
- 涉及一个结构体,包含两个元素坐标元素和一个结构体指针。
- 结构体串联形成链表,遍历获取成员坐标,打印符号得到蛇身。
- 不断的加头,去尾,重新遍历坐标,再打印形成蛇的移动。
- 食物产生的位置判定,不能越界,也不能与蛇身体重合。
- 蛇的转向判定,一条规则,不允许倒退。
- 转向的实现,跟行进方向决定新的关节坐标(当前头的上下左右)
- 死亡检测,是否头节点坐标是否与墙壁重合,是否与身体其他关节重合。
- 加速减速,设置刷新休眠时间实现。 参考资料来源:百度百科-C语言
c语言贪吃蛇的速度控制程序怎么编
可以Sleep函数设置延时来控制贪吃蛇的速度。
函数名: Sleep
功 能: 执行挂起一段时间
用 法: void Sleep(DWORD dwMilliseconds);
在VC中使用带上头文件
#include windows.h
( Sleep函数存放头文件:WinBase.h)
在gcc编译器中,使用的头文件因gcc版本的不同而不同
#include unistd.h
Sleep()单位为毫秒,sleep()单位为秒(如果需要更精确可以用usleep单位为微秒)
返回值
若进程/线程挂起到参数所指定的时间则返回0,若有信号中断则返回剩余秒数。
例程:
/*--------------------snake.h--------------------*/
#ifndef SNAKE_H
#define SNAKE_H
#define LEFT 'a'
#define RIGHT 'd'
#define DOWN 's'
#define UP 'w'
#define ESC 27
#define N 200 /*蛇的最大长度*/
char key; /*控制按键*/
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;
#endif
/*--------------------snake.c--------------------*/
#include graphics.h
#include stdlib.h
#include conio.h
#include time.h
#include stdio.h
#include "snake.h"
int i,key;
int score=0;/*得分*/
int gamespeed=100; /*蛇运行速度*/
static void Init(void); /*图形驱动*/
static void Close(void); /*图形结束*/
static void Game_interface(void); /*游戏界面*/
static void GameOver(void); /*结束游戏*/
static void GamePlay(void); /*游戏过程*/
static void PrScore(void); /*输出成绩*/
/*主函数*/
int main(void)
{
Init(); /*图形驱动*/
Game_interface(); /*开始画面*/
GamePlay(); /*玩游戏具体过程*/
Close(); /*图形结束*/
return 0;
}
/*图形驱动*/
static void Init(void)
{
int gd=9,gm=2;
initgraph(gd,gm," ");
cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
static void Game_interface(void)
{
int i;
COORD pos = {BEG_X, BEG_Y};
for(i=50;i<=600;i+=10) /*画边框*/
{
SetConsoleCursorPosition(hout, pos);
for(j=0;j<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;
}
}
/*游戏主函数*/
static void GamePlay(void)
{
int i;
srand(time(NULL)); /*随机数发生器*/
food.yes = 1; /*1表示需要出现新食物,0表示已经存在食物*/
snake.life = 0; /*活着*/
snake.direction = RIGHT; /*方向往右*/
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<snake.node;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(BLACK); /*把画面上的食物东西去掉*/
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(RED); /*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);
Sleep(gamespeed); /*用延迟控制贪吃蛇速度*/
setcolor(BLACK); /*用黑色去除蛇的的最后一节*/
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=getch(); /*接收按键*/
if (key == ESC) break; /*按ESC键退出*/
switch(key)
{
case UP:
if(snake.direction != DOWN) /*判断是否往相反的方向移动*/
snake.direction = UP;
break;
case RIGHT:
if(snake.direction != LEFT)
snake.direction = RIGHT;
break;
case LEFT:
if(snake.direction != RIGHT)
snake.direction = LEFT;
break;
case DOWN:
if(snake.direction != UP)
snake.direction = DOWN;
break;
}
}/*endwhile(1)*/
}
/*游戏结束*/
static void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
setfont(56,0,"黑体");
outtextxy(200,200,"GAME OVER");
getch();
}
/*输出成绩*/
static void PrScore(void)
{
char str[10];
setfillstyle(YELLOW);
bar(50,15,220,35);
setcolor(BROWN);
setfont(16,0,"宋体");
sprintf(str,"score:%d",score);
outtextxy(55,16,str);
}
static void Close(void)
{
closegraph();
}
用c语言编写的贪食蛇游戏
这是一个成功的贪吃蛇代码(c语言编写的),希望你能看懂!慢慢看:
#define N 200
#include graphics.h
#include stdlib.h
#include dos.h
#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<snake.node;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<snake.node;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();
}
c语言贪吃蛇代码问题,按左右按一下不能一直移动,请帮忙改下?
/*
program by wlfryq 71693456@qq.com
*/
#include stdio.h
#include stdlib.h
#include conio.h
#include windows.h
#include time.h
#include direct.h
#include stdbool.h
#define W 80 //屏幕宽度
#define H 37 //屏幕高度
#define SNAKE_ALL_LENGTH 200 //蛇身最长为
void CALLBACK TimerProc(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime);
void start();
struct MYPOINT
{
int x;
int y;
} s[SNAKE_ALL_LENGTH] , head, end, food;
int max_count=0; //历史最高分,如果count>max_count, 则max_count=count
int old_max_count=0; //历史最高分,不会变动, 用于死亡时判断max_count是否大于old_max_count,如果大于,则写入文件
int count=0; //得分
int len=20; //当前蛇身长度
int direct=0; //方向: 0-向右, 1-向下, 2-向左, 3-向上
int speed=200; //速度:毫秒
bool isfood=false; //食物是否存在
int timerID;
bool stop=false; //暂停
char* ini_path; //数据文件绝对路径
void setxy(int x, int y) //设置CMD窗口光标位置
{
COORD coord = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void hide_cursor() //隐藏CMD窗口光标
{
CONSOLE_CURSOR_INFO cci;
cci.bVisible = FALSE;
cci.dwSize = sizeof(cci);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle, cci);
}
void set_food() //设置食物坐标
{
if(isfood==true)
{
return;
}
int x,y,i;
bool flag=false;
while(1)
{
flag=false;
x=rand()%(W-14)+6;
y=rand()%(H-12)+6;
for(i=0;i<len;i++) //判断食物是否落在蛇身上
{
if(s[i].x==x && s[i].y==y)
{
flag=true;
break;
}
}
if(flag==true)
{
continue;
}
else
{
food.x=x;
food.y=y;
break;
}
}
setxy(food.x,food.y);
printf("*");
isfood=true;
}
void check_board() //检测蛇身是否越界和相交
{
int i;
if(s[0].x>=W-3 || s[0].x<=2 || s[0].y>=H-1 || s[0].y<=2)
{
setxy(W/2-5,0);
printf("game over\n");
stop=true;
if(old_max_count<max_count)
{
char t[5]={'\0'};
sprintf(t,"%d",max_count);
WritePrivateProfileString("MAX_COUNT","max_count",t,ini_path);
}
}
for(i=1;i<len;i++)
{
if(s[i].x==s[0].x && s[i].y==s[0].y)
{
setxy(W/2-5,0);
printf("game over\n");
stop=true;
if(old_max_count<max_count)
{
char t[5]={'\0'};
sprintf(t,"%d",max_count);
WritePrivateProfileString("MAX_COUNT","max_count",t,ini_path);
}
break;
}
}
if(stop==true)
{
KillTimer(NULL,timerID);
int c;
while(1)
{
fflush(stdin);
c=_getch();
if(c=='n' || c=='N')
{
start();
}
else if(c=='q' || c=='Q')
{
exit(0);
}
else continue;
}
}
}
void printf_body(bool is_first) //打印蛇身
{
if(is_first==true) //如果是第一次打印蛇身
{
int i;
for(i=0;i<len;i++)
{
setxy(s[i].x,s[i].y);
printf("O");
}
}
else //如果不是第一次打印蛇身
{
setxy(end.x,end.y);
printf(" ");
setxy(s[0].x,s[0].y);
printf("O");
}
if(food.x==s[0].x && food.y==s[0].y) //如果吃到食物
{
count++;
isfood=false; //重置食物
set_food();
len++;
KillTimer(NULL,timerID);
if(speed>100) speed-=10;
else if(speed>50) speed-=5;
else if(speed>30) speed-=2;
else if(speed>16) speed-=1;
else ;
setxy(0,0);
if(max_count<count) max_count=count;
printf(" speed : %d ms score : %d best score:%d ",speed,count,max_count);
timerID=SetTimer(NULL,001,speed,TimerProc);
}
}
void change_body_pos(int x, int y) //改变蛇身的坐标数据
{
end.x=s[len-1].x;
end.y=s[len-1].y;
int i;
for(i=len-1;i>0;i--)
{
s[i].x=s[i-1].x;
s[i].y=s[i-1].y;
}
s[0].x=x;
s[0].y=y;
}
void CALLBACK TimerProc(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
switch(direct)
{
case 0:
head.x++;
change_body_pos(head.x,head.y);
printf_body(false);
check_board();
break;
case 1:
head.y++;
change_body_pos(head.x,head.y);
printf_body(false);
check_board();
break;
case 2:
head.x--;
change_body_pos(head.x,head.y);
printf_body(false);
check_board();
break;
case 3:
head.y--;
change_body_pos(head.x,head.y);
printf_body(false);
check_board();
break;
}
}
void start()
{
int i;
KillTimer(NULL,timerID);
count=0; //得分
len=20; //当前蛇身长度
direct=0; //方向: 0-向右, 1-向下, 2-向左, 3-向上
speed=200; //速度:毫秒
isfood=false; //食物是否存在
stop=false; //停止
system("cls");
setxy(1,4);
printf("┌─────────────────────────────────────┐\n");
for(i=0;i<33;i++)
{
printf(" │ │\n");
}
printf(" └─────────────────────────────────────┘");
head.x=len-1+5;
head.y=H/2;
for(i=0;i<len;i++)
{
s[i].x=head.x-i;
s[i].y=head.y;
}
setxy(0,0);
printf(" speed : %d:ms score : %d best score:%d ",speed,count,max_count);
printf_body(true);
set_food();
timerID=SetTimer(NULL,001,speed,TimerProc);
int c;
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
if(stop==true) break;
if(_kbhit()) //如果按下的是方向键或功能键, _getch()要调用两次,第一次返回0XE0或0
{
fflush(stdin);
c=_getch(); //上: 72 下:80 左:75 右:77
if(c==0XE0 || c==0)
{
c=_getch();
if(c==72 && direct!=1 && direct!=3)
{
direct=3;
}
else if(c==80 && direct!=1 && direct!=3)
{
direct=1;
}
else if(c==75 && direct!=0 && direct!=2)
{
direct=2;
}
else if(c==77 && direct!=0 && direct!=2)
{
direct=0;
}
}
else if(c==' ')
{
setxy(W/2-10,0);
system("pause");
setxy(W/2-10,0);
printf(" ");
}
}
if(msg.message==WM_TIMER)
{
DispatchMessage(&msg);
}
}
}
int main()
{
ini_path=(char*)malloc(sizeof(char)*50);
srand((unsigned)time(0));
getcwd(ini_path,50);//取得当前程序绝对路径
ini_path=strcat(ini_path,"snake.dat");
max_count=GetPrivateProfileInt("MAX_COUNT","max_count",0,ini_path);
old_max_count=max_count;
char cmd[50];
sprintf(cmd,"mode con cols=%d lines=%d\0",W,H);
system(cmd);//改变CMD窗口大小
hide_cursor();
start();
return 0;
}
如何用C语言写贪吃蛇
#include conio.h
#include graphics.h
#include time.h
#include string.h
#include malloc.h
#include stdio.h
int grade=5,point=0,life=3;
void set(),menu(),move_head(),move_body(),move(),init_insect(),food_f(),ahead(),crate();
struct bug
{
int x;
int y;
struct bug *last;
struct bug *next;
};
struct fd
{
int x;
int y;
int judge;
}food={0,0,0};
struct bug *head_f=NULL,*head_l,*p1=NULL,*p2=NULL;
void main()
{
char ch;
initgraph(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();break;
case 80:down();break;
case 75:left();break;
case 77:right();break;
}
}
else
ahead();
}
else
{
ahead();
}
if(head_f->x==food.x&&head_f->y==food.y)
{
Sleep(100);
crate();
food.judge=0;
point=point+(6-grade)*10;
if(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=0;
init_graph();
init_insect();
menu();
}
for(p1=head_f->next;p1!=NULL;p1=p1->next)
{
if(head_f->x==p1->x&&head_f->y==p1->y)
{
Sleep(1000);
life--;
food.judge=0;
init_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);
return;
case '2':
exit(0);
break;
case '3':
outtextxy(700,90,":1 2 3 4 5");
grade=getch()-48;
set();
break;
case '4':
food.judge=0,grade=5;
point=0;
life=3;
init_insect();
menu();
break;
default:
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=NULL;
head_f->x=300;
head_f->y=300;
p2=head_f->next=p1=(struct bug *)malloc(sizeof(struct bug));
p1->last=head_f;
p1->x=295;
p1->y=300;
p1=p1->next=(struct bug *)malloc(sizeof(struct bug));
p1->next=NULL;
p1->x=290;
p1->y=300;
p1->last=p2;
head_l=p1;
}
void move()
{
for(p1=head_f;p1!=NULL;p1=p1->next)
{
circle(p1->x,p1->y,2);
}
}
void move_head()
{
}
void move_body()
{
for(p1=head_l,p2=p1->last;p2!=NULL;p1=p2,p2=p2->last)
{
p1->x=p2->x;
p1->y=p2->y;
}
}
void ahead()
{
p1=head_f;
p2=p1->next;
p2=p2->next;
if(p1->x==p2->x)
{
if(p1->y<p2->y)
head_f->y+=5;
else
head_f->y-=5;
}
else
{
if(p1->x<p2->x)
{
head_f->x+=5;
}
else
head_f->x-=5;
}
}
void upon()
{
p1=head_f->next;
p1=p1->next;
head_f->y-=5;
if(p1->x==head_f->x&&p1->y==head_f->y)
{
head_f->y+=5;
ahead();
}
}
void down()
{
p1=head_f->next;
p1=p1->next;
head_f->y+=5;
if(p1->x==head_f->x&&p1->y==head_f->y)
{
head_f->y-=5;
ahead();
}
}
void left()
{
p1=head_f->next;
p1=p1->next;
head_f->x-=5;
if(p1->x==head_f->x&&p1->y==head_f->y)
{
head_f->x+=5;
ahead();
}
}
void right()
{
p1=head_f->next;
p1=p1->next;
head_f->x+=5;
if(p1->x==head_f->x&&p1->y==head_f->y)
{
head_f->x-=5;
ahead();
}
}
void food_f()
{
if(!food.judge)
{
food.x=(rand()%117+1)*5;
food.y=(rand()%117+1)*5;
food.judge=1;
if(food.x<30||food.y<30||food.x>570||food.y>570)
life++;
menu();
}
}
void crate()
{
p1=head_l;
p1->next=p2=(struct bug *)malloc(sizeof(struct bug));
p2->last=p1;
p2->next=NULL;
p2->x=p1->x;
p2->y=p1->y;
head_l=p2;
}