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
96
97
98
99
100
101
102
103
104
|
#include "EnemyCar.h"
EnemyCar::EnemyCar(double x, double y)
:Car(x,y,BitmapStore::ENEMY,Maze::UP),
_state(CHASING),
_targetX(x),
_targetY(y)
{
}
void EnemyCar::update(const Maze& maze, const list<PlayerCar>& players, const list<Rock>& rocks)
{
if (!players.empty()) checkFacing(maze, players.front().x(), players.front().y(), rocks);
if (_state!=BLINDED)
{
move(maze);
}
else
{
_state = CHASING;
_speed = _baseSpeed;
}
}
void EnemyCar::checkFacing(const Maze& maze, double chasingX, double chasingY, const list<Rock>& rocks)
{
if (abs(_x - _targetX)>_speed || abs(_y - _targetY)>_speed) return;
map<Maze::Direction, pair<double, double> > adjacentBlocks;
pair<double, double> evaluatingTarget;
adjacentBlocks[Maze::LEFT] = make_pair(MazeMath::round(_x-1), MazeMath::round(_y));
adjacentBlocks[Maze::RIGHT] = make_pair(MazeMath::round(_x+1), MazeMath::round(_y));
adjacentBlocks[Maze::UP] = make_pair(MazeMath::round(_x), MazeMath::round(_y-1));
adjacentBlocks[Maze::DOWN] = make_pair(MazeMath::round(_x), MazeMath::round(_y+1));
//remove adjacent blocks that would result in crashing into a rock or a wall
for (map<Maze::Direction, pair<double, double> >::iterator iter=adjacentBlocks.begin(); iter!=adjacentBlocks.end(); )
{
if (rockAtLocation(iter->second.first, iter->second.second, rocks) || maze.getSolid(static_cast<int>(iter->second.first),static_cast<int>(iter->second.second)))
{
adjacentBlocks.erase(iter);
iter = adjacentBlocks.begin();
}
else
{
++iter;
}
}
if (adjacentBlocks.empty())
{
_speed = 0;
return;
}
else
{
_speed = _baseSpeed;
}
map<Maze::Direction, pair<double, double> >::iterator reverseFacing = adjacentBlocks.find(Maze::backwards(_facing));
if ((reverseFacing != adjacentBlocks.end()) && (adjacentBlocks.size()>1))
{
adjacentBlocks.erase(reverseFacing);
}
map<Maze::Direction, pair<double, double> >::const_iterator closestAdjacent = adjacentBlocks.begin();
double closestDistance = MazeMath::distance(closestAdjacent->second.first, closestAdjacent->second.second, chasingX, chasingY);
for (map<Maze::Direction, pair<double, double> >::const_iterator iter = ++adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ++iter)
{
double newDistance = MazeMath::distance(iter->second.first, iter->second.second, chasingX, chasingY);
if (newDistance < closestDistance)
{
closestDistance = newDistance;
closestAdjacent = iter;
}
}
_targetX = closestAdjacent->second.first;
_targetY = closestAdjacent->second.second;
_facing = closestAdjacent->first;
}
bool EnemyCar::rockAtLocation(double x, double y, const list<Rock>& rocks)
{
for (list<Rock>::const_iterator iter = rocks.begin(); iter!=rocks.end(); ++iter)
{
if (abs(x - iter->x())<1 && abs(y - iter->y())<1) return true;
}
return false;
}
void EnemyCar::crash()
{
_destroyed = true;
}
void EnemyCar::blind()
{
_state = BLINDED;
_speed = 0;
}
|