蟻群算法簡介與小程序(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