C语言贪吃蛇 传送、躲避、加速、追击版

 

1.随机传送

2.鼠标选点传送

3.食物躲避蛇的追击

4.蛇自动搜索路径

5.贪吃蛇的基本操作

这是这个贪吃蛇的大概内容     

 

代码如下:

 

/*

作者:黄铭杰
QQ:1024725390
最后修改日期:2018.6.19
*/
#include<time.h>
#include<stdio.h>
#include<string.h>
#include <conio.h>
#include<windows.h>
#include<iostream.h>
#define ontimer(C,MS,CODE) (clock()-C>(MS)&&((CODE),C=clock()))//定义计时器ontime(计时变量,间隔时间,需要执行的表达式)
extern "C" WINBASEAPI HWND WINAPI GetConsoleWindow ();   //GetConsoleWindow ()函数声明
HWND hwnd=GetConsoleWindow();    //窗口句柄
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);  //输出句柄
HWND hwnd1=GetActiveWindow();     //绘图窗口句柄
UINT map[35][35]={0},tally[2]={0},x,y,x1,y1,x2,y2,x3,y3,a=100,b=100,c1=100,d1=100,score,speed,flag,ch=0,diffcult,time1[3]={0};




typedef struct she
{
int x,y;
char dir;   //方向
she *next;
}snake;
snake *head = new snake,*tail = head; 




void color(char a);      //颜色函数
void __cdecl outtextxy(int x,int y,const char *str,...);   //控制输出
void Hide();             //隐藏光标
void move(int x,int y);  //蛇移动
void add(int x,int y);   //蛇增长
void dead();             //死亡判断
void change();           //改变方向
void door();             //随机传送
void superdoor();        //鼠标选点传送
void AI();               //食物躲避蛇的追击判断
void AI2();              //鬼畜模式,食物随机移动,因为比例不同    食物更高几率大范围移动
void AI3();              //不可思议走位模式    为了游戏可玩性,限制食物的范围
int mima();              //管理员密码
void startgame();        //开始游戏
void window();           //窗口建立
void menu();             //主菜单
void end();              //死亡销毁链表
bool road(char ch);      //代练路径
void AI6();              //代练
void POSE();             //暂停






void __cdecl outtextxy(int x,int y,const char *str,...)   //控制输出
{
    COORD pos={y*2,x};  //控制光标位置
    SetConsoleCursorPosition(hOut,pos);  //通过修改pos.X和pos.Y的值就可以实现光标的位置控制
va_list arg_ptr;     //va_list 型变量
va_start(arg_ptr,str);   //宏初始化该变量
//va_arg(arg_ptr,char);    //对后面的变量进行处理
vprintf(str,arg_ptr);    //输出
va_end(arg_ptr);  //将存放可变参数字符串的变量清空
}


void color(char a)//颜色函数
{  
if(a=='1')
SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_RED); //是API设置字体颜色和背景色的函数,GetStdHandle是一个Windows API函数。它用于从一个特定的标准设备中取得一个句柄
if(a=='2')
SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_GREEN);
if(a=='3')
SetConsoleTextAttribute(hOut,FOREGROUND_GREEN|FOREGROUND_BLUE);
}


void Hide()  //隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}


/*void locate()   
{
LONG zx = -1;  
    LONG zy = -1;  
    POINT ptB = { 0, 0 };  
    while (1)  
    {                 
        LPPOINT xy = &ptB;  //位置变量  
        GetCursorPos(xy);   //获取鼠标当前位置
        ScreenToClient(hwnd1, &ptB); // 将鼠标指针位置转换为窗口坐标
        //如果鼠标移动,(即当前的坐标改变则打印出坐标)打印出做坐标。  
        if ((zx != xy->x) || (zy != xy->y))  
        {    
            zx = xy->x;  
            zy = xy->y; 
if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(zy-30)/16;
y3=(zx-10)/16; 
if(x3<35&&y3<35)break;
}
        }             
    }
}*/


