/*ant.c*/ #define SPACE 0x20 /*按键定义*/ #define ESC 0x1b #define ANT_CHAR_EMPTY '+' #define ANT_CHAR_FOOD 153 /*携带食物的蚂蚁*/ #define HOME_CHAR 'H' #define FOOD_CHAR 'F' #define FOOD_CHAR2 'f' #define FOOD_HOME_COLOR 12 /*红色*/ #define BLOCK_CHAR 177 /*障碍物*/ #define MAX_ANT 50 /*蚂蚁数量*/ #define INI_SPEED 3 /*速度半径为3*3*/ #define MAXX 80 /*活动空间为80*23格*/ #define MAXY 23 #define MAX_FOOD 10000 /*最大食物量*/ #define TARGET_FOOD 200 /*需要采集回家的食物量*/ #define MAX_SMELL 5000 /*最大信息素*/ #define SMELL_DROP_RATE 0.05 /*信息素释放率*/ #define ANT_ERROR_RATE 0.02 /*蚂蚁犯错率(创新率)*/ #define ANT_EYESHOT 3 /**/ #define SMELL_GONE_SPEED 50 /*信息素消失速度*/ #define SMELL_GONE_RATE 0.05 /*信息素消失比率*/ #define TRACE_REMEMBER 50 /*蚂蚁记忆力*/ #define MAX_BLOCK 100 /*最大障碍物个数*/ #define NULL 0 #define UP 1 /*方向定义*/ #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define SMELL_TYPE_FOOD 0 /*信息素类型定义*/ #define SMELL_TYPE_HOME 1 #include "stdio.h" #include "conio.h" /*getch函数需要此头文件*/ #include "dos.h" #include "stdlib.h" #include "dos.h" #include "process.h" #include "ctype.h" #include "math.h" void WorldInitial(void); /*环境初始化函数*/ void BlockInitial(void); /*障碍物地图初始化*/ void CreatBlock(void); /*产生障碍物地图*/ void SaveBlock(void); /*保存障碍物地图*/ void LoadBlock(void); /*载入障碍物地图*/ void HomeFoodInitial(void); /*食物与家的位置初始化*/ void AntInitial(void); /*蚂蚁初始化*/ void WorldChange(void); /*更改环境*/ void AntMove(void); /*蚂蚁移动*/ void AntOneStep(void); /*蚂蚁动作一步*/ void DealKey(char key); /*按键扫描,功能键有p,t,1,2,3,s,l*/ void ClearSmellDisp(void); /*关闭信息素的显示*/ void DispSmell(int type); /*显示当前信息素的情况*/ int AntNextDir(int xxx,int yyy,int ddir); /*得到蚂蚁下一次移动的方向*/ int GetMaxSmell(int type,int xxx,int yyy,int ddir); /*获取最大信息素的值*/ int IsTrace(int xxx,int yyy); /*是否是曾经走过的路径*/ int MaxLocation(int num1,int num2,int num3); /*获得三个值中最大的一个的序号*/ int CanGo(int xxx,int yyy,int ddir); /*返回可以走的路径*/ int JudgeCanGo(int xxx,int yyy); /*判断某方向是否可以通过*/ int TurnLeft(int ddir); /*左传,右转,后退*/ int TurnRight(int ddir); int TurnBack(int ddir); int MainTimer(void); /*返回自上次调用后经历了多少个10ms的时间*/ char WaitForKey(int secnum); /*没有键则等待键盘输入,有键则返回键值*/ void DispPlayTime(void); /*显示运行时间*/ int TimeUse(void); /*计算时间花费*/ void HideCur(void); /*隐藏鼠标*/ void ResetCur(void); /*重置鼠标*/ /* --------------- */ struct HomeStruct { int xxx,yyy; int amount; /*已经搬运回家的食物数量*/ int TargetFood; /*需要搬运回家的食物数量*/ }home; struct FoodStruct { int xxx,yyy; int amount; /*剩余食物数量*/ }food; struct AntStruct { int xxx,yyy; /*蚂蚁当前位置*/ int dir; /*行走方向*/ int speed; /*蚂蚁速度,即计数器计到此则移动一步,所以越小蚂蚁移动越快*/ int SpeedTimer; /*速度计数器,每10ms记一次*/ int food; /*是否携带食物*/ int SmellAmount[2]; /*两种信息素的含量*/ int tracex[TRACE_REMEMBER]; /*所记忆的x坐标*/ int tracey[TRACE_REMEMBER]; /*所记忆的y坐标*/ int TracePtr; /*记录路径所用的指针*/ int IQ; /*好象没有用到。。。。。*/ }ant[MAX_ANT]; /*全局变量定义*/ int AntNow; /*当前蚂蚁*/ int timer10ms; /*记录多少个10ms已经过去*/ struct time starttime,endtime; /*起始结束时间定义*/ int Smell[2][MAXX+1][MAXY+1]; /*信息素数组*/ int block[MAXX+1][MAXY+1]; /*障碍物数组*/ int SmellGoneTimer; /*信息素消失计数器*/ int SmellDispFlag; /*信息素显示标志*/ int CanFindFood; /*可以找到获取食物的路径标志*/ int HardtoFindPath; /*找到路径比较困难的标志*/ /* ----- Main -------- */ void main(void) { char KeyPress; int tu; clrscr(); HideCur(); WorldInitial(); do { timer10ms = MainTimer(); if(timer10ms) AntMove(); if(timer10ms) WorldChange(); tu = TimeUse(); if(tu>=60&&!CanFindFood) { gotoxy(1,MAXY+1); printf("Can not find food, maybe a block world."); WaitForKey(10); WorldInitial(); } if(tu>=180&&home.amount<100&&!HardtoFindPath) { gotoxy(1,MAXY+1); printf("God! it is so difficult to find a path."); if(WaitForKey(10)==0x0d) WorldInitial(); else { HardtoFindPath = 1; gotoxy(1,MAXY+1); printf(" "); } } if(home.amount>=home.TargetFood) { gettime(&endtime); KeyPress = WaitForKey(60); DispPlayTime(); WaitForKey(10); WorldInitial(); } else if(kbhit()) { KeyPress = getch(); DealKey(KeyPress); } else KeyPress = NULL; } while(KeyPress!=ESC); gettime(&endtime); DispPlayTime(); WaitForKey(10); clrscr(); ResetCur(); } /* ------ general sub process ----------- */ int MainTimer(void) /* output: how much 10ms have pass from last time call this process */ { static int oldhund,oldsec; struct time t; int timeuse; gettime(&t); timeuse = 0; if(t.ti_hund!=oldhund) { if(t.ti_sec!=oldsec) { timeuse+=100; oldsec = t.ti_sec; } timeuse+=t.ti_hund-oldhund; oldhund = t.ti_hund; } else timeuse = 0; return (timeuse); } char WaitForKey(int secnum) /* funtion: if have key in, exit immediately, else wait 'secnum' senconds then exit input: secnum -- wait this senconds, must < 3600 (1 hour) output: key char, if no key in(exit when timeout), return NULL */ { int secin,secnow; int minin,minnow; int hourin,hournow; int secuse; struct time t; gettime(&t); secin = t.ti_sec; minin = t.ti_min; hourin = t.ti_hour; do { if(kbhit()) return(getch()); gettime(&t); secnow = t.ti_sec; minnow = t.ti_min; hournow = t.ti_hour; if(hournow!=hourin) minnow+=60; if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin); else secuse = secnow - secin; /* counting error check */ if(secuse<0) { gotoxy(1,MAXY+1); printf("Time conuting error, any keyto exit..."); getch(); exit(3); } } while(secuse<=secnum); return (NULL); } void DispPlayTime(void) { int ph,pm,ps; ph = endtime.ti_hour - starttime.ti_hour; pm = endtime.ti_min - starttime.ti_min; ps =