Rally X
ELEN3009 Project by Justin Wernick and David Schneider
source/logic/EnemyCar.cpp
Go to the documentation of this file.
00001 #include "EnemyCar.h"
00002 
00003 EnemyCar::EnemyCar(double x, double y)
00004     :Car(x,y,BitmapStore::ENEMY,Maze::UP),
00005     _state(CHASING),
00006     _targetX(x),
00007     _targetY(y)
00008 {
00009 }
00010 
00011 void EnemyCar::update(const Maze& maze, const list<PlayerCar>& players, const list<Rock>& rocks)
00012 {
00013     if (!players.empty()) checkFacing(maze, players.front().x(), players.front().y(), rocks);
00014 
00015     if (_state!=BLINDED)
00016     {
00017         move(maze);
00018     }
00019     else
00020     {
00021         _state = CHASING;
00022         _speed = _baseSpeed;
00023     }
00024 }
00025 
00026 void EnemyCar::checkFacing(const Maze& maze, double chasingX, double chasingY, const list<Rock>& rocks)
00027 {
00028     if (abs(_x - _targetX)>_speed || abs(_y - _targetY)>_speed) return;
00029 
00030     map<Maze::Direction, pair<double, double> > adjacentBlocks;
00031     pair<double, double> evaluatingTarget;
00032 
00033     adjacentBlocks[Maze::LEFT] = make_pair(MazeMath::round(_x-1), MazeMath::round(_y));
00034     adjacentBlocks[Maze::RIGHT] = make_pair(MazeMath::round(_x+1), MazeMath::round(_y));
00035     adjacentBlocks[Maze::UP] = make_pair(MazeMath::round(_x), MazeMath::round(_y-1));
00036     adjacentBlocks[Maze::DOWN] = make_pair(MazeMath::round(_x), MazeMath::round(_y+1));
00037 
00038     //remove adjacent blocks that would result in crashing into a rock or a wall
00039     for (map<Maze::Direction, pair<double, double> >::iterator iter=adjacentBlocks.begin(); iter!=adjacentBlocks.end(); )
00040     {
00041         if (rockAtLocation(iter->second.first, iter->second.second, rocks) || maze.getSolid(static_cast<int>(iter->second.first),static_cast<int>(iter->second.second)))
00042         {
00043             adjacentBlocks.erase(iter);
00044             iter = adjacentBlocks.begin();
00045         }
00046         else
00047         {
00048             ++iter;
00049         }
00050     }
00051 
00052     if (adjacentBlocks.empty())
00053     {
00054         _speed = 0;
00055         return;
00056     }
00057     else
00058     {
00059         _speed = _baseSpeed;
00060     }
00061 
00062     map<Maze::Direction, pair<double, double> >::iterator reverseFacing = adjacentBlocks.find(Maze::backwards(_facing));
00063     if ((reverseFacing != adjacentBlocks.end()) && (adjacentBlocks.size()>1))
00064     {
00065         adjacentBlocks.erase(reverseFacing);
00066     }
00067 
00068     map<Maze::Direction, pair<double, double> >::const_iterator closestAdjacent = adjacentBlocks.begin();
00069     double closestDistance = MazeMath::distance(closestAdjacent->second.first, closestAdjacent->second.second, chasingX, chasingY);
00070 
00071     for (map<Maze::Direction, pair<double, double> >::const_iterator iter = ++adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ++iter)
00072     {
00073         double newDistance = MazeMath::distance(iter->second.first, iter->second.second, chasingX, chasingY);
00074         if (newDistance < closestDistance)
00075         {
00076             closestDistance = newDistance;
00077             closestAdjacent = iter;
00078         }
00079     }
00080 
00081     _targetX = closestAdjacent->second.first;
00082     _targetY = closestAdjacent->second.second;
00083     _facing = closestAdjacent->first;
00084 }
00085 
00086 bool EnemyCar::rockAtLocation(double x, double y, const list<Rock>& rocks)
00087 {
00088     for (list<Rock>::const_iterator iter = rocks.begin(); iter!=rocks.end(); ++iter)
00089     {
00090         if (abs(x - iter->x())<1 && abs(y - iter->y())<1) return true;
00091     }
00092     return false;
00093 }
00094 
00095 void EnemyCar::crash()
00096 {
00097     _destroyed = true;
00098 }
00099 
00100 void EnemyCar::blind()
00101 {
00102     _state = BLINDED;
00103     _speed = 0;
00104 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator