2020-06-19

贪吃蛇重点在于蛇身位置的更新

//#include “stdafx.h” 如果是vc环境的话加上该头文件
#include<stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define TURNUP 1 //宏定义蛇运动的四个方向
#define TURNDOWN 2
#define TURNRIGHT 3
#define TURNLEFT 4
#define MAXROW 20
#define MAXCOL 30

void printSnake(int bodylen,COORD bodypos[]);
void run (int bodylen,COORD body,int dirction,int times);
void initSnake (int bodylen,COORD
body,COORD head);
void disappeartSnake(int bodylen,COORD *bodypos);
void createFood();
void printwall();
void printscore(int len);
void supervisekeybot(COORD *body,int direction,int times);
void createFood1();

int len=5;
COORD gfoodPos; //定义三个全局变量,身体长度和两种食物 坐标
COORD gfoodPos1; // COORD为系统定义结构体,可实现屏幕坐标表示

int main(int argc, char* argv[])
{
int direction=TURNRIGHT;//没有按键输入时默认的初始方向

COORD body[20]={0};
COORD head={1,1};          

printwall();
initSnake (len,body,head);//根据head初始化蛇的身体
printSnake(len,body);     //打印初始的蛇
createFood();
createFood1();

supervisekeybot(body,direction,10);

return 0;

}

/*******************************************
函数名称:printSnake
函数功能:打印蛇的身体
函数参数:bodylen --身体的长度
bodypos --蛇身体的坐标
函数返回:
函数作者:forxn@qq.com
********************************************/
void printSnake(int bodylen,COORD bodypos)
{
//调用库函数,获取蛇身体的坐标,并在该坐标点打印信息,蛇头为8,蛇身为

HANDLE hOut;
COORD pos=bodypos[bodylen-1];
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
printf(“8\n”);
for(int i=0;i<bodylen-1;i++)
{
HANDLE hOut;
//获取蛇身体的坐标
COORD pos=bodypos[i];
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
//打印该点
printf("*\n");

}

}

/*******************************************
函数名称:changeDirction
函数功能:实现蛇的转弯,或者说蛇身体的更新
该函数为整个贪吃蛇的核心点,核心思想为以蛇头坐标为起点,
此程序将蛇头坐标定为body[len-1];
后面点的坐标都取其前一个点的的位置
********************************************/
void changeDirction(int bodylen,COORD *body,int dirction)
{
int p=bodylen;
for(int i=0;bodylen>1;bodylen–)
{
body[i]=body[i+1];
i++;
}
switch (dirction)
{
case TURNUP :
{
body[p-1].Y–;
break;
}
case TURNDOWN :
{
body[p-1].Y++;
break;
}
case TURNRIGHT:
{
body[p-1].X++;
break;
}
case TURNLEFT :
{
body[p-1].X–;
break;
}
default:
{
break;
}
}
//吃到食物的时候
if(body[p-1].XgfoodPos.X
&&body[p-1].Y
gfoodPos.Y)
{

    body[p].X=body[p-1].X;
    body[p].Y=body[p-1].Y;
    len++;
    createFood();
    printscore(bodylen);

}

else if(body[p-1].XgfoodPos1.X //此处必须加else;不然有bug
&&body[p-1].Y
gfoodPos1.Y)
{
body[p].X=body[p-1].X;
body[p].Y=body[p-1].Y;
body[p+1].X=body[p].X;
body[p+1].Y=body[p].Y;
len=len+2;
createFood1();
printscore(bodylen);
}

//边界检测
if(body[p-1].X==0||body[p-1].Y==0||body[p-1].X==MAXCOL||body[p-1].Y==MAXROW)
{
    COORD a;
    a.X=5;
    a.Y=10;
    HANDLE hOut;
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,a);  
    printf("GAME  OVER!");
    printSnake(len,body);  
    exit(0);

}


for (int j=0;j<p;j++)
{
    if (body[p-1].X==body[p-j-2].X&&body[p-1].Y==body[p-j-2].Y)
    {
        COORD b;
        b.X=5;
        b.Y=10;
        HANDLE hOut;
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,b);  
        printf("GAME  OVER!");
        printSnake(len,body);  
        exit(0);
    }

}

}

/*******************************************
函数功能:
函数参数:
********************************************/
void run (int bodylen,COORD *body,int dirction,int times)
{
for(int i=0;i<times;i++)
{
//重新设置蛇身体的点坐标
changeDirction(bodylen,body,dirction);

    printSnake(bodylen,body);
    Sleep(200);
    disappeartSnake(bodylen,body);
}          

}
/*******************************************
函数功能:
函数参数:
********************************************/

void initSnake (int bodylen,COORD* body,COORD head)
{
for (int i=0;i<bodylen;i++)
{
body[bodylen-i-1].X=head.X;
body[bodylen-1-i].Y=head.Y;

}

}

/*******************************************
函数功能:产生食物,调用rand函数随机位置产生两种食物
函数参数:
********************************************/
void createFood()
{
srand(time(0));
int x=rand()%(MAXCOL-1);
int y=rand()%(MAXROW-1);

gfoodPos.X=x;
gfoodPos.Y=y;
if(gfoodPos.X==0||gfoodPos.Y==0)
{
    createFood();
}

    HANDLE hOut;
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,gfoodPos);
    printf("A\n");

}
void createFood1()
{
//srand(time(0));
int x=rand()%(MAXCOL-1);
int y=rand()%(MAXROW-1);

gfoodPos1.X=x;
gfoodPos1.Y=y;
if(gfoodPos1.X==0||gfoodPos1.Y==0)
{
    createFood1();
}

    HANDLE hOut;
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,gfoodPos1);
    printf("B\n");

}
/*******************************************
函数功能:蛇身体的更新,调用system(“cls”)不能满足要求
将坐标点依次打印空格可实现“清屏”效果
函数参数:
********************************************/

void disappeartSnake(int bodylen,COORD *bodypos)
{
for(int i=0;i<bodylen;i++)
{
HANDLE hOut;
COORD pos=bodypos[i];
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
printf(" \n");

}

}

/*******************************************
函数功能:打印墙的边界
函数参数:
********************************************/
void printwall()
{
for(int i=0;i<=MAXROW;i++)
{
for(int j=0;j<=MAXCOL;j++)
{
if(i0||j0||iMAXROW||jMAXCOL)
putchar(’#’);
else
printf(" ");
}
putchar(’\n’);
}
}

/*******************************************
函数功能:检测键盘的按键,实现蛇的实时控制
函数参数:
********************************************/
void supervisekeybot(COORD *body,int direction,int times)
{
while(1) // 蛇开始移动并监测键盘
{
run (len,body,direction,1);
printscore(len);
if(_kbhit())//监测键盘是否有输入,也可采用多线程实现,此处调用_kbhit()
{
char ch=getch();
switch (ch)
{
case ‘w’:
{
run (len,body,TURNUP,1);//此时times设置为1,才能实现实时控制响应;
direction=TURNUP; //键盘键入时蛇的方向更新并维持
break;
}
case ‘s’:
{
run (len,body,TURNDOWN,1);
direction=TURNDOWN;
break;
}
case ‘a’:
{
run (len,body,TURNLEFT,1);
direction=TURNLEFT;
break;
}
case ‘d’:
{
run (len,body,TURNRIGHT,1);
direction=TURNRIGHT;
break;
}
}
}

}

}
/*******************************************
函数功能:将蛇的身体长度打印,作为分数
函数参数:
********************************************/
void printscore(int len)
{
COORD score;
score.X=32;
score.Y=12;
HANDLE hOut;
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,score);
printf(“SCORE:%d”,len);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值