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 }