源代码使用GCC编译器编译并运行于Linux,想在windows下运行需要修改少许字符输出语句。在自动控制snake上下了很大功夫,但是对防止进入自身封闭上做的很不好,而且没有使用另一线程实现玩家控制方向。为了方便编写,分为“snakeGame”、“sankeAI”、“sankeHead.h"三个文件。
“sankeHead.h"
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <curses.h> 4 #include <time.h> 5 typedef enum {null=-2,stop=-1,left=0,right=1,up=2,down=3}movtype; 6 typedef enum {air,food,wall}coltype; 7 typedef struct { 8 coltype type; 9 int chartype; 10 }charModel; 11 typedef struct { 12 int x; 13 int y; 14 movtype type; 15 }ctrlModel; 16 void writeLineQ(charModel cmTemp[]); 17 void removSnake(ctrlModel snakeModel[]); 18 int collidedeal(charModel cmTEMP[],ctrlModel snakeModel[]); 19 void addfood(ctrlModel snakeModel[],ctrlModel foodModel[],int amount); 20 void addsnakemod(ctrlModel snakeModel[],int amount); 21 #define SCR_WIDTH 60 22 #define SCR_HEIGHT 20 23 #define SNAKE_CHAR '*' 24 #define SNAKE_LENGTH 8 25 #define FOOD_AMOUNT_MAX 10 26 #define FOOD_CHAR '0'
“sankeAI.c"
1 #include "snakeHead.h" 2 int closegraph(charModel cmTEMP[],ctrlModel snakeModel[],int direction); 3 movtype DirectionAlt(movtype type,int direction) 4 { 5 int irand; 6 switch(direction) 7 { 8 case 1: 9 return type; 10 case 2: 11 switch(type) 12 { 13 case left: 14 return down; 15 case right: 16 return up; 17 case up: 18 return left; 19 case down: 20 return right; 21 default: 22 return stop; 23 } 24 case 4: 25 switch(type) 26 { 27 case left: 28 return up; 29 case right: 30 return down; 31 case up: 32 return right; 33 case down: 34 return left; 35 default: 36 return stop; 37 } 38 case 3://随即选定一个方向 2选1 39 case 5: 40 irand=rand(); 41 irand=irand%2; 42 if(irand==0){//偶数 43 return type;} 44 else{//奇数 45 return DirectionAlt(type,direction-1);} 46 case 6: 47 irand=rand(); 48 irand=irand%2; 49 if(irand==0){//偶数 50 return DirectionAlt(type,2);} 51 else{//奇数 52 return DirectionAlt(type,4);} 53 case 7://随即选定一个方向 3选1 54 irand=rand(); 55 irand=irand%3; 56 if(irand==0){ 57 return type;} 58 else if(irand==1){ 59 return DirectionAlt(type,2);} 60 else { 61 return DirectionAlt(type,4);} 62 default: 63 return stop; 64 } 65 } 66 movtype EatAI(charModel cmTEMP[],ctrlModel snakeModel[],ctrlModel foodModel[]) 67 { 68 int ix,iy,i,foodamount[FOOD_AMOUNT_MAX],distance=SCR_WIDTH*SCR_HEIGHT,numfood[2]; 69 //寻找头部周围的身体 70 int headbar[4]={0,0,0,0};//[0]左 [1]右 [2]上 [3]下 71 for(i=1;i<SCR_WIDTH*SCR_HEIGHT;i++) 72 { 73 if(snakeModel[i].type==null){ 74 break;} 75 else if(snakeModel[i].x==snakeModel[0].x){ 76 if(snakeModel[i].y==snakeModel[0].y-1){ 77 headbar[2]=1;} 78 else if(snakeModel[i].y==snakeModel[0].y+1){ 79 headbar[3]=1;}} 80 else if(snakeModel[i].y==snakeModel[0].y){ 81 if(snakeModel[i].x==snakeModel[0].x-1){ 82 headbar[0]=1;} 83 else if(snakeModel[i].x==snakeModel[0].x+1){ 84 headbar[1]=1;}} 85 } 86 int direction=7; //1为向前 2为向左 4为向右 ,1+2 1+4 2+4 1+2+4 方向组合 87 //排除算法 排除墙体和身体碰撞 88 switch(snakeModel[0].type){ 89 case left: 90 if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1){ 91 direction-=1;} 92 if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1){ 93 direction-=2;} 94 if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1){ 95 direction-=4;} 96 break; 97 case right: 98 if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1){ 99 direction-=1;} 100 if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1){ 101 direction-=2;} 102 if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1){ 103 direction-=4;} 104 break; 105 case up: 106 if(cmTEMP[snakeModel[0].x+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1){ 107 direction-=1;} 108 if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1){ 109 direction-=2;} 110 if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1){ 111 direction-=4;} 112 break; 113 case down: 114 if(cmTEMP[snakeModel[0].x+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1){ 115 direction-=1;} 116 if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1){ 117 direction-=2;} 118 if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1){ 119 direction-=4;} 120 break; 121 case stop: 122 default: 123 return stop; 124 } 125 if(direction==0){ 126 return snakeModel[0].type;}//走投无路,自我毁灭 127 //是否形成闭合图形,检验方向可行性,防止自我封闭 128 if(direction!=1 && direction!=2 && direction!=4){ 129 direction=closegraph(cmTEMP,snakeModel,direction);} 130 //自动寻物 131 for(i=0;i<FOOD_AMOUNT_MAX;i++)//取相对距离,并选取最小值 132 { 133 if(foodModel[i].type==null){ 134 continue;} 135 ix=snakeModel[0].x-foodModel[i].x;iy=snakeModel[0].y-foodModel[i].y; 136 foodamount[i]=ix*ix+iy*iy;//平面两点坐标公式 x^2+y^2 137 if(distance>foodamount[i]){ 138 numfood[0]=foodModel[i].x; 139 numfood[1]=foodModel[i].y; 140 distance=foodamount[i];} 141 } 142 //创建寻物方向 143 int fooddirection=0,subx=snakeModel[0].x-numfood[0],suby=snakeModel[0].y-numfood[1]; 144 if(subx == 0){ 145 if(suby < 0){ 146 switch(snakeModel[0].type){ 147 case left: 148 fooddirection+=2; 149 break; 150 case right: 151 fooddirection+=4; 152 break; 153 case up: 154 fooddirection+=6; 155 break; 156 case down: 157 fooddirection+=1; 158 break; 159 default: 160 break;} 161 } 162 else if(suby > 0){ 163 switch(snakeModel[0].type){ 164 case left: 165 fooddirection+=4; 166 break; 167 case right: 168 fooddirection+=2; 169 break; 170 case up: 171 fooddirection+=1; 172 break; 173 case down: 174 fooddirection+=6; 175 break; 176 default: 177 break;} 178 } 179 } 180 else if(subx<0){ 181 if(suby== 0){ 182 switch(snakeModel[0].type){ 183 case left: 184 fooddirection+=6; 185 break; 186 case right: 187 fooddirection+=1; 188 break; 189 case up: 190 fooddirection+=4; 191 break; 192 case down: 193 fooddirection+=2; 194 break; 195 default: 196 break; 197 } 198 } 199 else if(suby < 0){ 200 switch(snakeModel[0].type){ 201 case left: 202 fooddirection+=2; 203 break; 204 case right: 205 fooddirection+=5; 206 break; 207 case up: 208 fooddirection+=4; 209 break; 210 case down: 211 fooddirection+=3; 212 break; 213 default: 214 break; 215 } 216 } 217 else{// suby > 0 218 switch(snakeModel[0].type){ 219 case left: 220 fooddirection+=4; 221 break; 222 case right: 223 fooddirection+=3; 224 break; 225 case up: 226 fooddirection+=5; 227 break; 228 case down: 229 fooddirection+=2; 230 break; 231 default: 232 break; 233 } 234 } 235 } 236 else{// subx > 0 237 if(suby== 0){ 238 switch(snakeModel[0].type){ 239 case left: 240 fooddirection+=1; 241 break; 242 case right: 243 fooddirection+=6; 244 break; 245 case up: 246 fooddirection+=2; 247 break; 248 case down: 249 fooddirection+=4; 250 break; 251 default: 252 break; 253 } 254 } 255 else if(suby < 0){ 256 switch(snakeModel[0].type){ 257 case left: 258 fooddirection+=3; 259 break; 260 case right: 261 fooddirection+=4; 262 break; 263 case up: 264 fooddirection+=2; 265 break; 266 case down: 267 fooddirection+=5; 268 break; 269 default: 270 break; 271 } 272 } 273 else{// suby > 0 274 switch(snakeModel[0].type){ 275 case left: 276 fooddirection+=5; 277 break; 278 case right: 279 fooddirection+=2; 280 break; 281 case up: 282 fooddirection+=3; 283 break; 284 case down: 285 fooddirection+=4; 286 break; 287 default: 288 break; 289 } 290 } 291 } 292 switch(direction){ 293 case 1: 294 return snakeModel[0].type; 295 case 2: 296 case 4: 297 return DirectionAlt(snakeModel[0].type,direction); 298 case 7://前左右 299 return DirectionAlt(snakeModel[0].type,fooddirection); 300 case 6://左右 301 if(fooddirection>=direction || fooddirection==1){ 302 return DirectionAlt(snakeModel[0].type,6);} 303 else if(fooddirection==2 || fooddirection==4){ 304 return DirectionAlt(snakeModel[0].type,fooddirection);} 305 else if(fooddirection==3 || fooddirection==5){ 306 return DirectionAlt(snakeModel[0].type,fooddirection-1);} 307 case 3://前左 308 if(fooddirection<=3){ 309 return DirectionAlt(snakeModel[0].type,fooddirection);} 310 else if(fooddirection==5||fooddirection==6){ 311 return DirectionAlt(snakeModel[0].type,fooddirection-4);} 312 else if(fooddirection==4||fooddirection==7){ 313 return DirectionAlt(snakeModel[0].type,3);} 314 case 5://前右 315 if(fooddirection==5||fooddirection==7){ 316 return DirectionAlt(snakeModel[0].type,5);} 317 else if(fooddirection<=3){ 318 return DirectionAlt(snakeModel[0].type,1);} 319 else if(fooddirection==4||fooddirection==6){ 320 return DirectionAlt(snakeModel[0].type,4);} 321 default: 322 return stop; 323 } 324 } 325 326 int closegraph(charModel cmTEMP[],ctrlModel snakeModel[],int direction) 327 { 328 //检测是否为闭合图形 1 蛇模型闭合 2 蛇模型+边界闭合 329 int i; 330 for(i=SCR_WIDTH*SCR_HEIGHT-1;i>=0;i--)//从蛇尾到倒找 331 { 332 if(snakeModel[i].type==null){ 333 continue;} 334 if(i==2){ 335 return direction;} 336 if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;} 337 if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y==snakeModel[0].y){break;} 338 if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;} 339 if(snakeModel[i].x==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;} 340 if(snakeModel[i].x==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;} 341 if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;} 342 if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y==snakeModel[0].y){break;} 343 if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;} 344 } 345 //如果结点为末尾无视 346 if(snakeModel[i+1].type==null){return direction;} 347 //判断前结点方向 348 movtype direfalse[2]={null,null}; 349 if(snakeModel[i-1].x==snakeModel[i].x){ 350 if(snakeModel[i-1].y-snakeModel[i].y==1){ 351 direfalse[0]=down;} 352 else{direfalse[0]=up;}} 353 else if(snakeModel[i-1].y==snakeModel[i].y){ 354 if(snakeModel[i-1].x-snakeModel[i].x==-1){ 355 direfalse[0]=left;} 356 else{direfalse[0]=right;}} 357 //判断后结点方向 358 if(snakeModel[i].x==snakeModel[i+1].x){ 359 if(snakeModel[i].y-snakeModel[i+1].y==1){ 360 direfalse[1]=down;} 361 else{direfalse[1]=up;}} 362 else if(snakeModel[i].y==snakeModel[i+1].y){ 363 if(snakeModel[i].x-snakeModel[i+1].x==-1){ 364 direfalse[1]=left;} 365 else{direfalse[1]=right;}} 366 //方向 367 for(i=0;i<2;i++){ 368 if(snakeModel[0].type==direfalse[i]){direction-=1;continue;} 369 if(direfalse[0]==direfalse[1]){break;} 370 switch(snakeModel[0].type){ 371 case 0: 372 if(direfalse[i]==2){direction-=4;} 373 else if(direfalse[i]==3){direction-=2;} 374 break; 375 case 1: 376 if(direfalse[i]==2){direction-=2;} 377 else if(direfalse[i]==3){direction-=4;} 378 break; 379 case 2: 380 if(direfalse[i]==0){direction-=2;} 381 else if(direfalse[i]==1){direction-=4;} 382 break; 383 case 3: 384 if(direfalse[i]==0){direction-=4;} 385 else if(direfalse[i]==1){direction-=2;} 386 break; 387 default: 388 break; 389 } 390 } 391 return direction; 392 }
“snakeGame
1 #include "snakeAI.c" 2 #define CTRL_TIMES 5 // 每秒显示的步数 3 #define WINDOW_W 40 4 #define WINDOW_H 10 5 int main() 6 { 7 srand((int)time(0)); 8 initscr(); 9 charModel cmTEMP[SCR_WIDTH*SCR_HEIGHT]; 10 ctrlModel snakeModel[SCR_WIDTH*SCR_HEIGHT]; 11 ctrlModel foodModel[FOOD_AMOUNT_MAX]; 12 while(1) 13 { 14 int i,usrctrl[2]; 15 while(1) 16 { 17 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)//初始化用户界面 18 { 19 if( i%SCR_WIDTH == 0|| i%SCR_WIDTH == SCR_WIDTH-1){ 20 cmTEMP[i].chartype='|'; 21 } 22 else if(i/SCR_WIDTH == 0 || i/SCR_WIDTH == SCR_HEIGHT-1){ 23 cmTEMP[i].chartype='-'; 24 } 25 else{ 26 cmTEMP[i].type=air; 27 cmTEMP[i].chartype=i%26+65; 28 } 29 } 30 for(i=0;i<WINDOW_W*WINDOW_H;i++) 31 { 32 int sum; 33 sum=(i/WINDOW_W+(SCR_HEIGHT-WINDOW_H)/2)*SCR_WIDTH+(i%WINDOW_W+(SCR_WIDTH-WINDOW_W)/2); 34 if(i%WINDOW_W == 0|| i%WINDOW_W == WINDOW_W-1 || i/WINDOW_W == 0 || i/WINDOW_W == WINDOW_H-1){ 35 cmTEMP[sum].chartype='*'; 36 } 37 else{ 38 cmTEMP[sum].chartype=' '; 39 } 40 } 41 writeLineQ (cmTEMP); 42 move((SCR_HEIGHT-WINDOW_H)/2+1,(SCR_WIDTH-WINDOW_W)/2+1); 43 printw(" SnakeGame "); 44 switch(usrctrl[0]) 45 { 46 case 1: 47 move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1); 48 printw(" Start SnakeGame "); 49 move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1); 50 printw(" >----Watch snakeAI----< "); 51 move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1); 52 printw(" About "); 53 move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1); 54 printw(" EXIT "); 55 move((SCR_HEIGHT-WINDOW_H)/2+7,(SCR_WIDTH-WINDOW_W)/2+1); 56 printw(" Tip UP:W DOWN:S Enter:D "); 57 move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+31); 58 break; 59 case 2: 60 move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1); 61 printw(" Start SnakeGame "); 62 move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1); 63 printw(" Watch snakeAI "); 64 move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1); 65 printw(" >----About----< "); 66 move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1); 67 printw(" EXIT "); 68 move((SCR_HEIGHT-WINDOW_H)/2+7,(SCR_WIDTH-WINDOW_W)/2+1); 69 printw(" Tip UP:W DOWN:S Enter:D "); 70 move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+31); 71 break; 72 case 3: 73 move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1); 74 printw(" Start SnakeGame "); 75 move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1); 76 printw(" Watch snakeAI "); 77 move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1); 78 printw(" About "); 79 move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1); 80 printw(" >----EXIT----< "); 81 move((SCR_HEIGHT-WINDOW_H)/2+7,(SCR_WIDTH-WINDOW_W)/2+1); 82 printw(" Tip UP:W DOWN:S Enter:D "); 83 move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+31); 84 break; 85 default: 86 move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1); 87 printw(" >----Start SnakeGame----< "); 88 move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1); 89 printw(" Watch snakeAI "); 90 move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1); 91 printw(" About "); 92 move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1); 93 printw(" EXIT "); 94 move((SCR_HEIGHT-WINDOW_H)/2+7,(SCR_WIDTH-WINDOW_W)/2+1); 95 printw(" Tip UP:W DOWN:S Enter:D "); 96 move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+31); 97 break; 98 } 99 refresh(); 100 noecho(); 101 switch(getch()) 102 { 103 case 'w': 104 if(usrctrl[0]<=0){usrctrl[0]=3;}else{usrctrl[0]-=1;}break; 105 case 's': 106 if(usrctrl[0]>=3){usrctrl[0]=0;}else{usrctrl[0]+=1;}break; 107 case 'd': 108 if(usrctrl[0]==3){clear();exit(0);} 109 else{usrctrl[1]=usrctrl[0]+1;} 110 break; 111 } 112 if(usrctrl[1]==1||usrctrl[1]==2){break;} 113 else{ 114 115 116 } 117 } 118 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)//初始化蛇模型 119 { 120 if(i<SNAKE_LENGTH) 121 { 122 snakeModel[i].x= (SCR_WIDTH+SNAKE_LENGTH)/2-i; 123 snakeModel[i].y= SCR_HEIGHT/2-1; 124 snakeModel[i].type=stop; 125 } 126 else 127 { 128 snakeModel[i].type=null; 129 } 130 } 131 for(i=0;i<FOOD_AMOUNT_MAX;i++)//初始化食物 132 { 133 foodModel[i].type=null; 134 } 135 addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX); 136 snakeModel[0].type=right;//蛇的移动方向向右 137 while(1) 138 { 139 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) 140 { 141 if( i%SCR_WIDTH == 0|| i%SCR_WIDTH == SCR_WIDTH-1){ 142 cmTEMP[i].type =wall; 143 cmTEMP[i].chartype='|'; 144 } 145 else if(i/SCR_WIDTH == 0 || i/SCR_WIDTH == SCR_HEIGHT-1){ 146 cmTEMP[i].type =wall; 147 cmTEMP[i].chartype='-'; 148 } 149 else{ 150 cmTEMP[i].type=air; 151 cmTEMP[i].chartype=' '; 152 } 153 } 154 removSnake(snakeModel);//移动蛇 155 for(i=0;i<FOOD_AMOUNT_MAX;i++) //添加食物图形 156 { 157 if(foodModel[i].type==null) 158 continue; 159 int sum; 160 sum=foodModel[i].x+foodModel[i].y*SCR_WIDTH; 161 cmTEMP[sum].type = food; 162 cmTEMP[sum].chartype=FOOD_CHAR; 163 } 164 int retdeal=collidedeal(cmTEMP,snakeModel);//碰撞处理 165 if(retdeal==1) 166 { 167 addsnakemod(snakeModel,1); 168 for(i=0;i<FOOD_AMOUNT_MAX;i++) 169 { 170 if(foodModel[i].x==snakeModel[0].x && foodModel[i].y==snakeModel[0].y){ 171 foodModel[i].type=null;} 172 } 173 addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX); 174 } 175 else if(retdeal==2) 176 { 177 for(i=0;i<5;i++) 178 { 179 move(SCR_HEIGHT/2-1,SCR_WIDTH/2-5); 180 printw("GAME OVER! %d...",5-i); 181 refresh(); 182 sleep(1); 183 } 184 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) 185 { 186 if(i<SNAKE_LENGTH) 187 { 188 snakeModel[i].x= (SCR_WIDTH+SNAKE_LENGTH)/2-i; 189 snakeModel[i].y= SCR_HEIGHT/2-1; 190 snakeModel[i].type=stop; 191 } 192 else 193 { 194 snakeModel[i].type=null; 195 } 196 } 197 for(i=0;i<FOOD_AMOUNT_MAX;i++) 198 { 199 foodModel[i].type=null; 200 } 201 addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX); 202 snakeModel[0].type=right;//测试 蛇的移动方向向右 203 continue; 204 } 205 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) //添加蛇模型 206 { 207 if(snakeModel[i].type==null) 208 break; 209 int sum; 210 sum=snakeModel[i].x+snakeModel[i].y*SCR_WIDTH; 211 cmTEMP[sum].type = wall; 212 cmTEMP[sum].chartype=SNAKE_CHAR; 213 if(i==0){ 214 cmTEMP[sum].chartype='+';} 215 216 } 217 writeLineQ (cmTEMP);//显示合成图形 218 if(usrctrl[1]==2){ 219 snakeModel[0].type=EatAI(cmTEMP,snakeModel,foodModel);} 220 else{ 221 noecho(); 222 switch(getch()) 223 { 224 case 'a': 225 snakeModel[0].type=left; 226 break; 227 case 'w': 228 snakeModel[0].type=up; 229 break; 230 case 's': 231 snakeModel[0].type=down; 232 break; 233 case 'd': 234 snakeModel[0].type=right; 235 break; 236 default: 237 break; 238 } 239 } 240 } 241 } 242 endwin(); 243 exit(EXIT_SUCCESS); 244 } 245 void ctrltimes() 246 { 247 static int a=0; 248 a+=1; 249 if(a==CTRL_TIMES) 250 { 251 sleep(1); 252 a=0; 253 } 254 } 255 void writeLineQ(charModel cmTEMP[]) 256 { 257 int i; 258 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) 259 { 260 move(i/SCR_WIDTH,i%SCR_WIDTH); 261 addch((cmTEMP[i]).chartype); 262 } 263 refresh(); 264 ctrltimes(); 265 } 266 267 void removSnake(ctrlModel snakeModel[]) 268 { 269 int i; 270 if( snakeModel[0].type==stop) 271 return; 272 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) 273 { 274 int nxtemp,nytemp,nttemp,xtemp,ytemp,ttemp; 275 if(snakeModel[i].type==null) 276 { 277 return; 278 } 279 nxtemp=snakeModel[i].x; 280 nytemp=snakeModel[i].y; 281 nttemp=snakeModel[i].type; 282 if(i==0) 283 { 284 xtemp=nxtemp; 285 ytemp=nytemp; 286 ttemp=nttemp; 287 switch(snakeModel[i].type) 288 { 289 case left: 290 snakeModel[i].x -=1;break; 291 case right: 292 snakeModel[i].x +=1;break; 293 case up: 294 snakeModel[i].y -=1;break; 295 case down: 296 snakeModel[i].y +=1;break; 297 default: 298 break; 299 } 300 } 301 else 302 { 303 snakeModel[i].x=xtemp; 304 snakeModel[i].y=ytemp; 305 snakeModel[i].type=ttemp; 306 xtemp=nxtemp; 307 ytemp=nytemp; 308 ttemp=nttemp; 309 } 310 311 } 312 313 } 314 int collidedeal(charModel cmTEMP[],ctrlModel snakeModel[]) 315 { 316 int i; 317 for(i=1;i<=SCR_WIDTH*SCR_HEIGHT;i++) 318 { 319 if(snakeModel[i].type==null){ 320 break;} 321 if(snakeModel[0].x==snakeModel[i].x && snakeModel[0].y==snakeModel[i].y){ 322 return 2;} 323 } 324 int sum; 325 sum=snakeModel[0].x+snakeModel[0].y*SCR_WIDTH; 326 switch(cmTEMP[sum].type) 327 { 328 case air: 329 return 0; 330 case food: 331 return 1; 332 case wall: 333 return 2; 334 default: 335 return -1; 336 } 337 } 338 void addfood(ctrlModel snakeModel[],ctrlModel foodModel[],int amount) 339 { 340 341 int i; 342 for(i=0;i<amount;i++){ 343 if(foodModel[i].type!=null){ 344 return;} 345 } 346 for(i=0;i<amount;i++) 347 { 348 int x,y,randx; 349 do{ 350 randx=rand(); 351 }while(randx>=SCR_WIDTH*SCR_HEIGHT); 352 x=randx%SCR_WIDTH;y=randx/SCR_WIDTH; 353 if(x!=0 && y!=0 && x!= SCR_WIDTH-1 && y!=SCR_HEIGHT-1) 354 { 355 356 int times,ctrlbool=0; 357 for(times=0;times<SCR_WIDTH*SCR_WIDTH;times++) 358 { 359 if(snakeModel[times].type==null){ 360 break;} 361 else if(snakeModel[times].x==x && snakeModel[times].y==y){ 362 ctrlbool=-1; 363 break;} 364 } 365 if(ctrlbool==-1){ 366 i--; 367 } 368 else{ 369 foodModel[i].x=x; 370 foodModel[i].y=y; 371 foodModel[i].type=stop; 372 } 373 374 } 375 else 376 { 377 i--; 378 } 379 } 380 } 381 void addsnakemod(ctrlModel snakeModel[],int amount) 382 { 383 int i,times; 384 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) 385 { 386 if( snakeModel[i].type==null) 387 { 388 for(times=0;times<amount;times++) 389 { 390 snakeModel[i+times].type=stop; 391 switch(snakeModel[i+times-1].type) 392 { 393 case left: 394 snakeModel[i+times].x=snakeModel[i+times-1].x+1; 395 snakeModel[i+times].y=snakeModel[i+times-1].y; 396 break; 397 case right: 398 snakeModel[i+times].x=snakeModel[i+times-1].x-1; 399 snakeModel[i+times].y=snakeModel[i+times-1].y; 400 break; 401 case up: 402 snakeModel[i+times].x=snakeModel[i+times-1].x; 403 snakeModel[i+times].y=snakeModel[i+times-1].y+1; 404 break; 405 case down: 406 snakeModel[i+times].x=snakeModel[i+times-1].x; 407 snakeModel[i+times].y=snakeModel[i+times-1].y-1; 408 break; 409 default: 410 break; 411 } 412 } 413 return; 414 } 415 } 416 }