蚁群算法简介与小程序(1)


原文出处:http://tech.ddvip.com/2009-04/1239243667114090.html,转载请注明原始出处。

程序开始运行,蚂蚁们开始从窝里出动了,寻找食物;他们会顺着屏幕爬满整个画面,直到找到食物再返回窝。 

其中,‘F’点表示食物,‘H’表示窝,白色块表示障碍物,‘+’就是蚂蚁了。 

预期的结果:各个蚂蚁在没有事先告诉他们食物在什么地方的前提下开始寻找食物。当一只找到食物以后,它会向环境释放一种信息素,吸引其他的蚂蚁过来,这样越来越多的蚂蚁会找到食物!有些蚂蚁并没有象其它蚂蚁一样总重复同样的路,他们会另辟蹊径,如果令开辟的道路比原来的其他道路更短,那么,渐渐,更多的蚂蚁被吸引到这条较短的路上来。最后,经过一段时间运行,可能会出现一条最短的路径被大多数蚂蚁重复着。 

原理:为什么小小的蚂蚁能够找到食物?他们具有智能么?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。 

然而,事实并没有你想得那么复杂,上面这个程序每个蚂蚁的核心程序编码不过100多行!为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就是人工生命、复杂性科学解释的规律!那么,这些简单规则是什么呢? 

下面详细说明: 

1、范围:蚂蚁观察到的范围是一个方格世界,蚂蚁有一个参数为速度半径(一般是3),那么它能观察到的范围就是3*3个方格世界,并且能移动的距离也在这个范围之内。 

2、环境:蚂蚁所在的环境是一个虚拟的世界,其中有障碍物,有别的蚂蚁,还有信息素,信息素有两种,一种是找到食物的蚂蚁洒下的食物信息素,一种是找到窝的蚂蚁洒下的窝的信息素。每个蚂蚁都仅仅能感知它范围内的环境信息。环境以一定的速率让信息素消失。 

3、觅食规则:在每只蚂蚁能感知的范围内寻找是否有食物,如果有就直接过去。否则看是否有信息素,并且比较在能感知的范围内哪一点的信息素最多,这样,它就朝信息素多的地方走,并且每只蚂蚁多会以小概率犯错误,从而并不是往信息素最多的点移动。蚂蚁找窝的规则和上面一样,只不过它对窝的信息素做出反应,而对食物信息素没反应。 

4、移动规则:每只蚂蚁都朝向信息素最多的方向移,并且,当周围没有信息素指引的时候,蚂蚁会按照自己原来运动的方向惯性的运动下去,并且,在运动的方向有一个随机的小的扰动。为了防止蚂蚁原地转圈,它会记住最近刚走过了哪些点,如果发现要走的下一点已经在最近走过了,它就会尽量避开。 

5、避障规则:如果蚂蚁要移动的方向有障碍物挡住,它会随机的选择另一个方向,并且有信息素指引的话,它会按照觅食的规则行为。 

6、播撒信息素规则:每只蚂蚁在刚找到食物或者窝的时候撒发的信息素最多,并随着它走远的距离,播撒的信息素越来越少。 

根据这几条规则,蚂蚁之间并没有直接的关系,但是每只蚂蚁都和环境发生交互,而通过信息素这个纽带,实际上把各个蚂蚁之间关联起来了。比如,当一只蚂蚁找到了食物,它并没有直接告诉其它蚂蚁这儿有食物,而是向环境播撒信息素,当其它的蚂蚁经过它附近的时候,就会感觉到信息素的存在,进而根据信息素的指引找到了食物。 

问题:说了这么多,蚂蚁究竟是怎么找到食物的呢? 

在没有蚂蚁找到食物的时候,环境没有有用的信息素,那么蚂蚁为什么会相对有效的找到食物呢?这要归功于蚂蚁的移动规则,尤其是在没有信息素时候的移动规则。首先,它要能尽量保持某种惯性,这样使得蚂蚁尽量向前方移动(开始,这个前方是随机固定的一个方向),而不是原地无谓的打转或者震动;其次,蚂蚁要有一定的随机性,虽然有了固定的方向,但它也不能像粒子一样直线运动下去,而是有一个随机的干扰。这样就使得蚂蚁运动起来具有了一定的目的性,尽量保持原来的方向,但又有新的试探,尤其当碰到障碍物的时候它会立即改变方向,这可以看成一种选择的过程,也就是环境的障碍物让蚂蚁的某个方向正确,而其他方向则不对。这就解释了为什么单个蚂蚁在复杂的诸如迷宫的地图中仍然能找到隐蔽得很好的食物。 

