TwoDistance.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "Hex.hpp"
00007 #include "BitsetIterator.hpp"
00008 #include "TwoDistance.hpp"
00009 #include "VCSet.hpp"
00010
00011 using namespace benzene;
00012
00013
00014
00015 TwoDistance::TwoDistance(NeighbourType ntype)
00016 : m_brd(0),
00017 m_ntype(ntype),
00018 m_score(0)
00019 {
00020 }
00021
00022 TwoDistance::~TwoDistance()
00023 {
00024 }
00025
00026
00027
00028 void TwoDistance::Evaluate(const HexBoard& brd)
00029 {
00030 m_brd = &brd;
00031 for (BWIterator it; it; ++it)
00032 ComputeScores(*it, m_scores[*it]);
00033 ComputeScore();
00034 }
00035
00036 void TwoDistance::ComputeScores(HexColor color, HexEval* out)
00037 {
00038 HexEval dist[2][BITSETSIZE];
00039 ComputeDistanceToEdge(color, HexPointUtil::colorEdge1(color), dist[0]);
00040 ComputeDistanceToEdge(color, HexPointUtil::colorEdge2(color), dist[1]);
00041
00042 for (BoardIterator it(m_brd->Const().Interior()); it; ++it)
00043 {
00044 if (m_brd->GetPosition().IsOccupied(*it))
00045 out[*it] = 0;
00046 else
00047 out[*it] = TwoDistUtil::AddDistance(dist[0][*it], dist[1][*it]);
00048
00049 }
00050 }
00051
00052 void TwoDistance::FindBest(HexEval* po, HexPoint& who, int& count)
00053 {
00054 HexEval best = EVAL_INFINITY;
00055 who = INVALID_POINT;
00056 count = 1;
00057
00058 for (BitsetIterator it(m_brd->GetPosition().GetEmpty()); it; ++it)
00059 {
00060 if (po[*it] < best)
00061 {
00062 best = po[*it];
00063 who = *it;
00064 count=1;
00065 }
00066 else if (po[*it] == best)
00067 count++;
00068 }
00069
00070 HexAssert(who != INVALID_POINT);
00071 HexAssert(best != EVAL_INFINITY);
00072 }
00073
00074 void TwoDistance::ComputeScore()
00075 {
00076 HexPoint black, white;
00077 int black_count, white_count;
00078 int SCALE_FACTOR = 1;
00079
00080 FindBest(m_scores[BLACK], black, black_count);
00081 FindBest(m_scores[WHITE], white, white_count);
00082
00083 m_score = (black - white)*SCALE_FACTOR + (black_count - white_count);
00084 }
00085
00086
00087
00088 bool TwoDistance::IsAdjacent(HexColor color, HexPoint p1, HexPoint p2)
00089 {
00090 VC vc;
00091 if (m_brd->Cons(color).SmallestVC(p1, p2, VC::FULL, vc)) {
00092 switch(m_ntype) {
00093 case ADJACENT: return vc.IsEmpty();
00094 case FULL_VC: return true;
00095 }
00096 }
00097 return false;
00098 }
00099
00100 void TwoDistance::ComputeDistanceToEdge(HexColor color,
00101 HexPoint edge,
00102 HexEval* out)
00103 {
00104 SetAllToInfinity(out);
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 std::priority_queue<std::pair<int, HexPoint> > q;
00116 std::set<HexPoint> done;
00117 std::set<HexPoint> once;
00118
00119
00120 for (BitsetIterator it(m_brd->GetPosition().GetEmpty()); it; ++it)
00121 {
00122 if (IsAdjacent(color, *it, edge))
00123 {
00124 out[*it] = 1;
00125 q.push(std::make_pair(-1, *it));
00126 done.insert(*it);
00127 }
00128 }
00129
00130 while (!q.empty()) {
00131 std::pair<int, HexPoint> pp = q.top();
00132 q.pop();
00133
00134 int dist = -pp.first;
00135 HexPoint p = pp.second;
00136
00137 for (BitsetIterator it(m_brd->GetPosition().GetEmpty()); it; ++it)
00138 {
00139 if (IsAdjacent(color, *it, p))
00140 {
00141
00142 if (done.count(*it))
00143 continue;
00144
00145
00146 else if (once.count(*it))
00147 {
00148 out[*it] = dist+1;
00149 q.push(std::make_pair(-(dist+1), *it));
00150 done.insert(*it);
00151 }
00152
00153 else
00154 once.insert(*it);
00155 }
00156 }
00157 }
00158 }
00159
00160 void TwoDistance::SetAllToInfinity(HexEval* out)
00161 {
00162 for (BoardIterator it(m_brd->Const().Interior()); it; ++it)
00163 out[*it] = EVAL_INFINITY;
00164 }
00165
00166
00167
00168 HexEval TwoDistUtil::AddDistance(HexEval a, HexEval b)
00169 {
00170 if (a == EVAL_INFINITY || b == EVAL_INFINITY)
00171 return EVAL_INFINITY;
00172 return a + b;
00173 }
00174
00175