void AI::obedientZombie(int index, std::deque<int> myOrders) { int x, y, humanIndex, wallIndex; Zombie* me = &zombies[index]; switch (myOrders.front()) { case 0: x = nextX(me->x(), me->y(), me->facing()); y = nextY(me->x(), me->y(), me->facing()); humanIndex = getHuman(x, y); if (humanIndex > -1) { myOrders.clear(); me->attack(humans[humanIndex]); } else me->move(); break; case 1: me->turn(-1); break; case 2: me->turn(1); break; } if (myOrders.size() > 0) myOrders.pop_front(); if (myOrders.size() > 0) orders[me->id()] = myOrders; else orders.erase(me->id()); }
const ConnectFour::Player& ConnectFour::Player::getOpposite() const { switch(m_type) { case PLAYER_TYPE_AI: return getHuman(); case PLAYER_TYPE_HUMAN: return getAI(); case PLAYER_TYPE_UNKNOWN: default: return getInvalid(); } }
//Attacks nearby zombies, then builds walls around himself. //Does not move. void AI::builderHuman(int i) { int attacks = 1; int tries = 0; int dir; int x, y; int zombieIndex, crateIndex, humanIndex, wallIndex; int moves = humans[i].moves(); while ((moves > 0 || attacks > 0) && tries < 12) { dir = rand() % 6; x = nextX(humans[i].x(), humans[i].y(), dir); y = nextY(humans[i].x(), humans[i].y(), dir); zombieIndex = getZombie(x, y); crateIndex = getCrate(x, y); humanIndex = getHuman(x, y); wallIndex = getHuman(x, y); if (crateIndex > -1) { humans[i].grab(crates[crateIndex]); } if (zombieIndex == -1 && humanIndex == -1 && moves > 0) { humans[i].build(x, y); moves -= 1; } else if (zombieIndex > -1 && attacks > 0) { humans[i].attack(zombies[zombieIndex]); attacks -= 1; } tries += 1; } }
void AI::callAirstrikes() { int calls = int(getAirstrikesReady()); int x, y; for (int i = 0; i < calls; i++) { do { x = (rand()%15) - 7; y = (rand()%15) - 7; } while (getHuman(x, y) > -1); Human::callAmmoDrop(x, y); } }
//Zombie i is given orders based soley on its smell and the object // directly in front of them. void AI::blindZombie(int i) { int x, y, wallIndex, humanIndex, zombieIndex; bool allowEat = (int(getZombieCap()) == zombies.size()); if (zombies[i].smell() == 0) { zombies[i].turn((rand()%2) * 2 - 1); } else { x = nextX(zombies[i].x(), zombies[i].y(), zombies[i].facing()); y = nextY(zombies[i].x(), zombies[i].y(), zombies[i].facing()); wallIndex = getWall(x, y); humanIndex = getHuman(x, y); zombieIndex = getZombie(x, y); if (humanIndex > -1) { zombies[i].attack(humans[humanIndex]); } else if (wallIndex > -1) { zombies[i].attack(walls[wallIndex]); } else if (zombieIndex > -1 && allowEat) { zombies[i].eat(zombies[zombieIndex]); eaten += 1; } else { zombies[i].move(); } } }
//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; }