当然,在有一只蚂蚁找到了食物的时候,其他蚂蚁会沿着信息素很快找到食物的。 

蚂蚁如何找到最短路径的?这一是要归功于信息素,另外要归功于环境,具体说是计算机时钟。信息素多的地方显然经过这里的蚂蚁会多,因而会有更多的蚂蚁聚集过来。假设有两条路从窝通向食物,开始的时候,走这两条路的蚂蚁数量同样多(或者较长的路上蚂蚁多,这也无关紧要)。当蚂蚁沿着一条路到达终点以后会马上返回来,这样,短的路蚂蚁来回一次的时间就短,这也意味着重复的频率就快,因而在单位时间里走过的蚂蚁数目就多,洒下的信息素自然也会多,自然会有更多的蚂蚁被吸引过来,从而洒下更多的信息素……;而长的路正相反,因此,越来越多地蚂蚁聚集到较短的路径上来,最短的路径就近似找到了。也许有人会问局部最短路径和全局最短路的问题,实际上蚂蚁逐渐接近全局最短路的,为什么呢?这源于蚂蚁会犯错误,也就是它会按照一定的概率不往信息素高的地方走而另辟蹊径,这可以理解为一种创新,这种创新如果能缩短路途,那么根据刚才叙述的原理,更多的蚂蚁会被吸引过来。 

引申跟着蚂蚁的踪迹,你找到了什么?通过上面的原理叙述和实际操作,我们不难发现蚂蚁之所以具有智能行为,完全归功于它的简单行为规则,而这些规则综合起来具有下面两个方面的特点: 

1、多样性2、正反馈多样性保证了蚂蚁在觅食的时候不置走进死胡同而无限循环,正反馈机制则保证了相对优良的信息能够被保存下来。我们可以把多样性看成是一种创造能力,而正反馈是一种学习强化能力。正反馈的力量也可以比喻成权威的意见,而多样性是打破权威体现的创造性,正是这两点小心翼翼的巧妙结合才使得智能行为涌现出来了。[Page]引申来讲,大自然的进化,社会的进步、人类的创新实际上都离不开这两样东西,多样性保证了系统的创新能力,正反馈保证了优良特性能够得到强化,两者要恰到好处的结合。如果多样性过剩,也就是系统过于活跃,这相当于蚂蚁会过多的随机运动,它就会陷入混沌状态;而相反,多样性不够,正反馈机制过强,那么系统就好比一潭死水。这在蚁群中来讲就表现为,蚂蚁的行为过于僵硬,当环境变化了,蚂蚁群仍然不能适当的调整。

既然复杂性、智能行为是根据底层规则涌现的,既然底层规则具有多样性和正反馈特点,那么也许你会问这些规则是哪里来的?多样性和正反馈又是哪里来的?我本人的意见:规则来源于大自然的进化。而大自然的进化根据刚才讲的也体现为多样性和正反馈的巧妙结合。而这样的巧妙结合又是为什么呢?为什么在你眼前呈现的世界是如此栩栩如生呢?答案在于环境造就了这一切,之所以你看到栩栩如生的世界,是因为那些不能够适应环境的多样性与正反馈的结合都已经死掉了,被环境淘汰了! 

参数说明:最大信息素:蚂蚁在一开始拥有的信息素总量,越大表示程序在较长一段时间能够存在信息素。信息素消减的速度:随着时间的流逝,已经存在于世界上的信息素会消减,这个数值越大,那么消减的越快。 

错误概率表示这个蚂蚁不往信息素最大的区域走的概率,越大则表示这个蚂蚁越有创新性。 

速度半径表示蚂蚁一次能走的最大长度,也表示这个蚂蚁的感知范围。 

记忆能力表示蚂蚁能记住多少个刚刚走过点的坐标,这个值避免了蚂蚁在本地打转,停滞不前。而这个值越大那么整个系统运行速度就慢,越小则蚂蚁越容易原地转圈。 

 

