#include #include #include "antsim.hh" #include "ant.hh" #include "map.hh" Ant::Ant() : x(0), y(0), dir(0), nestScent(1), foodScent(1), hasFood(false), trailLen(0), tmpTrailLen(0) { } Ant::~Ant() { } void Ant::load(int x_, int y_) { x = x_; y = y_; dir = random() % 8; } void Ant::move(Map* map, int exploreRate) { int prob[8]; if (hasFood) { prob[UL] = map->getNestScent(x-1, y-1); prob[U] = map->getNestScent(x, y-1); prob[UR] = map->getNestScent(x+1, y-1); prob[L] = map->getNestScent(x-1, y); prob[R] = map->getNestScent(x+1, y); prob[DL] = map->getNestScent(x-1, y+1); prob[D] = map->getNestScent(x, y+1); prob[DR] = map->getNestScent(x+1, y+1); } else { prob[UL] = map->getFoodScent(x-1, y-1); prob[U] = map->getFoodScent(x, y-1); prob[UR] = map->getFoodScent(x+1, y-1); prob[L] = map->getFoodScent(x-1, y); prob[R] = map->getFoodScent(x+1, y); prob[DL] = map->getFoodScent(x-1, y+1); prob[D] = map->getFoodScent(x, y+1); prob[DR] = map->getFoodScent(x+1, y+1); } /* switch(dir) { case UL: prob[DL] >>= 1; prob[D] >>= 2; prob[DR] >>= 4; prob[R] >>= 2; prob[UR] >>= 1; break; case U: prob[L] >>= 1; prob[DL] >>= 2; prob[D] >>= 4; prob[DR] >>= 2; prob[R] >>= 1; break; case UR: prob[UL] >>= 1; prob[L] >>= 2; prob[DL] >>= 4; prob[D] >>= 2; prob[DR] >>= 1; break; case L: prob[D] >>= 1; prob[DR] >>= 2; prob[R] >>= 4; prob[UR] >>= 2; prob[U] >>= 1; break; case R: prob[U] >>= 1; prob[UL] >>= 2; prob[L] >>= 4; prob[DL] >>= 2; prob[D] >>= 1; break; case DL: prob[DR] >>= 1; prob[R] >>= 2; prob[UR] >>= 4; prob[U] >>= 2; prob[UL] >>= 1; break; case D: prob[R] >>= 1; prob[UR] >>= 2; prob[U] >>= 4; prob[UL] >>= 2; prob[L] >>= 1; break; case DR: prob[UR] >>= 1; prob[U] >>= 2; prob[UL] >>= 4; prob[L] >>= 2; prob[DL] >>= 1; break; } */ if (map->getWall(x-1, y-1)) prob[UL] = 0; if (map->getWall(x, y-1)) prob[U] = 0; if (map->getWall(x+1, y-1)) prob[UR] = 0; if (map->getWall(x-1, y)) prob[L] = 0; if (map->getWall(x+1, y)) prob[R] = 0; if (map->getWall(x-1, y+1)) prob[DL] = 0; if (map->getWall(x, y+1)) prob[D] = 0; if (map->getWall(x+1, y+1)) prob[DR] = 0; int i; int total = 0; for (i = 0; i < 8; i++) { total += prob[i]; } if (total > 0) { int i; int ary[8]; int aryCount = 0; for (i = 0; i < 8; i++) { if (prob[i] > 0) ary[aryCount++] = i; } int randomMove = ary[random() % aryCount]; i = 0; int r = (random() % total); while (prob[i] <= r) { r -= prob[i++]; } int weightedMove = i; aryCount = 0; int largest = 0; for (i = 0; i < 8; i++) { if (largest < prob[i]) largest = prob[i]; } for (i = 0; i < 8; i++) { if (prob[i] == largest) ary[aryCount++] = i; } int gradientMove = ary[random() % aryCount]; if (hasFood) // dir = gradientMove; dir = random() % exploreRate ? gradientMove : weightedMove; else dir = random() % exploreRate ? weightedMove : randomMove; } if (nestScent > 1) { if (dir == U || dir == D || dir == L || dir == R) nestScent -= 8; else nestScent -= 11; if (nestScent < 1) nestScent = 1; } if (foodScent > 1) { if (dir == U || dir == D || dir == L || dir == R) foodScent -= 8; else foodScent -= 11; if (foodScent < 1) foodScent = 1; } map->setAnts(x, y, map->getAnts(x, y)-1); switch (dir) { case UL: x -= 1; y -= 1; break; case U: y -= 1; break; case UR: x += 1; y -= 1; break; case L: x -= 1; break; case R: x += 1; break; case DL: x -= 1; y += 1; break; case D: y += 1; break; case DR: x += 1; y += 1; break; } if (hasFood) tmpTrailLen++; if (map->getNest(x, y)) { if (hasFood) { hasFood = false; trailLen = tmpTrailLen; } nestScent = 16384; foodScent = 1; } if (map->getFood(x, y) > 0) { if (!hasFood) { hasFood = true; map->setFood(x, y, map->getFood(x, y)-1); } tmpTrailLen = 0; nestScent = 1; foodScent = 16384; } if (nestScent > map->getNestScent(x, y)) map->setNestScent(x, y, nestScent); if (foodScent > map->getFoodScent(x, y)) map->setFoodScent(x, y, foodScent); map->setAnts(x, y, map->getAnts(x, y)+1); } int Ant::getTrailLen() { return trailLen; }