1 #include <graphics.h> 2 #include <string.h> 3 #include <time.h> 4 #define NUM_R 10 //半径 5 #define NUM_X 25 //横向个数 6 #define NUM_Y 25 //纵向个数 7 #define NUM 30 //所需节点个数 8 void exe(int x,int y,int f); 9 int GetCommand(); 10 void eat(int x,int y); 11 void clear(); 12 void set(); 13 void flush(); 14 void over(bool a); 15 16 struct pos //建立链表储存每个关节的位置 17 { 18 int x; 19 int y; 20 struct pos*next; 21 }; 22 struct pos*head=(pos*)malloc(sizeof(pos)); //建立头指针 23 int n=0; //记录节点个数 24 25 void main() //初始化游戏 26 { 27 int x,y,f; //储存初始化点的位置方向 28 srand((unsigned) time(NULL)); //初始化随机库 29 do 30 { 31 x=rand()%NUM_X*NUM_R*2+NUM_R; 32 y=rand()%NUM_Y*NUM_R*2+NUM_R; 33 } while(x<4*NUM_R || y<4*NUM_R || 2*NUM_R*(NUM_X-2)<x || 2*NUM_R*(NUM_Y-2)<y); //产生不在矩形边缘的初始点 34 f=rand()%4; //随机方向 35 struct pos*a=(pos*)malloc(sizeof(pos)),*p=head; //建立链表第一个节点 36 a->x=x; //指针a储存第一个点数据 37 a->y=y; 38 head->next=a; //接链 39 a->next=NULL; //结尾 40 initgraph(2*NUM_R*NUM_X,2*NUM_R*NUM_Y+50); //初始绘图窗口 41 setcolor(WHITE); 42 line(0,2*NUM_R*NUM_Y+1,2*NUM_R*NUM_X,2*NUM_R*NUM_Y+1); 43 setcolor(getbkcolor()); //取消圆的边缘 44 setfillcolor(YELLOW); //设置填充颜色 45 fillcircle(x,y,NUM_R); //绘出初始点 46 set(); //产生食物 47 exe(x,y,f); //进入控制函数 48 } 49 50 void exe(int x,int y,int f) //操作游戏 51 { 52 int xf,yf,c,i; 53 while(1) //进入循环 54 { 55 c=0; //初始化方向 56 for(i=0;i<5;i++) //循环5次获取命令 57 { 58 Sleep(100-50*n/NUM); //等待 59 if(c==0) //若没获取到命令就进行获取 60 { 61 c=GetCommand(); 62 if(c==4) //返回4时退出循环等待 63 break; 64 } 65 } 66 f=f+c; //改变方向 67 if(f>3) //溢出处理 68 f=f-4; 69 xf=yf=0; //初始化方向参数 70 switch(f) 71 { 72 case 0:xf=1;break; //方向向右时 x坐标增加 73 case 1:yf=1;break; //方向向上时 y坐标增加 74 case 2:xf=-1;break; //方向向左时 x坐标减少 75 case 3:yf=-1;break; //方向向下时 y坐标减少 76 } 77 x=x+2*NUM_R*xf; //x坐标变化 78 y=y+2*NUM_R*yf; //y坐标变化 79 if(getpixel(x,y)==RED || x<0 || y<0 || 2*NUM_X*NUM_R<x || 2*NUM_Y*NUM_R<y) //判断是否遇到自身或碰到边界 80 over(0); //结束游戏 81 else //不结束进行下步运算 82 { 83 if(getpixel(x,y)==GREEN) //判断前方是否为食物 84 set(); //产生新食物 85 else 86 clear(); //清除尾结点 87 eat(x,y); //在前方生成新结点 88 if(n>NUM-1) //判断胜利条件 89 over(1); //结束游戏 90 } 91 } 92 } 93 94 int GetCommand() //获取方向 95 { 96 int c=0; //初始化方向变量 97 if(GetAsyncKeyState(VK_RIGHT) & 0x8000) c = 1; //右转为1 98 if(GetAsyncKeyState(VK_LEFT) & 0x8000) c = 3; //左转为3 99 if(GetAsyncKeyState(VK_UP) & 0x8000) c = 4; //按上为4 快进 100 if(GetAsyncKeyState(VK_DOWN) & 0x8000) system("pause"); //按下则暂停 101 return c; 102 } 103 104 void eat(int x,int y) //增加新结点 105 { 106 struct pos*a=(pos*)malloc(sizeof(pos)),*p=head; //声明指针变量 107 while(p->next!=NULL) //寻找链表尾节点 108 p=p->next; 109 a->x=x; //把数据储存到结点 110 a->y=y; 111 p->next=a; //指针a接到尾节点后 112 a->next=NULL; //结尾 113 setcolor(getbkcolor()); //取消圆的边缘 114 setfillcolor(RED); //设置填充颜色 115 fillcircle(p->x,p->y,NUM_R); //绘制新结点 116 setfillcolor(YELLOW); //设置填充颜色 117 fillcircle(x,y,NUM_R); //绘制新结点 118 } 119 120 void clear() //清除尾结点 121 { 122 setcolor(getbkcolor()); //取消圆的边缘 123 setfillcolor(getbkcolor()); //设置填充颜色 124 fillcircle(head->next->x,head->next->y,NUM_R); //擦除结点 125 head->next=head->next->next; //删除节点数据 126 } 127 128 void set() //产生食物和胜利判断 129 { 130 flush(); 131 int x,y; //声明变量 132 do 133 { 134 x=rand()%NUM_X*NUM_R*2+NUM_R; 135 y=rand()%NUM_Y*NUM_R*2+NUM_R; 136 } while (getpixel(x,y)==RED); //随机产生食物在非蛇的位置 137 setcolor(getbkcolor()); 138 setfillcolor(GREEN); //设置填充颜色 139 fillcircle(x,y,NUM_R); //产生食物 140 } 141 142 void flush() 143 { 144 n++; //节点计数累加 145 char strnum[20],string[10]="进度:"; 146 itoa(n,strnum,10); //转换 147 strcat(string,strnum); //链接 148 strcpy(strnum,"/"); //赋值 149 strcat(string,strnum); //连接 150 itoa(NUM,strnum,10); 151 strcat(string,strnum); 152 setcolor(WHITE); 153 settextstyle(32,0,_T("宋体")); //设置字体类型 154 outtextxy(20,2*NUM_R*NUM_Y+2," "); 155 outtextxy(20,2*NUM_R*NUM_Y+2,string); 156 } 157 158 void over(bool a) //结束游戏 159 { 160 setcolor(WHITE); //设置字体颜色 161 settextstyle(48,0,_T("宋体")); //设置字体类型 162 if(a) //判断条件 163 outtextxy(NUM_X*NUM_R-20,NUM_Y*NUM_R-20,"胜利"); //输出结果 164 else 165 outtextxy(NUM_X*NUM_R-20,NUM_Y*NUM_R-20,"失败"); //输出结果 166 Sleep(2000); 167 system("pause"); 168 exit(0); 169 }