代码如下:

  1  /*ant.c*/
  2  
  3  
  4 #define SPACE 0x20
  5  
  6 #define ESC 0x1b
  7  
  8 #define ANT_CHAR_EMPTY '+'
  9  
 10 #define ANT_CHAR_FOOD 153
 11  
 12 #define HOME_CHAR 'H'
 13  
 14 #define FOOD_CHAR 'F'
 15  
 16 #define FOOD_CHAR2 'f'
 17  
 18 #define FOOD_HOME_COLOR 12
 19  
 20 #define BLOCK_CHAR 177
 21  
 22  
 23 #define MAX_ANT 50
 24  
 25 #define INI_SPEED 3
 26  
 27 #define MAXX 80
 28  
 29 #define MAXY 23
 30  
 31 #define MAX_FOOD 10000
 32  
 33 #define TARGET_FOOD 200
 34  
 35 #define MAX_SMELL 5000
 36  
 37 #define SMELL_DROP_RATE 0.05
 38  
 39 #define ANT_ERROR_RATE 0.02
 40  
 41 #define ANT_EYESHOT 3
 42  
 43 #define SMELL_GONE_SPEED 50
 44  
 45 #define SMELL_GONE_RATE 0.05
 46  
 47 #define TRACE_REMEMBER 50
 48  
 49 #define MAX_BLOCK 100
 50  
 51  
 52 #define NULL 0
 53  
 54 #define UP 1
 55  
 56 #define DOWN 2
 57  
 58 #define LEFT 3
 59  
 60 #define RIGHT 4
 61  
 62 #define SMELL_TYPE_FOOD 0
 63  
 64 #define SMELL_TYPE_HOME 1
 65  
 66  
 67 #include "stdio.h"
 68  
 69 #include "conio.h"
 70  
 71 #include "dos.h"
 72  
 73 #include "stdlib.h"
 74  
 75 #include "dos.h"
 76  
 77 #include "process.h"
 78  
 79 #include "ctype.h"
 80  
 81 #include "math.h"
 82  
 83  
 84 void WorldInitial(void);
 85  
 86 void BlockInitial(void);
 87  
 88 void CreatBlock(void);
 89  
 90 void SaveBlock(void);
 91  
 92 void LoadBlock(void);
 93  
 94 void HomeFoodInitial(void);
 95  
 96 void AntInitial(void);
 97  
 98 void WorldChange(void);
 99  
