00001 #include <cmath>
00002 #include <ecf/ECF.h>
00003 #include "AntEvalOp.h"
00004 #include <iostream>
00005 #include <fstream>
00006 #include <vector>
00007 #include <iostream>
00008 #include <string>
00009 using namespace std;
00010
00011
00012 bool AntEvalOp::trace = false;
00013 bool AntEvalOp::step = false;
00014 const char AntEvalOp::LEFT = '<';
00015 const char AntEvalOp::RIGHT = '>';
00016 const char AntEvalOp::UP = '^';
00017 const char AntEvalOp::DOWN = 'v';
00018
00019
00023 ostream& operator<<(ostream& os, AntEvalOp& ant)
00024 {
00025 for (uint j = 0; j < ant.tmpRow; j++) {
00026 os << endl;
00027 for (uint k = 0; k < ant.tmpColumn; k++)
00028 os << ant.tmpBoard[j * ant.tmpColumn + k];
00029 }
00030 os << endl;
00031 return os;
00032 }
00033
00034
00035 void AntEvalOp::registerParameters(StateP state)
00036 {
00037 state->getRegistry()->registerEntry("learning_trails", (voidP) (new std::string("learning_trails.txt")), ECF::STRING);
00038 state->getRegistry()->registerEntry("test_trails", (voidP) (new std::string("test_trails.txt")), ECF::STRING);
00039 }
00040
00041
00045 bool AntEvalOp::initialize(StateP state)
00046 {
00047 state_ = state;
00048
00049 state->getContext()->environment = this;
00050
00051 voidP sptr = state->getRegistry()->getEntry("learning_trails");
00052 std::string filePath = *((std::string*) sptr.get());
00053
00054 ifstream file;
00055 file.open(filePath.c_str());
00056
00057 if(!file.is_open()) {
00058 ECF_LOG_ERROR(state, "Error: can't open input file " + filePath);
00059 return false;
00060 }
00061
00062
00063 file >> boardNo;
00064
00065
00066 for (uint k = 0; k < boardNo; k++) {
00067 tmpRow = tmpColumn = tmpMaxSteps = 0;
00068 file >> tmpRow;
00069 file >> tmpColumn;
00070 file >> tmpFoodNo;
00071 file.ignore(1);
00072 file >> tmpMaxSteps;
00073
00074 rowNo.push_back(tmpRow);
00075 columnNo.push_back(tmpColumn);
00076 maxSteps.push_back(tmpMaxSteps);
00077 foodNo.push_back(tmpFoodNo);
00078
00079 tmpBoard = (char*) malloc (tmpRow * tmpColumn);
00080
00081
00082 for (uint i = 0; i < tmpRow; i++ )
00083 for (uint j = 0; j < tmpColumn; j++)
00084 file >> tmpBoard[i * tmpColumn + j];
00085
00086 board.push_back(tmpBoard);
00087 }
00088
00089 file.close();
00090
00091 return true;
00092 }
00093
00094
00098 FitnessP AntEvalOp::evaluate(IndividualP individual)
00099 {
00100
00101 FitnessP fitness (new FitnessMax);
00102
00103
00104 Tree::Tree* tree = (Tree::Tree*) individual->getGenotype().get();
00105
00106
00107 ofstream output;
00108 if (trace) {
00109 currentTree = tree->toString();
00110 output.open("./output.txt");
00111 output << "Number of trails: " << boardNo << endl;
00112 }
00113
00114 int allTheFood = 0;
00115 for (uint i = 0; i < boardNo; i++) {
00116
00117 x_ = y_ = 0;
00118 moves_ = 0;
00119 facing_ = 0;
00120 foodEaten_ = 0;
00121
00122
00123 tmpRow = rowNo[i];
00124 tmpColumn = columnNo[i];
00125 tmpMaxSteps = maxSteps[i];
00126 tmpFoodNo = foodNo[i];
00127
00128 tmpBoard = (char*) malloc (tmpRow * tmpColumn);
00129
00130
00131 for (uint j = 0; j < tmpRow; j++)
00132 for (uint k = 0; k < tmpColumn; k++)
00133 tmpBoard[j * tmpColumn + k] = board[i][j * tmpColumn + k];
00134
00135
00136 if (tmpBoard[0] == 'x')
00137 foodEaten_++;
00138
00139 if (trace)
00140 if (tmpBoard[0] == 'x')
00141 tmpBoard[0] = -2;
00142 else tmpBoard[0] = 'o';
00143
00144
00145 while(moves_ < tmpMaxSteps && foodEaten_< tmpFoodNo) {
00146 tree->execute(this);
00147 }
00148 allTheFood += foodEaten_;
00149
00150
00151 if (trace) {
00152 output << "Dimension: " << tmpColumn << "x" << tmpRow << endl;
00153 output << "Food: " << tmpFoodNo << endl;
00154 output << "Max Steps: " << tmpMaxSteps << endl;
00155 output << "Fitness (eaten food): " << foodEaten_ << endl;
00156 output << *this << endl;
00157 }
00158
00159
00160 if (trace) {
00161 cout << *this;
00162 cout << "Eaten food: " << foodEaten_ << endl;
00163 }
00164 free(tmpBoard);
00165 }
00166
00167
00168 if (trace) {
00169 cout << "Food eaten in all the enviroments: " << allTheFood << endl;
00170 output << "Total fitness: " << allTheFood << endl;
00171 output.close();
00172 }
00173
00174 fitness->setValue(allTheFood);
00175
00176 return fitness;
00177 }
00178
00179
00183 void AntEvalOp::turnLeft()
00184 {
00185 if (moves_ >= tmpMaxSteps) return;
00186 moves_++;
00187
00188 facing_ = (facing_ - 1) % 4;
00189 if(trace && step)
00190 showStep("left");
00191 }
00192
00193
00197 void AntEvalOp::turnRight()
00198 {
00199 if (moves_ >= tmpMaxSteps) return;
00200 moves_++;
00201
00202 facing_ = (facing_ + 1) % 4;
00203 if(trace && step)
00204 showStep("right");
00205 }
00206
00207
00211 void AntEvalOp::moveAhead()
00212 {
00213 if (moves_ >= tmpMaxSteps) return;
00214 moves_++;
00215
00216
00217
00218 switch (facing_)
00219 {
00220 case 3:
00221 y_ = (y_ - 1) % tmpRow;
00222 break;
00223 case 2:
00224 x_ = (x_ - 1) % tmpColumn;
00225 break;
00226 case 1:
00227 y_ = (y_ + 1) % tmpRow;
00228 break;
00229 case 0:
00230 x_ = (x_ + 1) % tmpColumn;
00231 break;
00232 default:
00233 break;
00234 }
00235
00236
00237 if (tmpBoard[y_*tmpColumn+x_] == 'x') {
00238 foodEaten_++;
00239 if (trace)
00240 tmpBoard[y_*tmpColumn+x_] = -2;
00241 else
00242 tmpBoard[y_*tmpColumn+x_] = '.';
00243 }
00244 if(trace) {
00245 if(tmpBoard[y_*tmpColumn+x_] == '.')
00246 tmpBoard[y_*tmpColumn+x_] = 'o';
00247 if(step)
00248 showStep("move");
00249 }
00250 }
00251
00252
00256 bool AntEvalOp::facingFood()
00257 {
00258 int x1,y1;
00259 x1 = x_;
00260 y1 = y_;
00261 switch (facing_)
00262 {
00263 case 3: y1 = (y_==0 ? tmpRow-1 : y_-1); break;
00264 case 2: x1 = (x_==0 ? tmpColumn-1 : x_-1); break;
00265 case 1: y1 = (y_+1)%tmpRow; break;
00266 case 0: x1 = (x_+1)%tmpColumn; break;
00267 }
00268 if (tmpBoard[y1 * tmpColumn + x1] == 'x')
00269 return true;
00270 return false;
00271 }
00272
00273
00277 void AntEvalOp::showStep(string action)
00278 {
00279 cout << "Ant: " << currentTree << endl;
00280 cout << "Action: " << action << ", moves: " << moves_ << "/" << tmpMaxSteps << endl;
00281
00282 char ant, position = tmpBoard[y_ * tmpColumn + x_];
00283 switch (facing_) {
00284 case 3: ant = UP; break;
00285 case 2: ant = LEFT; break;
00286 case 1: ant = DOWN; break;
00287 case 0: ant = RIGHT; break;
00288 }
00289
00290 tmpBoard[y_ * tmpColumn + x_] = ant;
00291 cout << *this;
00292 tmpBoard[y_ * tmpColumn + x_] = position;
00293
00294 cout << "(Enter to continue...)";
00295 string dummy;
00296 getline(cin, dummy);
00297 }