貪吃蛇

  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 }

相關文章
相關標籤/搜索