00001 #include <ecf/ECF.h>
00002 #include "AgentEvalOp.h"
00003 #include "Maze.h"
00004 #include <ctime>
00005
00006 Maze individualMaze, maze8x8, maze15x15a, maze9x6, maze12x16;
00007 int startingDirection8x8, startingDirection15x15a, startingDirection9x6, startingDirection12x16;
00008 pair<int,int> posOffset8x8, posOffset15x15a, posOffset9x6, posOffset12x16;
00009
00010
00011 bool AgentEvalOp::initialize(StateP state)
00012 {
00013 state_ = state;
00014
00015 srand( (unsigned int) time(NULL) );
00016
00017
00018
00019
00020 maze8x8.GenerateMaze(make_pair(8,8));
00021
00022 maze15x15a.GenerateMaze(make_pair(15,15));
00023
00024 maze9x6.GenerateMaze(make_pair(9,6));
00025
00026 maze12x16.GenerateMaze(make_pair(12,16));
00027
00028
00029
00030
00031
00032 posOffset8x8 = make_pair( rand() % maze8x8.GetHeight(), rand() % maze8x8.GetWidth() );
00033 startingDirection8x8 = rand() % 4;
00034
00035 posOffset15x15a = make_pair( rand() % maze15x15a.GetHeight(), rand() % maze15x15a.GetWidth() );
00036 startingDirection15x15a = rand() % 4;
00037
00038 posOffset9x6 = make_pair( rand() % maze9x6.GetHeight(), rand() % maze9x6.GetWidth() );
00039 startingDirection9x6 = rand() % 4;
00040
00041 posOffset12x16 = make_pair( rand() % maze12x16.GetHeight(), rand() % maze12x16.GetWidth() );
00042 startingDirection12x16 = rand() % 4;
00043
00044 maze8x8.SaveMazeToFile( "labirintTest1.txt", posOffset8x8, startingDirection8x8 );
00045 maze15x15a.SaveMazeToFile( "labirintTest2.txt", posOffset15x15a, startingDirection15x15a );
00046 maze9x6.SaveMazeToFile( "labirintTest3.txt", posOffset9x6, startingDirection9x6 );
00047 maze12x16.SaveMazeToFile( "labirintTest4.txt", posOffset12x16, startingDirection12x16 );
00048
00049 return true;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 FitnessP AgentEvalOp::evaluate(IndividualP individual)
00061 {
00062
00063 double fit = 0;
00064 double lastMetric = 0, exBestMetric = 0, newMetric = 0;
00065 int counter = 0;
00066
00067 FitnessP fitness (new FitnessMax);
00068
00069 Tree::Tree* tree = (Tree::Tree*) individual->getGenotype().get();
00070
00071 for(int testNumb = 0; testNumb < 4; testNumb++)
00072 {
00073 switch(testNumb)
00074 {
00075 case 0:
00076 individualMaze = maze8x8;
00077 startingDirection = startingDirection8x8;
00078 posOffset = posOffset8x8;
00079 break;
00080 case 1:
00081 individualMaze = maze15x15a;
00082 startingDirection = startingDirection15x15a;
00083 posOffset = posOffset15x15a;
00084 break;
00085 case 2:
00086 individualMaze = maze9x6;
00087 startingDirection = startingDirection9x6;
00088 posOffset = posOffset9x6;
00089 break;
00090 case 3:
00091 individualMaze = maze12x16;
00092 startingDirection = startingDirection12x16;
00093 posOffset = posOffset12x16;
00094 break;
00095 default :
00096 exit(0);
00097 }
00098
00099 memory.clear();
00100 direction = startingDirection;
00101 moves = 0;
00102 steps = 0;
00103 isOut = false;
00104 counter = 0;
00105 currentPosition = make_pair(0,0);
00106
00107 lastMetric = exBestMetric = newMetric = individualMaze.FindMetric( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ));
00108
00109 while(moves < 800 && !isOut)
00110 {
00111 tree->execute(this);
00112 counter++;
00113
00114 if(!(counter % 11))
00115 {
00116 newMetric = individualMaze.FindMetric( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ));
00117 if(exBestMetric > newMetric)
00118 {
00119 fit += 10;
00120 exBestMetric = newMetric;
00121 }
00122 }
00123
00124 if(!(counter % 6))
00125 {
00126 newMetric = individualMaze.FindMetric( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ));
00127 if( newMetric == lastMetric )
00128 fit -= 10;
00129 lastMetric = newMetric;
00130 }
00131
00132 }
00133
00134 fit += steps;
00135
00136 if (isOut)
00137 fit += 2000;
00138 }
00139
00140
00141 fitness->setValue(fit);
00142 return fitness;
00143 }
00144
00145
00146 void AgentEvalOp::turnLeft()
00147 {
00148 moves++;
00149 direction = direction - 1;
00150 if( direction == -1 )
00151 direction = 3;
00152 }
00153
00154 void AgentEvalOp::turnRight()
00155 {
00156 moves++;
00157 direction = (direction + 1) % 4;
00158 }
00159
00160
00161
00162
00163
00164
00165 void AgentEvalOp::stepFoward()
00166 {
00167
00168
00169 if( individualMaze.IsThereWallAhead( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ), direction ) )
00170 moves++;
00171 else
00172 {
00173 memory.insert( currentPosition );
00174
00175 if( direction == 0 )
00176 currentPosition.first = currentPosition.first - 1;
00177 if( direction == 1 )
00178 currentPosition.second = currentPosition.second + 1;
00179 if( direction == 2 )
00180 currentPosition.first = currentPosition.first + 1;
00181 if( direction == 3 )
00182 currentPosition.second = currentPosition.second - 1;
00183
00184 moves++;
00185 steps++;
00186
00187 if( individualMaze.IsExit( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ) ) )
00188 isOut = true;
00189 }
00190
00191 }
00192
00193 bool AgentEvalOp::checkFrontWall()
00194 {
00195 if( individualMaze.IsThereWallAhead( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ), direction ) )
00196 return true;
00197 else return false;
00198 }
00199
00200 bool AgentEvalOp::checkLeftWall()
00201 {
00202 int tmpDirection;
00203 tmpDirection = direction - 1;
00204
00205 if( tmpDirection == -1 )
00206 tmpDirection = 3;
00207
00208 if( individualMaze.IsThereWallAhead( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ), tmpDirection ) )
00209 return true;
00210 else return false;
00211 }
00212 bool AgentEvalOp::checkRightWall()
00213 {
00214 int tmpDirection;
00215 tmpDirection = (direction + 1) % 4;
00216
00217 if( individualMaze.IsThereWallAhead( make_pair( currentPosition.first + posOffset.first, currentPosition.second + posOffset.second ), tmpDirection ) )
00218 return true;
00219 else return false;
00220 }
00221
00222
00223
00224
00225
00226
00227 int AgentEvalOp::checkIfVisited()
00228 {
00229 pair<int,int> nextPosition;
00230
00231 nextPosition = currentPosition;
00232
00233 if( checkFrontWall() )
00234 return 2;
00235 else
00236 {
00237 if( direction == 0 )
00238 nextPosition.first = currentPosition.first - 1;
00239 if( direction == 1 )
00240 nextPosition.second = currentPosition.second + 1;
00241 if( direction == 2 )
00242 nextPosition.first = currentPosition.first + 1;
00243 if( direction == 3 )
00244 nextPosition.second = currentPosition.second - 1;
00245
00246 if( memory.find(nextPosition) != memory.end() )
00247 return 1;
00248
00249 else return 0;
00250 }
00251 }