void move(int x,int y)    //蛇移动
{
char di;
di=head->dir;
map[tail->x][tail->y]=0;
outtextxy(head->x,head->y,"■");
outtextxy(tail->x,tail->y,"  ");
head->next=tail;
head=head->next;
map[x][y]=1;
head->x=x;
head->y=y;
head->dir=di;
outtextxy(x,y,"◆");
tail=tail->next;
}


void add(int x,int y)    //蛇增长
{
outtextxy(head->x,head->y,"■");
head->next=new snake;
head->next->dir=head->dir;
head=head->next;
head->x=x;
head->y=y;
map[x][y]=1;
outtextxy(x,y,"◆");
x1=rand()%35; /
y1=rand()%35;
map[x1][y1]=2;
outtextxy(x1,y1,"★");
outtextxy(8,42,"%d  ",score+=50);
outtextxy(4,42,"%d  ",speed>60?--speed:speed);
}


void dead()    //死亡判断
{
if(head->dir=='W')
{
if(x>0 && map[x-1][y]==0)
move(--x,y);
else if(map[x-1][y]==2)
add(--x,y);
else
end();
}


else if(head->dir=='A')
{
if(y>0 && map[x][y-1]==0)
move(x,--y);
else if(map[x][y-1]==2)
add(x,--y);
else
end();
}
else if(head->dir=='S')
{
if(x<34 && map[x+1][y]==0)
move(++x,y);
else if(map[x+1][y]==2)
add(++x,y);
else
end();
}
else if(head->dir=='D')
{
if(y<34 && map[x][y+1]==0)
move(x,++y);
else if(map[x][y+1]==2)
add(x,++y);
else
end();
}
}


void change()    //改变方向
{
if(GetAsyncKeyState('W')& 1)
{
if(head->dir!='S')
head->dir='W';
}
else if(GetAsyncKeyState('A')& 1)
{
if(head->dir!='D')
head->dir='A';
}
else if(GetAsyncKeyState('S')& 1)
{
if(head->dir!='W')
head->dir='S';
}
else if(GetAsyncKeyState('D')& 1)
{
if(head->dir!='A')
head->dir='D';
}
else if(GetAsyncKeyState('E'))
door();
else if(GetAsyncKeyState('R'))
superdoor();
else if(GetAsyncKeyState('P')& 1)
POSE();
if(c1!=100&&d1!=100)
{
outtextxy(c1,d1,"卍");
outtextxy(x3,y3,"卍");
if(tail->x==c1 && tail->y==d1)
{
outtextxy(c1,d1,"  ");
outtextxy(x3,y3,"  ");
c1=100;d1=100;
}
}
if(a!=100&&b!=100)
{
outtextxy(a,b,"卍");
outtextxy(x2,y2,"卍");
if(tail->x==a&&tail->y==b)
{
outtextxy(a,b,"  ");
outtextxy(x2,y2,"  ");
a=100;b=100;
}
}

dead();
}


void POSE()//暂停
{
while(1)
{
if(GetAsyncKeyState('P')& 1)break;
}
}


void door()    //随机传送
{
if(score>=100)
{
while(1)
{
x2=rand()%35; 
y2=rand()%35;
if(!map[x2][y2])
break;
}
a=x;b=y;
x=x2;y=y2;
outtextxy(8,42,"%d  ",score-=100);
}
}


void superdoor()    //鼠标选点传送
{
RECT rect;
GetWindowRect(hwnd,&rect);     //获取窗口左上角坐标
int left = rect.left;
int top = rect.top;

LONG zx = -1;  
    LONG zy = -1;  
    POINT ptB = { 0, 0 };
if(score>=300)
{
//locate();  
while (1)  
{                 
LPPOINT xy = &ptB;  //位置变量  
GetCursorPos(xy);   //获取鼠标当前位置
ScreenToClient(hwnd1, &ptB); // 将鼠标指针位置转换为窗口坐标
//如果鼠标移动,(即当前的坐标改变则打印出坐标)打印出做坐标。  
/*if ((zx != xy->x) || (zy != xy->y))  
{    
zx = xy->x;  
zy = xy->y; 
if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(zy-30)/16;
y3=(zx-10)/16; 
if(x3<35&&y3<35)break;
}
}   */  
/*if(GetAsyncKeyState(VK_LBUTTON))
{
x3=(xy->y-23)/16;
y3=xy->x/16; 
if(GetAsyncKeyState(VK_LBUTTON) && x3<35&&y3<35)break;
}*/
if(GetAsyncKeyState(VK_LBUTTON))
{
//outtextxy(5,42,"%d %d",xy->x,xy->y);
x3=(xy->y-30-top)/16;
y3=(xy->x-10-left)/16; 
if(GetAsyncKeyState(VK_LBUTTON) && x3<35&&y3<35)break;
}
}
c1=x;d1=y;
x=x3;y=y3;
outtextxy(8,42,"%d  ",score-=300);
}
}


