//Zombie i is given orders based on an A* search to the nearest human // where nearest is defined by the zombieDistance function //Smart zombies will not break down walls, and will do nothing if // no path is available to the nearest human. void AI::smartZombie(int index) { const int FORGET = 5; //forget the last x of the generated path. const int REMEMBER = 5; //go no more than x turns without recalulating path int forgotten = 0; Zombie* me = &zombies[index]; Human* target = NULL; int bestDis = 9999999; int nextDis; int x, y, humanIndex, wallIndex; std::deque<int> path; std::cout << "smart" << std::endl; for (int i = 0; i < humans.size(); i++) { nextDis = zombieDistance(me->x(), me->y(), humans[i].x(), humans[i].y(), me->facing()); if (nextDis < bestDis) { bestDis = nextDis; target = &humans[i]; } } if (target != NULL) { path = findZombiePath(me->x(), me->y(), target->x(), target->y(), me->facing()); std::cout << "(" << me->x() << "," << me->y() << "," << target->x() << "," << target->y() << "," << me->facing() << ") = "; for (int k = 0; k < path.size(); k++) { std::cout << path[k] << " "; } if (path.size() == 0) { std::cout << "No action"; } std::cout << std::endl; if (path.size() > 1) { path.pop_front(); switch (path.front()) { case 0: x = nextX(me->x(), me->y(), me->facing()); y = nextY(me->x(), me->y(), me->facing()); humanIndex = getHuman(x, y); wallIndex = getWall(x, y); if (humanIndex > -1) me->attack(humans[humanIndex]); else if (wallIndex > -1) me->attack(walls[wallIndex]); else me->move(); break; case 1: me->turn(-1); break; case 2: me->turn(1); break; } /* while (path.size() > 0 && forgotten < FORGET) { path.pop_back(); forgotten += 1; } while (path.size() > REMEMBER) { path.pop_back(); } if (path.size() > 0) orders[me->id()] = path; */ } } std::cout << "end" << std::endl; }
bool operator !=(const Zombie& left, const Zombie& right) { return (left.getPosition() != right.getPosition()) && (left.getVelocity() != right.getVelocity()); }