100 void AntMove(void);
101  
102 void AntOneStep(void);
103  
104 void DealKey(char key);
105  
106 void ClearSmellDisp(void);
107  
108 void DispSmell(int type);
109  
110 int AntNextDir(int xxx,int yyy,int ddir);
111  
112 int GetMaxSmell(int type,int xxx,int yyy,int ddir);[Page]
113  
114 int IsTrace(int xxx,int yyy);
115  
116 int MaxLocation(int num1,int num2,int num3);
117  
118 int CanGo(int xxx,int yyy,int ddir);
119  
120 int JudgeCanGo(int xxx,int yyy);
121  
122 int TurnLeft(int ddir);
123  
124 int TurnRight(int ddir);
125  
126 int TurnBack(int ddir);
127  
128  
129 int MainTimer(void);
130  
131 char WaitForKey(int secnum);
132  
133 void DispPlayTime(void);
134  
135 int TimeUse(void);
136  
137 void HideCur(void);
138  
139 void ResetCur(void);
140  
141  
142 /* ---------------  */
143  
144 struct HomeStruct
145  
146 {
147  
148     int xxx,yyy;
149  
150     int amount;
151  
152     int TargetFood;
153  
154 }home;
155  
156  
157 struct FoodStruct
158  
159 {
160  
161     int xxx,yyy;
162  
163     int amount;
164  
165 }food;
166  
167  
168 struct AntStruct
169  
170 {
171  
172     int xxx,yyy;
173  
174     int dir;
175  
176     int speed;
177  
178     int SpeedTimer;
179  
180     int food;
181  
182     int SmellAmount[2];
183  
184     int tracex[TRACE_REMEMBER];
185  
186     int tracey[TRACE_REMEMBER];
187  
188     int TracePtr;
189  
190     int IQ;
191  
192 }ant[MAX_ANT];
193  
194 int AntNow;
195  
196 int timer10ms;
197  
198 struct time starttime,endtime;
199  
200 int Smell[2][MAXX+1][MAXY+1];
201  
202 int block[MAXX+1][MAXY+1];
203  
204 int SmellGoneTimer;
205  
206 int SmellDispFlag;
207  
208 int CanFindFood;
209  
210 int HardtoFindPath;
211  
212  
213 /* ----- Main -------- */
214  
215 void main(void)
216  
217 {
218  
219     char KeyPress;
220  
221     int tu;
222  
223  
224     clrscr();
225  
226     HideCur();
227  
228     WorldInitial();
229  
230     do
231  
232     {
233  
234         timer10ms = MainTimer();
235  
236         if(timer10ms) AntMove();
237  
238         if(timer10ms) WorldChange();
239  
240         tu = TimeUse();
241  
242         if(tu>=60&&!CanFindFood)
243  
244   {
245  
246             gotoxy(1,MAXY+1);
247  
248             printf("Can not find food, maybe a block world.");
249  
250             WaitForKey(10);
251  
252             WorldInitial();
253  
254         }
255  
256         if(tu>=180&&home.amount<100&&!HardtoFindPath)
257  
258         {
259  
260             gotoxy(1,MAXY+1);
261  
262             printf("God! it is so difficult to find a path.");[Page]
263  
264             if(WaitForKey(10)==0x0d) WorldInitial();
265  
266             else
267  
268          {
269  
270                 HardtoFindPath = 1;
271  
272                 gotoxy(1,MAXY+1);
273  
274                 printf("                                       ");
275  
276          }
277  
278         }
279  
280         if(home.amount>=home.TargetFood)
281  
282         {
283  
284             gettime(&endtime);
285  
286             KeyPress = WaitForKey(60);
287  
288             DispPlayTime();
289  
290             WaitForKey(10);
291  
292             WorldInitial();
293  
294         }
295  
296         else if(kbhit())
297  
298         {
299  
300             KeyPress = getch();
301  
302             DealKey(KeyPress);
303  
304         }
305  
306         else KeyPress = NULL;
307  
308     }
309  
310     while(KeyPress!=ESC);
311  
312     gettime(&endtime);
313  
314     DispPlayTime();
315  
316     WaitForKey(10);
317  
318     clrscr();
319  
320     ResetCur();
321  
322 }
323  
324  
325 /* ------ general sub process ----------- */
326  
327 int MainTimer(void)
328  
329 /* output: how much 10ms have pass from last time call this process */
330  
331 {
332  
333     static int oldhund,oldsec;
334  
335     struct  time t;
336  
337     int timeuse;
338  
339  
340     gettime(&t);
341  
342     timeuse = 0;
343  
344     if(t.ti_hund!=oldhund)
345  
346     {
347  
348         if(t.ti_sec!=oldsec)[Page]
349  
350         {
351  
352             timeuse+=100;
353  
354             oldsec = t.ti_sec;
355  
356         }
357  
358         timeuse+=t.ti_hund-oldhund;
359  
360         oldhund = t.ti_hund;
361  
362     }
363  
364     else timeuse = 0;
365  
366     return (timeuse);
367  
368 }
369  
370  
371 char WaitForKey(int secnum)
372  
373 /* funtion: if have key in, exit immediately, else wait 'secnum' senconds then exit
374  
375    input: secnum -- wait this senconds, must < 3600 (1 hour)
376  
377    output: key char, if no key in(exit when timeout), return NULL */
378  
379 {
380  
381     int secin,secnow;
382  
383     int minin,minnow;
384  
385     int hourin,hournow;
386  
387     int secuse;
388  
389     struct  time t;
390  
391  
392     gettime(&t);
393  
394     secin = t.ti_sec;
395  
396     minin = t.ti_min;
397  
398     hourin = t.ti_hour;
399  
400  
401     do
402  
403     {
404  
405         if(kbhit()) return(getch());
406  
407         gettime(&t);
408  
409         secnow = t.ti_sec;
410  
411         minnow = t.ti_min;
412  
413         hournow = t.ti_hour;
414  
415  
416  
417  
418  if(hournow!=hourin) minnow+=60;
419  
420         if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin);
421  
422         else secuse = secnow - secin;
423  
424  
425         /* counting error check */
426  
427         if(secuse<0)
428  
429         {
430  
431             gotoxy(1,MAXY+1);
432  
433             printf("Time conuting error, any keyto exit...");
434  
435             getch();
436  
437             exit(3);
438  
439         }
440  
441     }
442  
443     while(secuse<=secnum);
444  
445     return (NULL);
446  
447 }
448  
449  
450 void DispPlayTime(void)
451  
452 {
453  
454     int ph,pm,ps;
455  
456  
457     ph = endtime.ti_hour - starttime.ti_hour;[Page]
458  
459     pm = endtime.ti_min - starttime.ti_min;
460  
461     ps = endtime.ti_sec - starttime.ti_sec;
462  
463  
464     if(ph<0) ph+=24;
465  
466     if(pm<0) { ph--; pm+=60; }
467  
468     if(ps<0) { pm--; ps+=60; }
469  
470  
471     gotoxy(1,MAXY+1);
472  
473     printf("Time use: %d hour- %d min- %d sec ",ph,pm,ps);
474  
475 }
476  
477  
478 int TimeUse(void)
479  
480 {
481  
482     int ph,pm,ps;
483  
484  
485     gettime(&endtime);
486  
487     ph = endtime.ti_hour - starttime.ti_hour;
488  
489     pm = endtime.ti_min - starttime.ti_min;
490  
491     ps = endtime.ti_sec - starttime.ti_sec;
492  
493  
494     if(ph<0) ph+=24;
495  
496     if(pm<0) { ph--; pm+=60; }
497  
498     if(ps<0) { pm--; ps+=60; }
499  
500  
501     return(ps+(60*(pm+60*ph)));
502  
503 }
504  
505  
506  
507 void HideCur(void)
508  
509 {
510  
511     union REGS regs0;
512  
513     regs0.h.ah=1;
514  
515     regs0.h.ch=0x30;
516  
517     regs0.h.cl=0x31;
518  
519     int86(0x10,&regs0,&regs0);
520  
521 }
522  
523  
524 void ResetCur(void)
525  
526 {
527  
528     union REGS regs0;
529  
530     regs0.h.ah=1;
531  
532     regs0.h.ch=0x06;
533  
534     regs0.h.cl=0x07;
535  
536     int86(0x10,&regs0,&regs0);
537  
538 }
539  
540  
541 /* ------------ main ANT programe ------------- */
542  
543 void WorldInitial(void)
544  
545 {
546  
547     int k,i,j;
548  
549     randomize();
550  
551     clrscr();
552  
553     HomeFoodInitial();
554  
555     for(AntNow=0;AntNow<MAX_ANT;AntNow++)
556  
557     {
558  
559         AntInitial();
560  
561     } /* of for AntNow */;
562  
563  
564     BlockInitial();
565  
566     for(k=0;k<=1;k++)
567  
568     /* SMELL TYPE FOOD and HOME */
569  
570         for(i=0;i<=MAXX;i++)
571  
572             for(j=0;j<=MAXY;j++)
573  
574                 Smell[k][i][j] = 0;
575  
576     SmellGoneTimer = 0;
577  
578     gettime(&starttime);
579  
580     SmellDispFlag = 0;
581  
582     CanFindFood = 0;
583  
584     HardtoFindPath = 0;
585  
586 }
587  
588  
589 void BlockInitial(void)
590  
591 {
592  
593     int i,j;
594  
595     int bn;
596  
597  
598     for(i=0;i<=MAXX;i++)
599  
600         for(j=0;j<=MAXY;j++)[Page]
601  
602             block[i][j] = 0;
603  
604  
605     bn = 1+ MAX_BLOCK/2 + random(MAX_BLOCK/2);
606  
607     for(i=0;i<=bn;i++) CreatBlock();
608  
609 }
610  
611  
612 void CreatBlock(void)
613  
614 {
615  
616     int x1,y1,x2,y2;
617  
618     int dx,dy;
619  
620     int i,j;
621  
622  
623     x1 = random(MAXX)+1;
624  
625     y1 = random(MAXY)+1;
626  
627  
628     dx = random(MAXX/10)+1;
629  
630     dy = random(MAXY/10)+1;
631  
632  
633     x2 = x1+dx;
634  
635     y2 = y1+dy;
636  
637  
638     if(x2>MAXX) x2 = MAXX;
639  
640     if(y2>MAXY) y2 = MAXY;
641  
642  
643     if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2) return;
644  
645     if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2) return;
646  
647  
648 for(i=x1;i<=x2;i++)
649  
650         for(j=y1;j<=y2;j++)
651  
652         {
653  
654             block[i][j] = 1;
655  
656             gotoxy(i,j);
657  
658             putch(BLOCK_CHAR);
659  
660         }
661  
662 }
663  
664  
665 void SaveBlock(void)
666  
667 {
668  
669  FILE *fp_block;
670  
671  char FileNameBlock[20];
672  
673  int i,j;
674  
675  
676  gotoxy(1,MAXY+1);
677  
678     printf("                                       ");
679  
680  gotoxy(1,MAXY+1);
681  
682  printf("Save to file...",FileNameBlock);
683  
684  gets(FileNameBlock);
685  
686  if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");
687  
688  else strcat(FileNameBlock,".ant");
689  
690  
691  if ((fp_block = fopen(FileNameBlock, "wb")) == NULL)
692  
693  { gotoxy(1,MAXY+1);
694  
695         printf("Creat file %s fail...",FileNameBlock);
696  
697   getch();
698  
699   exit(2);
700  
701  }
702  
703  gotoxy(1,MAXY+1);
704  
705     printf("                                                     "); [Page]
706  
707  
708  fputc(home.xxx,fp_block);
709  
710  fputc(home.yyy,fp_block);
711  
712  fputc(food.xxx,fp_block);
713  
714  fputc(food.yyy,fp_block);
715  
716  
717  for(i=0;i<=MAXX;i++)
718  
719         for(j=0;j<=MAXY;j++)
720  
721             fputc(block[i][j],fp_block);
722  
723  
724     fclose(fp_block);
725  
726 }
727  
728  
729 void LoadBlock(void)
730  
731 {
732  
733  FILE *fp_block;
734  
735  char FileNameBlock[20];
736  
737  int i,j,k;
738  
739  
740  gotoxy(1,MAXY+1);
741  
742     printf("                                       ");
743  
744  gotoxy(1,MAXY+1);
745  
746  printf("Load file...",FileNameBlock);
747  
748  gets(FileNameBlock);
749  
750  if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");
751  
752  else strcat(FileNameBlock,".ant");
753  
754  
755  if ((fp_block = fopen(FileNameBlock, "rb")) == NULL)
756  
757  { gotoxy(1,MAXY+1);
758  
759         printf("Open file %s fail...",FileNameBlock);
760  
761   getch();
762  
763   exit(2);
764  
765  }
766  
767  
768  clrscr();
769  
770  home.xxx = fgetc(fp_block);
771  
772  home.yyy = fgetc(fp_block);
773  
774  food.xxx = fgetc(fp_block);
775  
776  food.yyy = fgetc(fp_block);
777  
778  gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);
779  
780     gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR);
781  
782     food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1;
783  
784     /* food.amount = MAX_FOOD; */
785  
786     home.amount = 0;
787  
788     home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD;
789  
790  
791  for(AntNow=0;AntNow<MAX_ANT;AntNow++)
792  
793     {
794  
795         AntInitial();
796  
797     } /* of for AntNow */;
798  
799  
800  for(i=0;i<=MAXX;i++)
801  
802         for(j=0;j<=MAXY;j++)
803  
804         {
805  
806             block[i][j] = fgetc(fp_block);
807  
808             if(block[i][j])
809  
810             {
811  
812              gotoxy(i,j);
813  
814              putch(BLOCK_CHAR);
815  
816          }
817  
818         }[Page]
819  
820  
821     for(k=0;k<=1;k++)
822  
823     /* SMELL TYPE FOOD and HOME */
824  
825         for(i=0;i<=MAXX;i++)
826  
827             for(j=0;j<=MAXY;j++)
828  
829                 Smell[k][i][j] = 0;
830  
831     SmellGoneTimer = 0;
832  
833     gettime(&starttime);
834  
835     SmellDispFlag = 0;
836  
837     CanFindFood = 0;
838  
839     HardtoFindPath = 0;


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM