贪吃蛇

  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 }

原文地址:https://www.cnblogs.com/wxdjss/p/5700755.html