原文出處: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,®s0,®s0); 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,®s0,®s0); 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;