-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleAI.hpp
95 lines (79 loc) · 2.36 KB
/
SimpleAI.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2016 Anton Erholt <aerholt@kth.se>
#include "Actor.hpp"
#include "Player.hpp"
#include "DungeonMap.hpp"
#ifndef LAB3_SIMPLEAI_HPP_
#define LAB3_SIMPLEAI_HPP_
namespace lab3 {
struct SimpleAI: virtual public Actor {
int wimpyTurns = 0;
SimpleAI(const Environment *position, DungeonMap *dm, const Race *race) : Actor(position, dm, race) { }
virtual void fight(Actor *target) {
if (this->isDead()) {
std::clog << this->id << " is dead, so it can't fight." << std::endl;
return;
}
try {
Player *player = getPlayer();
if (target == player) {
std::cout << *this->race << " attacks!" << std::endl;
player->fight(this);
return;
}
} catch (const std::invalid_argument &ex) {
// No player found
}
this->hurt(target->damage());
target->hurt(this->damage());
}
virtual void action() {
std::clog << *this << std::endl;
if (this->tickHasChangedSinceLastAction() && tickCount % this->speed == 0) {
Player *player = getPlayer();
if (current_state == AGGRESSIVE) {
if (current_health < max_health >> 2) {
current_state = WIMPY;
wimpyTurns = 0;
}
if (player->getPosition()->id == this->position->id) {
this->fight(player);
Actor::action();
return;
}
Actor::moveTowards(player->getPosition());
if (player->getPosition()->id == this->position->id) {
auto noise = this->race->noise();
std::cout << "A " << *this->race << " has arrived: " << noise <<
std::endl;
}
Actor::action();
return;
} else if (current_state == WIMPY) {
++wimpyTurns;
if (wimpyTurns >= 3) {
this->current_state = NEUTRAL;
wimpyTurns = 0;
}
if (closeToPlayer(player)) {
std::cout << "A " << *this->race << " is fleeing." << std::endl;
}
this->flee();
Actor::action();
return;
} else { // NEUTRAL
if (closeToPlayer(player)) {
this->current_state = AGGRESSIVE;
}
this->wait();
}
} else {
wait();
}
Actor::action();
}
bool closeToPlayer(const Player *player) const {
return game_map->bfs(position, player->getPosition(), game_map).size() <= 2;
}
};
} // namespace lab3
#endif // LAB3_SIMPLEAI_HPP_