void AI()    //食物躲避蛇的追击判断
{
if(y1!=y&&x1<=x&&x1>0&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1!=y&&x1>=x&&x1<34&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1<=y&&y1>0&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1>=y&&y1<34&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}


void AI2()    //鬼畜模式,食物随机移动,因为比例不同    食物更高几率大范围移动
{
flag=rand()%11;
if(flag<2&&x1>0&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<5&&y1>0&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<7&&x1<34&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(flag<11&&y1<34&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}


void AI3()  //不可思议走位模式    为了游戏可玩性,限制食物的范围
{
if(y1!=y&&x1<=x&&x1>6&&!map[x1-1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[--x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1!=y&&x1>=x&&x1<26&&!map[x1+1][y1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[++x1][y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1<=y&&y1>6&&!map[x1][y1-1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][--y1]=2;
outtextxy(x1,y1,"★");
}
else if(y1>=y&&y1<26&&!map[x1][y1+1])
{
map[x1][y1]=0;
outtextxy(x1,y1,"  ");
map[x1][++y1]=2;
outtextxy(x1,y1,"★");
}
}


int mima()   //管理员密码
{
system("cls");
cout<<"\n\n\n\n\n\n"<<"  输入管理密码"<<endl;
/*char str[10];
cin>>str;
if(strcmp(str,"HUANG")==0)*/
char str;
str=_getch();
if(str=='H')
return 1;
else
return 0;
}


void startgame()   //开始游戏
{
while(1)

if(GetKeyState(VK_SPACE)&0x80)//如果空格键是按下状态,将速度临时调整至60ms
ontimer(time1[0],60,change());
else
ontimer(time1[1],speed,change());//否则按照变量ms的速度运行游戏
if(diffcult=='2')
ontimer(time1[2],speed*3/2,AI());
else if(diffcult=='3')
ontimer(time1[2],speed*3/2,AI());
else if(diffcult=='4')
ontimer(time1[2],speed*6/5,AI());
else if(diffcult=='5')
ontimer(time1[2],110,AI3());
else if(diffcult=='6')
ontimer(time1[2],40,AI2());
else if(diffcult=='7')
AI6();

}
}
void window()//窗口建立
{
SetConsoleTitle("黄铭杰贪吃蛇");//设定窗口标题
//MoveWindow(hwnd,-10,-10,600,800,1);//窗口位置
system("mode con lines=35 cols=100");//设定窗口大小
Hide();
map[15][16]=1;
x=15;y=16;
head->x=15;
head->y=16;
if(diffcult=='3')
score=40000;
else score=400;
speed=260;
for(int i=0;i<35;++i)
outtextxy(i,35,"▓");
outtextxy(2,41,"游戏速度");
outtextxy(4,42,"%d",speed);
outtextxy(6,42,"得分");
outtextxy(8,42,"%d",score);
outtextxy(10,38,"P键暂停,继续再按一次");
outtextxy(12,41,"游戏规则");
outtextxy(15,39,"鼠标、方向键操作");
outtextxy(17,40," E、R键技能");
outtextxy(19,42,"W");
outtextxy(21,40," A  S  D");
outtextxy(23,39,"按下空格临时加速");
outtextxy(25,37,"E键随机传送消耗100积分");
outtextxy(28,37,"R键指定传送消耗300积分");
outtextxy(29,37,"指定操作 鼠标左键选点");
outtextxy(31,39,"作者:黄铭杰");
outtextxy(15,12,"按方向键开始游戏");
for(ch=getch();ch!='W'&&ch!='A'&&ch!='S'&&ch!='D';ch=getch());head->dir=ch;
outtextxy(15,10,"                               ");
srand((unsigned) time(NULL));
x1=rand()%35;
y1=rand()%35;
map[x1][y1]=2;
outtextxy(x1,y1,"★");
outtextxy(15,16,"◆");
startgame();
}


void menu()//主菜单
{
system("cls");
cout<<"\n\n\n\n\n\n"<<"  输入你想要的模式\n\n"<<"  1->新手玩家\n\n"<<"  2->正常玩家\n\n"<<"  3->氪金玩家\n\n"<<"  4->困难模式(一区河蟹)\n\n"<<"  5->地狱模式(不可思议的走位)\n\n"<<"  6->鬼畜模式(这食物可能是刚放出来)\n\n"<<"  7->代练(卢老爷)"<<endl;
while(1)
{
diffcult=_getch();
if(diffcult>'0' && diffcult<'8')break;
}
if(diffcult=='7')
{
if(mima())
window();
else
{
menu();
window();
}
}
}


void end()   //死亡销毁链表
{
while(tail!=head)  //释放链表
{
she *temp=tail->next;
free(tail);
tail=temp;
}
memset(map,0,sizeof(map));
system("cls");
outtextxy(10,14," d888b   .d8b.  .88b  d88. d88888b");
outtextxy(11,14,"88' Y8b d8' `8b 88'YbdP`88 88'");
outtextxy(12,14,"88      88ooo88 88  88  88 88ooooo");
outtextxy(13,14,"88  ooo 88~~~88 88  88  88 88~~~~~");
outtextxy(14,14,"88. ~8~ 88   88 88  88  88 88.");
outtextxy(15,14," Y888P  YP   YP YP  YP  YP Y88888P");
outtextxy(16,14,"\t\t .d88b.  db    db d88888b d8888b.");
outtextxy(17,14,"\t\t.8P  Y8. 88    88 88'     88  `8D");
outtextxy(18,14,"\t\t88    88 Y8    8P 88ooooo 88oobY'");
outtextxy(19,14,"\t\t88    88 `8b  d8' 88~~~~~ 88`8b");
outtextxy(20,14,"\t\t`8b  d8'  `8bd8'  88.     88 `88.");
outtextxy(21,14,"\t\t `Y88P'     YP    Y88888P 88   YD");
outtextxy(23,14,"按回车键重新开始游戏,按0返回主菜单");
while(1)
{
ch=getch();
if(ch==13)
window();
if(ch=='0')
{
menu();
window();
}
}
}






bool road(char ch)   //代练路径
{
int i=x,j=y;
switch(ch)
{
case 'W':
while(i!=x1)
if (map[--i][y]==1)
return 0;
break;
case 'S':
while(i!=x1)
if (map[++i][y]==1)
return 0;
break;
case 'A':
while(j!=y1)
if (map[x][--j]==1)
return 0;
break;
case 'D':
while(j!=y1)
if (map[x][++j]==1)
return 0;
break;
}
return 1;
}


void AI6()    //代练
{
while(1)
{


if(x>x1 && road('W'))
head->dir='W';
else if(x<x1&&road('S'))
head->dir='S';
else if(y>y1&&road('A'))
head->dir='A';
else if(y<y1&&road('D'))
head->dir='D';
ontimer(tally[1],30,dead());
ontimer(tally[2],40,AI3());
}
}




int main(void)  //主函数
{
MoveWindow(hwnd,480,200,680,480,1);//窗口位置
Hide();
char a;
cout<<"\n\n\n\n\n\n"<<"  输入你想要的颜色\n\n"<<"  1->red\n\n"<<"  2->green\n\n"<<"  3->blue"<<endl;
while(1)
{
a=_getch();
if(a>'0' && a<'4')break;
}
color(a);
menu();
//SetConsoleTextAttribute(hOut,FOREGROUND_INTENSITY|FOREGROUND_GREEN);
window();
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值