Snake.h
#ifndef _SNAKE_H_
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<assert.h>
#include<time.h>
#define _SNAKE_H_
#define FOOD "■"
#define INIT_X 24
#define INIT_Y 5
//蛇的节点
typedef struct node{
int _x;
int _y;
struct node *_next;
}SnakeNode,*pSnakeNode;
//蛇的行走方向
enum DIRECTION{UP=1,DOWN,LEFT,RIGHT};
//蛇的当前状态
enum Status{OK,KILL_BY_SELF,KILL_BY_WALL};
//蛇本身
typedef struct snake{
pSnakeNode _pSnake;//蛇头指针
pSnakeNode _pFood;//蛇的食物
enum DIRECTION _Dir;//蛇行走的方向
enum Status _status;//蛇的当前状态
int _SleepTime;//每走一步停一步的时间
int _grade;
}Snake,*pSnake;
void DropMap();
void SetPos(int x,int y);
void Welcome();
int NextHasFood(pSnake ps,pSnakeNode newNode);
void EatFood(pSnake ps,pSnakeNode newNode);
void NoFood(pSnake ps,pSnakeNode newNode);
void KillBySelf(pSnake ps);
void KillByWall(pSnake ps);
void SnakeRun(pSnake ps);
void test1();
#endif
Snake.c
#include"snake.h"
//设置光标所在位置
void SetPos(int x,int y){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = {0};
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(handle,pos);
}
//绘制地图
void DropMap(){
int i;
system("cls");
for(i=0;i<58;i+=2){
SetPos(i,0);
printf(FOOD);
}
for(i=0;i<26;i++){
SetPos(0,i);
printf(FOOD);
SetPos(58,i);
printf(FOOD);
}
for(i=0;i<=58;i+=2){
SetPos(i,26);
printf(FOOD);
}
SetPos(66,3);
printf("分数:0");
SetPos(66,5);
printf("按空格加速/减速");
}
//初始化蛇
void InitSnake(pSnake ps){
pSnakeNode cur=NULL;
int i=0;
cur = (pSnakeNode)malloc(sizeof(SnakeNode));
memset(cur,0,sizeof(SnakeNode));
cur->_x=INIT_X;
cur->_y=INIT_Y;
cur->_next=NULL;
ps->_SleepTime = 500;
ps->_status = OK;
ps->_Dir = RIGHT;
ps->_grade = 0;
for(i=1;i<=4;i++){
ps->_pSnake = (pSnakeNode)malloc(sizeof(SnakeNode));
ps->_pSnake->_next = cur;
ps->_pSnake->_x = INIT_X+i*2;
ps->_pSnake->_y = INIT_Y;
cur=ps->_pSnake;
}
while(cur!=NULL){
SetPos(cur->_x,cur->_y);
printf(FOOD);
cur= cur->_next;
}
}
void CreateFood(pSnake ps){
pSnakeNode food = NULL;
pSnakeNode cur = NULL;
food = (pSnakeNode)malloc(sizeof(SnakeNode));
srand(time(NULL));
again:
memset(food,0,sizeof(SnakeNode));
do{
food->_x=rand()%56+2;
}while(food->_x%2!=0);
food->_y = rand()%25+1;
cur = ps->_pSnake;
while(cur!=NULL){
if(cur->_x == food->_x&&cur->_y == food->_y){
goto again; //返回到again
}
cur = cur->_next;
}
SetPos(food->_x,food->_y);
printf(FOOD);
ps->_pFood=food;
}
void Welcome(){
system("color 73");
system("mode con cols=100 lines=32");
SetPos(25,6);
printf("贪吃蛇游戏\n");
SetPos(22,8);
printf("↑ ↓ ← → 控制方向\n");
}
void start(pSnake ps){
Welcome();
getchar();
DropMap();
InitSnake(ps);
CreateFood(ps);
}
int NextHasFood(pSnake ps,pSnakeNode newNode){
return (ps->_pFood->_x==newNode->_x) && (ps->_pFood->_y==newNode->_y);
}
void EatFood(pSnake ps,pSnakeNode newNode){
pSnakeNode cur = ps->_pSnake;
newNode->_next = cur;
ps->_pSnake = newNode;
cur = ps->_pSnake;
ps->_grade+=4;
while(cur!=NULL){
SetPos(cur->_x,cur->_y);
printf(FOOD);
cur=cur->_next;
}
if(ps->_SleepTime>300)
ps->_SleepTime-=100;
else if(ps->_SleepTime>100)
ps->_SleepTime-=50;
SetPos(72,3);
printf("%d",ps->_grade);
CreateFood(ps);
}
void NoFood(pSnake ps,pSnakeNode newNode){
pSnakeNode cur = ps->_pSnake;
newNode->_next = cur;
ps->_pSnake = newNode;
cur=ps->_pSnake;
while(cur->_next->_next!=NULL){
SetPos(cur->_x,cur->_y);
printf(FOOD);
cur=cur->_next;
}
SetPos(cur->_next->_x,cur->_next->_y);
printf(" ");
free(cur->_next);
cur->_next=NULL;
}
enum DIRECTION getDir(pSnake ps){
do{
if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=DOWN)
ps->_Dir=DOWN;
if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=UP)
ps->_Dir=UP;
if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=LEFT)
ps->_Dir=LEFT;
if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=RIGHT)
ps->_Dir=RIGHT;
}while(ps->_status==OK);
return ps->_Dir;
}
void SnakeMove(pSnake ps){
pSnakeNode newNode = (pSnakeNode)malloc(sizeof(SnakeNode));
memset(newNode,0,sizeof(SnakeNode));
newNode->_x = ps->_pSnake->_x;
newNode->_y = ps->_pSnake->_y;
switch(ps->_Dir){
case UP:
newNode->_y--;
break;
case DOWN:
newNode->_y++;
break;
case LEFT:
newNode->_x-=2;
break;
case RIGHT:
newNode->_x+=2;
break;
default:
break;
}
if(NextHasFood(ps,newNode)){
EatFood(ps,newNode);
}
else{
NoFood(ps,newNode);
}
}
void KillBySelf(pSnake ps){
pSnakeNode cur = ps->_pSnake->_next;
while(cur){
if(cur->_x==ps->_pSnake->_x&&cur->_y==ps->_pSnake->_y){
ps->_status=KILL_BY_SELF;
SetPos(66,7);
printf("自杀");
SetPos(0,27);
}
cur = cur->_next;
}
}
void KillByWall(pSnake ps){
if(ps->_pSnake->_x==0||ps->_pSnake->_x==58||
ps->_pSnake->_y==0||ps->_pSnake->_y==26){
ps->_status = KILL_BY_WALL;
SetPos(66,7);
printf("撞墙");
SetPos(0,27);
}
}
void SnakeRun(pSnake ps){
int flag = 0;
do{
if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=UP){
ps->_Dir = DOWN;
}
else if(GetAsyncKeyState(VK_UP)&&ps->_Dir!=DOWN){
ps->_Dir = UP;
}
else if(GetAsyncKeyState(VK_LEFT)&&ps->_Dir!=RIGHT){
ps->_Dir = LEFT;
}
else if(GetAsyncKeyState(VK_RIGHT)&&ps->_Dir!=LEFT){
ps->_Dir = RIGHT;
}
else if(GetAsyncKeyState(VK_SPACE)){ //按下空格来控制蛇的加速减速
if(flag==0){
ps->_SleepTime/=2;
flag=1;
}
else if(flag==1){
ps->_SleepTime*=2;
flag=0;
}
}
SnakeMove(ps);
KillBySelf(ps);
KillByWall(ps);
Sleep(ps->_SleepTime);
}while(ps->_status == OK);
}
void test1(){
Snake snake;
start(&snake);
SnakeRun(&snake);
}
main.c
#include"snake.h"
int main(){
test1();
getchar();
system("pause");
return 0;
}