00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FinderAlg.h"
00010
00011 #include "V2.h"
00012 #include "Unit.h"
00013 #include "FinderPlace.h"
00014
00015
00016 FinderAlg::FinderAlg(int w, int h)
00017 : m_closed(w, h)
00018 {
00019 m_unit = NULL;
00020 }
00021
00022
00023
00024
00025
00026
00027
00028 Dir::eDir
00029 FinderAlg::findDir(const Unit *unit, const V2 &dest)
00030 {
00031 if (m_unit) {
00032 m_closed.reset();
00033 m_fifo.clear();
00034 }
00035 m_unit = unit;
00036 V2 uLoc = unit->getLoc();
00037 int w = unit->getW();
00038 int h = unit->getH();
00039 if (isInRect(uLoc, w, h, dest)) {
00040 return Dir::DIR_NO;
00041 }
00042
00043
00044 m_closed.markClosed(uLoc);
00045 m_fifo.push_back(FinderPlace(Dir::DIR_LEFT, uLoc.plus(V2(-1, 0))));
00046 m_fifo.push_back(FinderPlace(Dir::DIR_RIGHT, uLoc.plus(V2(+1, 0))));
00047 m_fifo.push_back(FinderPlace(Dir::DIR_UP, uLoc.plus(V2(0, -1))));
00048 m_fifo.push_back(FinderPlace(Dir::DIR_DOWN, uLoc.plus(V2(0, +1))));
00049
00050 while (!m_fifo.empty()) {
00051 FinderPlace place = m_fifo.front();
00052 m_fifo.pop_front();
00053 if (tryPlace(place)) {
00054 if (isInRect(place.getLoc(), w, h, dest)) {
00055 return place.getStartDir();
00056 }
00057
00058 pushNext(place, V2(-1, 0));
00059 pushNext(place, V2(+1, 0));
00060 pushNext(place, V2(0, -1));
00061 pushNext(place, V2(0, +1));
00062 }
00063 }
00064 return Dir::DIR_NO;
00065 }
00066
00067
00068
00069
00070
00071 void
00072 FinderAlg::pushNext(const FinderPlace &parent, const V2 &shift)
00073 {
00074 V2 loc = parent.getLoc().plus(shift);
00075 if (!m_closed.isClosed(loc)) {
00076 m_closed.markClosed(loc);
00077 m_fifo.push_back(FinderPlace(parent.getStartDir(), loc));
00078 }
00079 }
00080
00081
00082
00083
00084 bool
00085 FinderAlg::isInRect(const V2 &rectLoc, int w, int h, const V2 &dest) const
00086 {
00087 int rX = rectLoc.getX();
00088 int rY = rectLoc.getY();
00089 int destX = dest.getX();
00090 int destY = dest.getY();
00091 return (rX <= destX && destX < rX + w)
00092 && (rY <= destY && destY < rY + h);
00093 }
00094
00095 bool
00096 FinderAlg::tryPlace(const FinderPlace &place) const
00097 {
00098 return m_unit->isFreePlace(place.getLoc());
00099 }
00100