C语言贪吃蛇再进化!

嗯,这是终结版,虽然还有一些地方不完善,但我感觉也没必要完善。只是纠结于AI的自动寻物还是有问题,桑心。GCC编译命令 gcc -Wall -D_REENTRANT  -o "%e" "%f" -lncurses -lpthread 

snakeGame.c

  1 #include "snakeAI.c"
  2 #define CTRL_TIMES 1000 // AI每秒显示的最大步数
  3 #define WINDOW_W 40
  4 #define WINDOW_H 10
  5 int threadtype=-1,threadbool=0;
  6 void *threadctrl(void *arg)
  7 {
  8     noecho();
  9     while(1)
 10     {
 11         if(threadbool)
 12         {
 13             switch(getch())
 14             {
 15                 case 'a':
 16                     threadtype=0;
 17                     break;
 18                 case 'd':
 19                     threadtype=1;
 20                     break;
 21                 case 'w':
 22                     threadtype=2;
 23                     break;
 24                 case 's':
 25                     threadtype=3;
 26                     break;
 27                 case 'q':
 28                     threadbool=0;
 29                     threadtype=4;
 30                     break;
 31                 default:
 32                     break;
 33             }
 34         }
 35     }
 36 }
 37 
 38 
 39 int main()
 40 {
 41     srand((int)time(0));
 42     initscr();
 43     int exitbool = 0;
 44     //create_queue(100);
 45     /*检查屏幕是否支持彩色功能*/
 46     if(has_colors())
 47     {
 48         start_color();
 49         init_pair(10,COLOR_BLACK,COLOR_WHITE);//菜单背景
 50         init_pair(11,COLOR_WHITE,COLOR_BLACK);//菜单选中文字
 51         init_pair(12,COLOR_WHITE,COLOR_BLACK);//弹出菜单
 52         init_pair(20,COLOR_YELLOW,COLOR_BLACK);//食物
 53         init_pair(30,COLOR_GREEN,COLOR_BLACK);//蛇通常
 54         init_pair(31,COLOR_CYAN,COLOR_BLACK);//蛇变色
 55         init_pair(40,COLOR_RED,COLOR_BLACK);//游戏碰撞
 56         init_pair(41,COLOR_BLACK,COLOR_BLACK);//游戏背景
 57         init_pair(50,COLOR_WHITE,COLOR_RED);//程序出错
 58     }
 59     
 60     /*用户控制线程*/
 61     pthread_t a_thread;
 62     pthread_create(&a_thread,NULL,threadctrl,(void *)0);
 63     charModel cmTEMP[SCR_WIDTH*SCR_HEIGHT];
 64     ctrlModel snakeModel[SCR_WIDTH*SCR_HEIGHT];
 65     ctrlModel foodModel[FOOD_AMOUNT_MAX];
 66     /*菜单选项*/
 67     while(1)
 68     {
 69         threadbool = 0;//键盘控制游戏-禁止
 70         int i = 0,usrctrl[2] = {0,0};
 71         while(1)
 72         {
 73             attrset(COLOR_PAIR(10));
 74             for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
 75             {
 76                 if( i%SCR_WIDTH == 0|| i%SCR_WIDTH == SCR_WIDTH-1)
 77                 {
 78                     cmTEMP[i].chartype='|';
 79                 }
 80                 else if(i/SCR_WIDTH == 0 ||  i/SCR_WIDTH == SCR_HEIGHT-1)
 81                 {
 82                     cmTEMP[i].chartype='-';
 83                 }
 84                 else
 85                 {
 86                     cmTEMP[i].type=air;
 87                     cmTEMP[i].chartype=i%26+65;
 88                 }
 89             }
 90             for(i=0;i<WINDOW_W*WINDOW_H;i++)
 91             {
 92                 int sum;
 93                 sum=(i/WINDOW_W+(SCR_HEIGHT-WINDOW_H)/2)*SCR_WIDTH+(i%WINDOW_W+(SCR_WIDTH-WINDOW_W)/2);
 94                 if(i%WINDOW_W == 0|| i%WINDOW_W == WINDOW_W-1 || i/WINDOW_W == 0 || i/WINDOW_W == WINDOW_H-1)
 95                 {
 96                     cmTEMP[sum].chartype='.';
 97                 }
 98                 else
 99                 {
100                     cmTEMP[sum].chartype='=';
101                 }
102             }
103             attrset(COLOR_PAIR(10));
104             writeLineQ (cmTEMP,0);
105             move((SCR_HEIGHT-WINDOW_H)/2+1,(SCR_WIDTH-WINDOW_W)/2+1);
106             printw("                SnakeGame             ");
107             move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1);
108             printw("             Start SnakeGame          ");
109             move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1);
110             printw("              Watch snakeAI           ");
111             move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1);
112             printw("                 About                ");
113             move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1);
114             printw("                 EXIT                 ");
115             move((SCR_HEIGHT-WINDOW_H)/2+7,(SCR_WIDTH-WINDOW_W)/2+1);
116             printw("   Ctrl UP:W  DOWN:S  Enter:D Quit:Q  ");
117             move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+40);
118             attrset(COLOR_PAIR(11));
119             switch(usrctrl[0])
120             {
121                 case 1:
122                     move((SCR_HEIGHT-WINDOW_H)/2+3,(SCR_WIDTH-WINDOW_W)/2+1);
123                     printw("         >----Watch snakeAI----<      ");
124                 break;
125                 case 2:
126                     move((SCR_HEIGHT-WINDOW_H)/2+4,(SCR_WIDTH-WINDOW_W)/2+1);
127                     printw("            >----About----<           ");
128                 break;
129                 case 3:
130                     move((SCR_HEIGHT-WINDOW_H)/2+5,(SCR_WIDTH-WINDOW_W)/2+1);
131                     printw("            >----EXIT----<            ");
132                 break;
133                 default:
134                     move((SCR_HEIGHT-WINDOW_H)/2+2,(SCR_WIDTH-WINDOW_W)/2+1);
135                     printw("        >----Start SnakeGame----<     ");
136                     break;
137             }
138             refresh();
139             noecho();
140             switch(getch())
141             {
142                 case 'w':
143                     if(usrctrl[0]==0)
144                     {
145                         usrctrl[0]=3;
146                     }
147                     else
148                     {
149                         usrctrl[0]-=1;
150                     }
151                     break;
152                 case 's':
153                     if(usrctrl[0]==3)
154                     {
155                         usrctrl[0]=0;
156                     }
157                     else
158                     {
159                         usrctrl[0]+=1;
160                     }
161                     break;
162                 case 'd':
163                     if(usrctrl[0]==3)
164                     {
165                         clear();
166                         exit(1);
167                     }
168                     else if(usrctrl[0]==1)
169                     {
170                         usrctrl[1]=1;
171                         snakeModel[0].type=right;
172                     }
173                     else if(usrctrl[0]==2)
174                     {
175                         /*about*/
176                     }
177                     else
178                     {
179                         usrctrl[1]=2;
180                         snakeModel[0].type=stop;
181                     }
182                     break;    
183             }
184             if(usrctrl[1]==1||usrctrl[1]==2)
185             {
186                 break;
187             }
188         }
189             
190         /*游戏初始化*/
191         for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)//初始化蛇模型
192         {
193             if(i<SNAKE_LENGTH)
194             {
195                 snakeModel[i].x= (SCR_WIDTH+SNAKE_LENGTH)/2-i;
196                 snakeModel[i].y= SCR_HEIGHT/2-1;
197                 if(i!=0)
198                 {
199                     snakeModel[i].type=stop;
200                 }
201             }
202             else
203             {
204                 snakeModel[i].type=null;
205             }    
206         }
207         for(i=0;i<FOOD_AMOUNT_MAX;i++)//初始化食物
208         {
209             foodModel[i].type=null;
210         }
211         addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX);
212         threadbool=1;//允许键盘控制
213         
214         /*游戏主循环*/
215         while(1)
216         {
217             int bctrlsnake=0;    //变色模式控制
218             for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
219             {
220                 if( i%SCR_WIDTH == 0|| i%SCR_WIDTH == SCR_WIDTH-1)
221                 {
222                     cmTEMP[i].type =wall;
223                     cmTEMP[i].chartype='|';
224                 }
225                 else if(i/SCR_WIDTH == 0 ||  i/SCR_WIDTH == SCR_HEIGHT-1)
226                 {
227                     cmTEMP[i].type =wall;
228                     cmTEMP[i].chartype='-';
229                 }
230                 else
231                 {
232                     cmTEMP[i].type=air;
233                     cmTEMP[i].chartype=' ';
234                 }
235             }
236             removSnake(snakeModel);    //移动蛇
237             /*添加食物图形*/
238             for(i=0;i<FOOD_AMOUNT_MAX;i++) 
239             {
240                 if(foodModel[i].type==null)
241                     continue;
242                 int sum;
243                 sum=foodModel[i].x+foodModel[i].y*SCR_WIDTH;
244                 cmTEMP[sum].type = food;
245                 cmTEMP[sum].chartype=FOOD_CHAR;
246             }
247             /*碰撞处理*/
248             int retdeal=collidedeal(cmTEMP,snakeModel);
249             if(retdeal==1)
250             {
251                 addsnakemod(snakeModel,1);
252                 for(i=0;i<FOOD_AMOUNT_MAX;i++)
253                 {
254                     if(foodModel[i].x==snakeModel[0].x && foodModel[i].y==snakeModel[0].y)
255                     {
256                         foodModel[i].type=null;
257                     }
258                 }
259                 addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX);
260                 bctrlsnake=1;    //变色
261             }
262             else if(retdeal==2)
263             {
264                 for(i=0;i<5;i++)
265                 {
266                     move(SCR_HEIGHT/2-1,SCR_WIDTH/2-5);
267                     attrset(COLOR_PAIR(40));
268                     printw("GAME OVER! %d...",5-i);
269                     refresh();
270                     sleep(1);
271                 }
272                 for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
273                 {
274                     if(i<SNAKE_LENGTH)
275                     {
276                         snakeModel[i].x= (SCR_WIDTH+SNAKE_LENGTH)/2-i;
277                         snakeModel[i].y= SCR_HEIGHT/2-1;
278                         snakeModel[i].type=stop;
279                     }
280                     else
281                     {
282                         snakeModel[i].type=null;
283                     }    
284                 }
285                 for(i=0;i<FOOD_AMOUNT_MAX;i++)
286                 {
287                     foodModel[i].type=null;
288                 }
289                 addfood(snakeModel,foodModel,FOOD_AMOUNT_MAX);
290                 if(usrctrl[1]==1)
291                 {
292                     snakeModel[0].type=right;
293                 }
294                 else
295                 {
296                     snakeModel[0].type=stop;
297                 }
298                 continue;
299             }
300             else if(retdeal==-1)
301             {
302                 program_error("Collidedeal type NULL");
303             }
304             /*关卡等级及游戏速度控制 并未实现*/
305             for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++) //添加蛇模型
306             {
307                 if(snakeModel[i].type==null)
308                 {
309                     break;
310                 }
311                 int sum;
312                 sum=snakeModel[i].x+snakeModel[i].y*SCR_WIDTH;
313                 cmTEMP[sum].type = wall;
314                 cmTEMP[sum].chartype=SNAKE_CHAR;
315                 if(i==0)
316                 {
317                     switch(snakeModel[0].type)
318                     {
319                         case left:
320                             cmTEMP[sum].chartype='<';
321                             break;
322                         case right:
323                             cmTEMP[sum].chartype='>';
324                             break;
325                         case up:
326                             cmTEMP[sum].chartype='^';
327                             break;
328                         case down:
329                             cmTEMP[sum].chartype='+';
330                             break;
331                         case stop:
332                             cmTEMP[sum].chartype='@';
333                             break;
334                         case null:
335                             program_error("SnakeModel[0] type NULL");
336                         default:
337                             program_error("SnakeModel[0] type =?");
338                     }
339                 }
340             }
341             /*玩家控制或者自动AI 即菜单选项1和2 */
342             if(usrctrl[1]==1)
343             {
344                 if(bctrlsnake==1)
345                 {
346                     writeLineQ (cmTEMP,5);
347                 }
348                 else
349                 {
350                     writeLineQ (cmTEMP,1);
351                 }
352                 snakeModel[0].type=EatAI(cmTEMP,snakeModel,foodModel);
353             }
354             else
355             {
356                 if(bctrlsnake==1)
357                 {
358                     writeLineQ (cmTEMP,4);
359                 }
360                 else
361                 {
362                     writeLineQ (cmTEMP,2);
363                 }
364                 switch(threadtype)
365                 {
366                         case stop:
367                         case left:
368                         case up:
369                         case down:
370                         case right:
371                             snakeModel[0].type=threadtype;
372                             break;
373                         case 4:
374                             exitbool = 1;
375                             break;
376                         default:
377                             break;
378                 }        
379             }
380             if(exitbool == 1)
381             {
382                 exitbool = 0;
383                 break;
384             }
385         }
386     }
387     endwin();
388     exit(EXIT_SUCCESS);
389 }
390 
391 void ctrltimes()
392 {
393     static int a=0;
394     a+=1;
395     if(a==CTRL_TIMES)
396     {
397         sleep(1);
398         a=0;
399     }
400 }
401 
402 void writeLineQ(charModel cmTEMP[],int bctrltime)
403 {
404     int i;
405     for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
406     {
407         move(i/SCR_WIDTH,i%SCR_WIDTH);
408         switch(cmTEMP[i].chartype)
409         {
410             case '+':
411             case '<':
412             case '>':
413             case '^':
414             case '@':
415             case SNAKE_CHAR:
416                 if(bctrltime==4||bctrltime==5)
417                 {
418                     attrset(COLOR_PAIR(31));
419                 }
420                 else
421                 {
422                     attrset(COLOR_PAIR(30));
423                 }
424                 break;
425             case FOOD_CHAR:
426                 attrset(COLOR_PAIR(20));
427                 break;
428             case '|':
429             case '-':
430                 attrset(COLOR_PAIR(10));
431                 break;
432             case '.':
433                 attrset(COLOR_PAIR(10));
434                 break;
435             case '=':
436                 attrset(COLOR_PAIR(10));
437                 break;
438             default:
439                 attrset(COLOR_PAIR(41));
440                 break;
441                 
442         }
443         addch((cmTEMP[i]).chartype);
444     }
445     refresh();
446     switch(bctrltime)
447     {
448         case 1:
449             ctrltimes();
450             break;
451         case 2:
452         case 5:
453             sleep(1);
454             break;
455         case 0:
456         case 4:
457             break;
458         default:
459             program_error("WriteLineQ bctrltime '=?'");
460     }
461 }
462 void removSnake(ctrlModel snakeModel[])
463 {
464     int i;
465     if( snakeModel[0].type==stop)
466     {
467         return;
468     }
469     for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
470     {
471         int nxtemp,nytemp,nttemp,xtemp,ytemp,ttemp;
472         if(snakeModel[i].type==null)
473         {
474             return;
475         }
476         nxtemp=snakeModel[i].x;
477         nytemp=snakeModel[i].y;
478         nttemp=snakeModel[i].type;
479         if(i==0)
480         {
481             xtemp=nxtemp;
482             ytemp=nytemp;
483             ttemp=nttemp;
484             switch(snakeModel[i].type)
485             {
486                 case left:
487                     snakeModel[i].x -=1;
488                     break;
489                 case right:
490                     snakeModel[i].x +=1;
491                     break;
492                 case up:
493                     snakeModel[i].y -=1;
494                     break;
495                 case down:
496                     snakeModel[i].y +=1;
497                     break;
498                 default:
499                     break;
500             }
501         }
502         else
503         {
504             snakeModel[i].x=xtemp;
505             snakeModel[i].y=ytemp;
506             snakeModel[i].type=ttemp;
507             xtemp=nxtemp;
508             ytemp=nytemp;
509             ttemp=nttemp;
510         }
511     }
512 }
513 
514 void fallremovSnake(ctrlModel snakeModel[])
515 {
516     int i,ctrls;
517     for(i=SCR_WIDTH*SCR_HEIGHT-1;i>=0;i--)
518     {
519         int nxtemp,nytemp,nttemp,xtemp,ytemp,ttemp;
520         if(snakeModel[i].type==null)
521         {
522             ctrls = 1;
523             continue;
524         }
525         nxtemp=snakeModel[i].x;
526         nytemp=snakeModel[i].y;
527         nttemp=snakeModel[i].type;
528         if(ctrls == 1)
529         {
530             xtemp=snakeModel[i].x;
531             ytemp=snakeModel[i].y;
532             ttemp=snakeModel[i].type;
533             switch(snakeModel[i].type)
534             {
535             case left:
536                 snakeModel[i].x +=1;
537                 break;
538             case right:
539                 snakeModel[i].x -=1;
540                 break;
541             case up:
542                 snakeModel[i].y +=1;
543                 break;
544             case down:
545                 snakeModel[i].y -=1;
546                 break;
547             default:
548                 break;
549             }
550             ctrls = 0 ;
551         }
552         else
553         {
554             snakeModel[i].x=xtemp;
555             snakeModel[i].y=ytemp;
556             snakeModel[i].type=ttemp;
557             xtemp=nxtemp;
558             ytemp=nytemp;
559             ttemp=nttemp;
560         }
561     }
562 }
563 
564 int collidedeal(charModel cmTEMP[],ctrlModel snakeModel[])
565 {
566     int i;
567     for(i=1;i<=SCR_WIDTH*SCR_HEIGHT;i++)
568     {
569         if(snakeModel[i].type==null)
570         {
571             break;
572         }
573         if(snakeModel[0].x==snakeModel[i].x && snakeModel[0].y==snakeModel[i].y)
574         {
575             return 2;
576         }
577     }
578     int sum;
579     sum=snakeModel[0].x+snakeModel[0].y*SCR_WIDTH;
580     switch(cmTEMP[sum].type)
581     {
582         case air:
583             return 0;
584         case food:
585             return 1;
586         case wall:
587             return 2;
588         default:
589             return -1;
590     }
591 }
592 
593 void addfood(ctrlModel snakeModel[],ctrlModel foodModel[],int amount)
594 {
595     
596     int i;
597     for(i=0;i<amount;i++)
598     {
599         if(foodModel[i].type!=null)
600         {
601             return;
602         }
603     }
604     for(i=0;i<amount;i++)
605     {
606         int x,y,randx;
607         do
608         {
609             randx=rand();
610         }while(randx>=SCR_WIDTH*SCR_HEIGHT);
611         x=randx%SCR_WIDTH;y=randx/SCR_WIDTH;
612         if(x!=0 && y!=0 && x!= SCR_WIDTH-1 && y!=SCR_HEIGHT-1)
613         {
614             int times,ctrlbool=0;
615             for(times=0;times<SCR_WIDTH*SCR_WIDTH;times++)
616             {
617                 if(snakeModel[times].type==null)
618                 {
619                     break;
620                 }
621                 else if(snakeModel[times].x==x && snakeModel[times].y==y)
622                 {
623                         ctrlbool=-1;
624                         break;
625                 }
626             }
627             if(ctrlbool==-1)
628             {
629                 i--;
630             }
631             else
632             {
633                 foodModel[i].x=x;
634                 foodModel[i].y=y;
635                 foodModel[i].type=stop;
636             }
637             
638         }
639         else
640         {
641             i--;
642         }
643     }
644 }
645 
646 void addsnakemod(ctrlModel snakeModel[],int amount)
647 {
648     int i,times;
649     for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
650     {
651         if( snakeModel[i].type==null)
652         {
653             for(times=0;times<amount;times++)
654             {
655                 snakeModel[i+times].type=stop;
656                 switch(snakeModel[i+times-1].type)
657                 {
658                     
659                     case left:
660                         snakeModel[i+times].x=snakeModel[i+times-1].x+1;
661                         snakeModel[i+times].y=snakeModel[i+times-1].y;
662                         break;
663                     case right:
664                         snakeModel[i+times].x=snakeModel[i+times-1].x-1;
665                         snakeModel[i+times].y=snakeModel[i+times-1].y;
666                         break;
667                     case up:
668                         snakeModel[i+times].x=snakeModel[i+times-1].x;
669                         snakeModel[i+times].y=snakeModel[i+times-1].y+1;
670                         break;
671                     case down:
672                         snakeModel[i+times].x=snakeModel[i+times-1].x;
673                         snakeModel[i+times].y=snakeModel[i+times-1].y-1;
674                         break;
675                     default:
676                         break;
677                 }
678             }
679             return;
680         }    
681     }    
682 }
683 
684 void program_error(char error_string[])
685 {
686     attrset(COLOR_PAIR(50));
687     int i;
688     for(i=0;i<SCR_WIDTH*SCR_HEIGHT;i++)
689     {
690         move(i/SCR_WIDTH,i%SCR_WIDTH);
691         addch(' ');
692     }
693     move(SCR_HEIGHT/2,0);
694     printw("***  (ERROR) \"%s\"",error_string);
695     refresh();
696     sleep(5);
697     exit(0);
698 }

snakeAI.c

  1 #include "snakeHead.h"
  2 
  3 int calculate(charModel cmTEMP[],ctrlModel snakeModel[],int direction);
  4 movtype DirectionAlt(movtype type,int direction)
  5 {
  6     int irand;
  7     switch(direction)
  8     {
  9         case 1:
 10             return type;
 11         case 2:
 12             switch(type)
 13             {
 14                 case left:
 15                     return down;
 16                 case right:
 17                     return up;
 18                 case up:
 19                     return left;
 20                 case down:
 21                     return right;
 22                 default:
 23                     return stop;
 24             }
 25         case 4:
 26             switch(type)
 27             {
 28                 case left:
 29                     return up;
 30                 case right:
 31                     return down;
 32                 case up:
 33                     return right;
 34                 case down:
 35                     return left;
 36                 default:
 37                     return stop;
 38             }
 39         case 3://随即选定一个方向
 40         case 5:
 41             irand=rand();
 42             irand=irand%2;
 43             if(irand==0)
 44             {
 45                 return type;
 46             }
 47             else
 48             {
 49                 return DirectionAlt(type,direction-1);
 50             }
 51         case 6://随即选定一个方向
 52             irand=rand();
 53             irand=irand%2;
 54             if(irand==0)
 55             {
 56                 return DirectionAlt(type,2);
 57             }
 58             else
 59             {
 60                 return DirectionAlt(type,4);
 61                 }
 62         case 7://随即选定一个方向
 63             irand=rand();
 64             irand=irand%3;
 65             if(irand==0)
 66             {
 67                 return type;
 68             }
 69             else if(irand==1)
 70             {
 71                 return DirectionAlt(type,2);
 72             }
 73             else 
 74             {
 75                 return DirectionAlt(type,4);
 76             }
 77         default:
 78             return stop;
 79     }
 80 }
 81 
 82 movtype EatAI(charModel cmTEMP[],ctrlModel snakeModel[],ctrlModel foodModel[])
 83 {
 84     int ix,iy,i,foodamount[FOOD_AMOUNT_MAX],distance=SCR_WIDTH*SCR_HEIGHT,numfood[2];
 85     
 86     /*寻找头部周围的身体*/
 87     int headbar[4]={0,0,0,0};//[0]左 [1]右 [2]上 [3]下
 88     for(i=1;i<SCR_WIDTH*SCR_HEIGHT;i++)
 89     {
 90         if(snakeModel[i].type==null)
 91         {
 92             break;
 93         }
 94         else if(snakeModel[i].x==snakeModel[0].x)
 95         {
 96             if(snakeModel[i].y==snakeModel[0].y-1)
 97             {
 98                 headbar[2]=1;
 99             }
100             else if(snakeModel[i].y==snakeModel[0].y+1)
101             {
102                 headbar[3]=1;
103             }
104         }
105         else if(snakeModel[i].y==snakeModel[0].y)
106         {
107             if(snakeModel[i].x==snakeModel[0].x-1)
108             {
109                 headbar[0]=1;
110             }
111             else if(snakeModel[i].x==snakeModel[0].x+1)
112             {
113                 headbar[1]=1;
114             }
115         }
116     }
117     int direction=7; //1为向前 2为向左 4为向右 ,1+2 1+4 2+4 1+2+4 方向组合
118     
119     /*排除算法 排除墙体和身体碰撞*/
120     switch(snakeModel[0].type)
121     {
122         case left:
123             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
124             {
125                 direction-=1;
126             }
127             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
128             {
129                 direction-=2;
130             }
131             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
132             {
133                 direction-=4;
134             }
135             break;
136         case right:
137             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
138             {
139                 direction-=1;
140             }
141             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
142             {
143                 direction-=2;
144             }
145             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
146             {
147                 direction-=4;
148             }
149             break;
150         case up:
151             if(cmTEMP[snakeModel[0].x+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
152             {
153                 direction-=1;
154             }
155             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
156             {
157                 direction-=2;
158             }
159             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
160             {
161                 direction-=4;
162             }
163             break;
164         case down:
165             if(cmTEMP[snakeModel[0].x+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
166             {
167                 direction-=1;
168             }
169             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
170             {
171                 direction-=2;
172             }
173             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
174             {
175                 direction-=4;
176             }
177             break;
178         case stop:
179         default:
180             return stop;    
181     }
182     
183     /*走投无路,自我毁灭*/
184     if(direction==0){
185         return snakeModel[0].type;}
186         
187     /*带深度递归,检验方向可行性,防止自我封闭*/
188     if(direction!=1 && direction!=2 && direction!=4)
189     {
190          direction=calculate(cmTEMP,snakeModel,direction);
191      }
192         
193     /*自动寻物*/
194     for(i=0;i<FOOD_AMOUNT_MAX;i++)//取相对距离,并选取最小值
195     {
196         if(foodModel[i].type==null)
197         {
198             continue;
199         }
200         ix=snakeModel[0].x-foodModel[i].x;iy=snakeModel[0].y-foodModel[i].y;
201         foodamount[i]=ix*ix+iy*iy;//平面两点坐标公式 x^2+y^2
202         if(distance>foodamount[i])
203         {
204             numfood[0]=foodModel[i].x;
205             numfood[1]=foodModel[i].y;
206             distance=foodamount[i];
207         }
208     }
209     /*创建寻物方向*/
210     int fooddirection=0,subx=snakeModel[0].x-numfood[0],suby=snakeModel[0].y-numfood[1];
211     if(subx == 0)
212     {
213         if(suby < 0)
214         {
215             switch(snakeModel[0].type)
216             {
217                 case left:
218                     fooddirection+=2;
219                     break;
220                 case right:
221                     fooddirection+=4;
222                     break;
223                 case up:
224                     fooddirection+=6;
225                     break;
226                 case down:
227                     fooddirection+=1;
228                     break;    
229                 default:
230                     break;
231             }
232         }
233         else if(suby > 0)
234         {
235             switch(snakeModel[0].type)
236             {
237                 case left:
238                     fooddirection+=4;
239                     break;
240                 case right:
241                     fooddirection+=2;
242                     break;
243                 case up:
244                     fooddirection+=1;
245                     break;
246                 case down:
247                     fooddirection+=6;
248                     break;    
249                 default:
250                     break;
251             }
252         }
253     }
254     else if(subx<0)
255     {
256         if(suby== 0)
257         {
258             switch(snakeModel[0].type)
259             {
260                 case left:
261                     fooddirection+=6;
262                     break;
263                 case right:
264                     fooddirection+=1;
265                     break;
266                 case up:
267                     fooddirection+=4;
268                     break;
269                 case down:
270                     fooddirection+=2;
271                     break;    
272                 default:
273                     break;
274             }
275         }
276         else if(suby < 0)
277         {
278             switch(snakeModel[0].type)
279             {
280                 case left:
281                     fooddirection+=2;
282                     break;
283                 case right:
284                     fooddirection+=5;
285                     break;
286                 case up:
287                     fooddirection+=4;
288                     break;
289                 case down:
290                     fooddirection+=3;
291                     break;    
292                 default:
293                     break;
294             }
295         }
296         else{
297             switch(snakeModel[0].type)
298             {
299                 case left:
300                     fooddirection+=4;
301                     break;
302                 case right:
303                     fooddirection+=3;
304                     break;
305                 case up:
306                     fooddirection+=5;
307                     break;
308                 case down:
309                     fooddirection+=2;
310                     break;    
311                 default:
312                     break;
313             }
314         }
315     }
316     else{
317         if(suby== 0)
318         {
319             switch(snakeModel[0].type)
320             {
321                 case left:
322                     fooddirection+=1;
323                     break;
324                 case right:
325                     fooddirection+=6;
326                     break;
327                 case up:
328                     fooddirection+=2;
329                     break;
330                 case down:
331                     fooddirection+=4;
332                     break;    
333                 default:
334                     break;
335             }
336         }
337         else if(suby < 0)
338         {
339             switch(snakeModel[0].type)
340             {
341                 case left:
342                     fooddirection+=3;
343                     break;
344                 case right:
345                     fooddirection+=4;
346                     break;
347                 case up:
348                     fooddirection+=2;
349                     break;
350                 case down:
351                     fooddirection+=5;
352                     break;    
353                 default:
354                     break;
355             }
356         }
357         else{
358             switch(snakeModel[0].type)
359             {
360                 case left:
361                     fooddirection+=5;
362                     break;
363                 case right:
364                     fooddirection+=2;
365                     break;
366                 case up:
367                     fooddirection+=3;
368                     break;
369                 case down:
370                     fooddirection+=4;
371                     break;    
372                 default:
373                     break;
374             }
375         }
376     }
377     switch(direction)
378     {
379         case 1:
380             return snakeModel[0].type;
381         case 2:
382         case 4:
383             return DirectionAlt(snakeModel[0].type,direction);
384         case 7://前左右
385             return DirectionAlt(snakeModel[0].type,fooddirection);
386         case 6://左右
387             if(fooddirection>=direction || fooddirection==1)
388             {
389                 return DirectionAlt(snakeModel[0].type,6);
390             }
391             else if(fooddirection==2 || fooddirection==4)
392             {
393                 return DirectionAlt(snakeModel[0].type,fooddirection);
394             }
395             else if(fooddirection==3 || fooddirection==5)
396             {
397                 return DirectionAlt(snakeModel[0].type,fooddirection-1);
398             }    
399         case 3://前左
400             if(fooddirection<=3)
401             {
402                 return DirectionAlt(snakeModel[0].type,fooddirection);
403             }
404             else if(fooddirection==5||fooddirection==6)
405             {
406                 return DirectionAlt(snakeModel[0].type,fooddirection-4);
407             }
408             else if(fooddirection==4||fooddirection==7)
409             {
410                 return DirectionAlt(snakeModel[0].type,3);
411             }
412         case 5://前右
413             if(fooddirection==5||fooddirection==7)
414             {
415                 return DirectionAlt(snakeModel[0].type,5);
416             }
417             else if(fooddirection<=3)
418             {
419                 return DirectionAlt(snakeModel[0].type,1);
420             }
421             else if(fooddirection==4||fooddirection==6)
422             {
423                 return DirectionAlt(snakeModel[0].type,4);
424             }
425         default:
426             return stop;
427     }
428 }
429 
430 /*自动寻物递归精简版本*/
431 movtype ToWhy(charModel cmTEMP[],ctrlModel snakeModel[])
432 {
433     int i;
434     int headbar[4]={0,0,0,0};
435     for(i=1;i<SCR_WIDTH*SCR_HEIGHT;i++)
436     {
437         if(snakeModel[i].type==null)
438         {
439             break;
440         }
441         else if(snakeModel[i].x==snakeModel[0].x)
442         {
443             if(snakeModel[i].y==snakeModel[0].y-1)
444             {
445                 headbar[2]=1;
446             }
447             else if(snakeModel[i].y==snakeModel[0].y+1)
448             {
449                 headbar[3]=1;
450             }
451         }
452         else if(snakeModel[i].y==snakeModel[0].y)
453         {
454             if(snakeModel[i].x==snakeModel[0].x-1)
455             {
456                 headbar[0]=1;
457             }
458             else if(snakeModel[i].x==snakeModel[0].x+1)
459             {
460                 headbar[1]=1;
461             }
462         }
463     }
464     int direction=7; //1为向前 2为向左 4为向右 ,1+2 1+4 2+4 1+2+4 方向组合
465     switch(snakeModel[0].type)
466     {
467         case left:
468             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
469             {
470                 direction-=1;
471             }
472             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
473             {
474                 direction-=2;
475             }
476             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
477             {
478                 direction-=4;
479             }
480             break;
481         case right:
482             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
483             {
484                 direction-=1;
485             }
486             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
487             {
488                 direction-=2;
489             }
490             if(cmTEMP[(snakeModel[0].x)+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
491             {
492                 direction-=4;
493             }
494             break;
495         case up:
496             if(cmTEMP[snakeModel[0].x+(snakeModel[0].y-1)*60].type==wall || headbar[2]==1)
497             {
498                 direction-=1;
499             }
500             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
501             {
502                 direction-=2;
503             }
504             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
505             {
506                 direction-=4;
507             }
508             break;
509         case down:
510             if(cmTEMP[snakeModel[0].x+(snakeModel[0].y+1)*60].type==wall || headbar[3]==1)
511             {
512                 direction-=1;
513             }
514             if(cmTEMP[(snakeModel[0].x+1)+snakeModel[0].y*60].type==wall || headbar[1]==1)
515             {
516                 direction-=2;
517             }
518             if(cmTEMP[(snakeModel[0].x-1)+snakeModel[0].y*60].type==wall || headbar[0]==1)
519             {
520                 direction-=4;
521             }
522             break;
523         case stop:
524         default:
525             return stop;    
526     }
527     return direction;
528 }
529 
530 int depthrecurrence(charModel charTEMP[],ctrlModel TEMP_snake[],int depth,int direction,int DIR[])
531 {
532     if(depth <= 0)
533     {
534         return 0;
535     }
536     int x,y,z;
537     switch(direction)
538     {
539         case 0:
540             return 1;
541         case 1:
542             TEMP_snake[0].type = DirectionAlt(TEMP_snake[0].type,1);
543             removSnake(TEMP_snake);
544             DIR[1] = depthrecurrence(charTEMP,TEMP_snake,depth-1,ToWhy(charTEMP,TEMP_snake),DIR) + DIR[1];
545             fallremovSnake(TEMP_snake);
546             return DIR[1];
547         case 2:
548             TEMP_snake[0].type=DirectionAlt(TEMP_snake[0].type,2);
549             removSnake(TEMP_snake);
550             DIR[2] = depthrecurrence(charTEMP,TEMP_snake,depth-1,ToWhy(charTEMP,TEMP_snake),DIR) + DIR[2];
551             fallremovSnake(TEMP_snake);
552             return DIR[2];
553         case 3:
554             x = depthrecurrence(charTEMP,TEMP_snake,depth-1,1,DIR);
555             y = depthrecurrence(charTEMP,TEMP_snake,depth-1,2,DIR);
556             if(x>=y){DIR[3] = x + 1;}else{DIR[3] = y + 1;}
557             return DIR[3];    
558         case 4:
559             TEMP_snake[0].type=DirectionAlt(TEMP_snake[0].type,4);
560             removSnake(TEMP_snake);
561             DIR[4] = depthrecurrence(charTEMP,TEMP_snake,depth-1,ToWhy(charTEMP,TEMP_snake),DIR) + DIR[2];
562             fallremovSnake(TEMP_snake);
563             return DIR[4];
564         case 5:
565             x = depthrecurrence(charTEMP,TEMP_snake,depth-1,1,DIR);
566             y = depthrecurrence(charTEMP,TEMP_snake,depth-1,4,DIR);
567             if(x>=y){DIR[5] = x + 1;}else{DIR[5] = y + 1;}
568             return DIR[5];
569         case 6:
570             DIR[6] += 1;
571             x = depthrecurrence(charTEMP,TEMP_snake,depth-1,2,DIR);
572             y = depthrecurrence(charTEMP,TEMP_snake,depth-1,4,DIR);
573             if(x>=y){DIR[6] = x + 1;}else{DIR[6] = y + 1;}
574             return DIR[6];
575         case 7:
576             DIR[7] += 1;
577             x = depthrecurrence(charTEMP,TEMP_snake,depth-1,1,DIR);
578             y = depthrecurrence(charTEMP,TEMP_snake,depth-1,2,DIR);
579             z = depthrecurrence(charTEMP,TEMP_snake,depth-1,4,DIR);
580             if(x>=y)
581             {
582                 if(x>=z){DIR[7] = x + 1;}else{DIR[7] = z + 1;}
583             }
584             else
585             {
586                 if(y>=z){DIR[7] = y + 1;}else{DIR[7] = z + 1;}
587             }
588             return DIR[7];
589         default:
590             program_error("Direction type =?");
591             return -1;
592             
593     }
594 }
595 
596 int calculate(charModel cmTEMP[],ctrlModel snakeModel[],int direction)
597 {
598     int i,x;
599     int DIR[8]={0,0,0,0,0,0,0,0};
600     DIR[8]=direction;
601     ctrlModel TEMP_snake[SCR_WIDTH*SCR_HEIGHT];
602     for(i = 0; i<SCR_WIDTH*SCR_HEIGHT; i++)
603     {
604         if(snakeModel[i].type == null)
605         {
606             break;
607         }
608         TEMP_snake[i]=snakeModel[i];
609     }
610     depthrecurrence(cmTEMP,TEMP_snake,SNAKEAI_DEPTH,direction,DIR);
611     x=DIR[0];
612     for(i = 1;i<=6;i++)
613     {
614         if(x<=DIR[i+1])
615         {
616             x=DIR[i+1];
617             DIR[8] = i+1;
618         }
619     }
620     switch(direction)
621     {
622             case 7:
623                 break;
624             case 3:
625                 if(DIR[8] == 1 || DIR[8] == 2 || DIR[8] == 3){break;}
626                 else{DIR[8] = direction;}
627                 break;
628             case 5:
629                 if(DIR[8] == 1 || DIR[8] == 4 || DIR[8] == 5){break;}
630                 else{DIR[8] = direction;}
631                 break;
632             case 6:
633                 if(DIR[8] == 2 || DIR[8] == 4 || DIR[8] == 6){break;}
634                 else{DIR[8] = direction;}
635                 break;
636             case 1:
637             case 2:
638             case 4:
639                 DIR[8] = direction;
640                 break;
641             default:
642                 DIR[8] = direction;
643                 break;
644     }
645     
646     
647     return DIR[8];
648 }
649 
650 
651 
652 //~ int closegraph(charModel cmTEMP[],ctrlModel snakeModel[],int direction)
653 //~ {
654     //~ /*检测是否为闭合图形 1 蛇模型闭合 2 蛇模型+边界闭合 (沒有实现)*/
655     //~ int i;
656     //~ for(i=SCR_WIDTH*SCR_HEIGHT-1;i>=0;i--)//从蛇尾到倒找
657     //~ {
658         //~ if(snakeModel[i].type==null)
659         //~ {
660             //~ continue;
661         //~ }
662         //~ if(i==2)
663         //~ {
664             //~ return direction;
665         //~ }
666         //~ if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;}
667         //~ if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y==snakeModel[0].y){break;}
668         //~ if(snakeModel[i].x-1==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;}
669         //~ if(snakeModel[i].x==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;}
670         //~ if(snakeModel[i].x==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;}
671         //~ if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y-1==snakeModel[0].y){break;}
672         //~ if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y==snakeModel[0].y){break;}
673         //~ if(snakeModel[i].x+1==snakeModel[0].x && snakeModel[i].y+1==snakeModel[0].y){break;}
674     //~ }
675     //~ /*如果结点为末尾无视*/
676     //~ if(snakeModel[i+1].type==null){return direction;}
677     //~ /*判断前结点方向*/
678     //~ movtype direfalse[2]={null,null};
679     //~ if(snakeModel[i-1].x==snakeModel[i].x)
680     //~ {
681         //~ if(snakeModel[i-1].y-snakeModel[i].y==1)
682         //~ {
683             //~ direfalse[0]=down;
684         //~ }
685         //~ else
686         //~ {
687             //~ direfalse[0]=up;
688         //~ }
689     //~ }
690     //~ else if(snakeModel[i-1].y==snakeModel[i].y)
691     //~ {
692         //~ if(snakeModel[i-1].x-snakeModel[i].x==-1)
693         //~ {
694             //~ direfalse[0]=left;
695         //~ }
696         //~ else
697         //~ {
698             //~ direfalse[0]=right;
699         //~ }
700     //~ }
701     //~ /*判断后结点方向*/
702     //~ if(snakeModel[i].x==snakeModel[i+1].x)
703     //~ {
704         //~ if(snakeModel[i].y-snakeModel[i+1].y==1)
705         //~ {
706             //~ direfalse[1]=down;
707         //~ }
708         //~ else
709         //~ {
710             //~ direfalse[1]=up;
711         //~ }
712     //~ }
713     //~ else if(snakeModel[i].y==snakeModel[i+1].y)
714     //~ {
715         //~ if(snakeModel[i].x-snakeModel[i+1].x==-1)
716         //~ {
717             //~ direfalse[1]=left;
718         //~ }
719         //~ else
720         //~ {
721             //~ direfalse[1]=right;
722         //~ }
723     //~ }
724     //~ /*方向*/
725     //~ for(i=0;i<2;i++)
726     //~ {
727         //~ if(snakeModel[0].type==direfalse[i])
728         //~ {
729             //~ direction-=1;
730             //~ continue;
731         //~ }
732         //~ if(direfalse[0]==direfalse[1])
733         //~ {
734             //~ break;
735         //~ }              
736         //~ switch(snakeModel[0].type)
737         //~ {
738             //~ case 0:
739                 //~ if(direfalse[i]==2)
740                 //~ {
741                     //~ direction-=4;
742                 //~ }
743                 //~ else if(direfalse[i]==3)
744                 //~ {
745                     //~ direction-=2;
746                 //~ }
747                 //~ break;
748             //~ case 1:
749                 //~ if(direfalse[i]==2)
750                 //~ {
751                     //~ direction-=2;
752                 //~ }
753                 //~ else if(direfalse[i]==3)
754                 //~ {
755                     //~ direction-=4;
756                 //~ }
757                 //~ break;
758             //~ case 2:
759                 //~ if(direfalse[i]==0)
760                 //~ {
761                     //~ direction-=2;
762                 //~ }
763                 //~ else if(direfalse[i]==1)
764                 //~ {
765                     //~ direction-=4;
766                 //~ }
767                 //~ break;
768             //~ case 3:
769                 //~ if(direfalse[i]==0)
770                 //~ {
771                     //~ direction-=4;
772                 //~ }
773                 //~ else if(direfalse[i]==1)
774                 //~ {
775                     //~ direction-=2;
776                 //~ }
777                 //~ break;
778             //~ default:
779                 //~ break;
780         //~ }
781     //~ }
782     //~ return direction;
783 //~ }

snakeHead.h

 1 #include <unistd.h>
 2 #include <stdlib.h>
 3 #include <curses.h>
 4 #include <time.h>
 5 #include <pthread.h>
 6 typedef enum {null=-2,stop=-1,left=0,right=1,up=2,down=3}movtype;
 7 typedef enum {air,food,wall}coltype;
 8 typedef struct {
 9     coltype type; 
10     int chartype;
11 }charModel;
12 typedef struct {
13     int x;
14     int y;
15     movtype type; 
16 }ctrlModel;
17 void writeLineQ(charModel cmTemp[],int bctrltime);
18 void removSnake(ctrlModel snakeModel[]);
19 void fallremovSnake(ctrlModel snakeModel[]);
20 int collidedeal(charModel cmTEMP[],ctrlModel snakeModel[]);
21 void addfood(ctrlModel snakeModel[],ctrlModel foodModel[],int amount);
22 void addsnakemod(ctrlModel snakeModel[],int amount);
23 void program_error(char error_string[]);
24 
25 #define SCR_WIDTH 60
26 #define SCR_HEIGHT 20
27 #define SNAKE_CHAR '*'
28 #define SNAKE_LENGTH 8
29 #define FOOD_AMOUNT_MAX 10
30 #define FOOD_CHAR '0'
31 #define SNAKEAI_DEPTH 15

截图:

转载于:https://www.cnblogs.com/gnuer/archive/2012/10/29/2745211.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值