00001
00002
00003
00004
00005
00006 #include "Hex.hpp"
00007 #include "ChangeLog.hpp"
00008 #include "VCSet.hpp"
00009 #include "VC.hpp"
00010 #include "VCList.hpp"
00011
00012 using namespace benzene;
00013
00014
00015
00016 VCSet::VCSet(const ConstBoard& brd, HexColor color)
00017 : m_brd(&brd),
00018 m_color(color)
00019 {
00020 int softlimit_full = 25;
00021 int softlimit_semi = 50;
00022
00023
00024
00025
00026 for (BoardIterator y(m_brd->EdgesAndInterior()); y; ++y) {
00027 for (BoardIterator x(m_brd->EdgesAndInterior()); x; ++x) {
00028 m_vc[VC::FULL][*x][*y] =
00029 m_vc[VC::FULL][*y][*x] =
00030 new VCList(*y, *x, softlimit_full);
00031
00032 m_vc[VC::SEMI][*x][*y] =
00033 m_vc[VC::SEMI][*y][*x] =
00034 new VCList(*y, *x, softlimit_semi);
00035
00036 if (*x == *y) break;
00037 }
00038 }
00039 }
00040
00041 VCSet::VCSet(const VCSet& other)
00042 : m_brd(other.m_brd),
00043 m_color(other.m_color)
00044 {
00045 AllocateAndCopyLists(other);
00046 }
00047
00048 void VCSet::operator=(const VCSet& other)
00049 {
00050 m_brd = other.m_brd;
00051 m_color = other.m_color;
00052 FreeLists();
00053 AllocateAndCopyLists(other);
00054 }
00055
00056 void VCSet::AllocateAndCopyLists(const VCSet& other)
00057 {
00058 for (BoardIterator y = m_brd->EdgesAndInterior(); y; ++y) {
00059 for (BoardIterator x = m_brd->EdgesAndInterior(); x; ++x) {
00060 m_vc[VC::FULL][*x][*y] =
00061 m_vc[VC::FULL][*y][*x] =
00062 new VCList(*other.m_vc[VC::FULL][*y][*x]);
00063
00064 m_vc[VC::SEMI][*x][*y] =
00065 m_vc[VC::SEMI][*y][*x] =
00066 new VCList(*other.m_vc[VC::SEMI][*y][*x]);
00067
00068 if (*x == *y) break;
00069 }
00070 }
00071 }
00072
00073 VCSet::~VCSet()
00074 {
00075 FreeLists();
00076 }
00077
00078 void VCSet::FreeLists()
00079 {
00080 for (BoardIterator y = m_brd->EdgesAndInterior(); y; ++y) {
00081 for (BoardIterator x = m_brd->EdgesAndInterior(); x; ++x) {
00082 for (int i=0; i<VC::NUM_TYPES; ++i)
00083 delete m_vc[i][*x][*y];
00084 if (*x == *y) break;
00085 }
00086 }
00087 }
00088
00089
00090
00091 bool VCSet::Exists(HexPoint x, HexPoint y, VC::Type type) const
00092 {
00093 return !m_vc[type][x][y]->empty();
00094 }
00095
00096 bool VCSet::SmallestVC(HexPoint x, HexPoint y,
00097 VC::Type type, VC& out) const
00098 {
00099 if (!Exists(x, y, type))
00100 return false;
00101 out = *m_vc[type][x][y]->begin();
00102 return true;
00103 }
00104
00105 void VCSet::VCs(HexPoint x, HexPoint y, VC::Type type,
00106 std::vector<VC>& out) const
00107 {
00108 out.clear();
00109 const VCList* who = m_vc[type][x][y];
00110 for (VCList::const_iterator it(who->begin()); it != who->end(); ++it)
00111 out.push_back(*it);
00112 }
00113
00114
00115
00116 void VCSet::SetSoftLimit(VC::Type type, int limit)
00117 {
00118 for (BoardIterator y(m_brd->EdgesAndInterior()); y; ++y) {
00119 for (BoardIterator x(m_brd->EdgesAndInterior()); *x != *y; ++x)
00120 m_vc[type][*x][*y]->setSoftLimit(limit);
00121 }
00122 }
00123
00124 void VCSet::Clear()
00125 {
00126 for (BoardIterator y(m_brd->EdgesAndInterior()); y; ++y) {
00127 for (BoardIterator x(m_brd->EdgesAndInterior()); *x != *y; ++x) {
00128 for (int i=0; i<VC::NUM_TYPES; ++i) {
00129 m_vc[i][*x][*y]->clear();
00130 }
00131 }
00132 }
00133 }
00134
00135 void VCSet::Revert(ChangeLog<VC>& log)
00136 {
00137 while (!log.empty()) {
00138 int action = log.topAction();
00139 if (action == ChangeLog<VC>::MARKER) {
00140 log.pop();
00141 break;
00142 }
00143
00144 VC vc(log.topData());
00145 log.pop();
00146
00147 VCList* list = m_vc[vc.type()][vc.x()][vc.y()];
00148 if (action == ChangeLog<VC>::ADD) {
00149 #ifdef NDEBUG
00150 list->remove(vc, 0);
00151 #else
00152 HexAssert(list->remove(vc, 0));
00153 #endif
00154 } else if (action == ChangeLog<VC>::REMOVE) {
00155 list->simple_add(vc);
00156 } else if (action == ChangeLog<VC>::PROCESSED) {
00157 VCList::iterator it = list->find(vc);
00158 HexAssert(it != list->end());
00159 HexAssert(it->processed());
00160 it->setProcessed(false);
00161 }
00162 }
00163 }
00164
00165
00166
00167 bool VCSet::operator==(const VCSet& other) const
00168 {
00169 for (BoardIterator x(m_brd->EdgesAndInterior()); x; ++x)
00170 {
00171 for (BoardIterator y(m_brd->EdgesAndInterior()); *y != *x; ++y)
00172 {
00173 const VCList& full1 = *m_vc[VC::FULL][*x][*y];
00174 const VCList& full2 = *other.m_vc[VC::FULL][*x][*y];
00175 if (full1 != full2) return false;
00176
00177 const VCList& semi1 = *m_vc[VC::SEMI][*x][*y];
00178 const VCList& semi2 = *other.m_vc[VC::SEMI][*x][*y];
00179 if (semi1 != semi2) return false;
00180 }
00181 }
00182 return true;
00183 }
00184
00185 bool VCSet::operator!=(const VCSet& other) const
00186 {
00187 return !operator==(other);
00188 }
00189
00190
00191
00192 bitset_t VCSetUtil::ConnectedTo(const VCSet& con, const Groups& groups,
00193 HexPoint x, VC::Type type)
00194 {
00195 bitset_t ret;
00196 const StoneBoard& brd = groups.Board();
00197 HexColorSet not_other = HexColorSetUtil::ColorOrEmpty(con.Color());
00198 for (BoardIterator y(brd.Stones(not_other)); y; ++y)
00199 if (con.Exists(groups.CaptainOf(x), groups.CaptainOf(*y), type))
00200 ret.set(*y);
00201 return ret;
00202 }
00203
00204 bool VCSetUtil::EqualOnGroups(const VCSet& c1, const VCSet& c2,
00205 const Groups& groups)
00206 {
00207 if (c1.Color() != c2.Color())
00208 return false;
00209 if (c1.Board() != c2.Board())
00210 return false;
00211
00212 HexColorSet not_other = HexColorSetUtil::ColorOrEmpty(c1.Color());
00213 for (GroupIterator x(groups, not_other); x; ++x)
00214 {
00215 HexPoint xc = x->Captain();
00216 for (GroupIterator y(groups, not_other); &*y != &*x; ++y)
00217 {
00218 HexPoint yc = y->Captain();
00219 if (c1.GetList(VC::FULL, xc, yc) != c2.GetList(VC::FULL, xc, yc))
00220 {
00221 std::cout << "FULL " << xc << ", " << yc << "\n";
00222 std::cout << c1.GetList(VC::FULL, xc, yc).dump() << '\n';
00223 std::cout << "==============\n";
00224 std::cout << c2.GetList(VC::FULL, xc, yc).dump() << '\n';
00225 return false;
00226 }
00227 if (c1.GetList(VC::SEMI, xc, yc) != c2.GetList(VC::SEMI, xc, yc))
00228 {
00229 std::cout << "SEMI " << xc << ", " << yc << "\n";
00230 std::cout << c1.GetList(VC::SEMI, xc, yc).dump() << '\n';
00231 std::cout << "==============\n";
00232 std::cout << c2.GetList(VC::SEMI, xc, yc).dump() << '\n';
00233 return false;
00234 }
00235 }
00236 }
00237 return true;
00238 }
00239
00240
00241
00242 VCSetStatistics::VCSetStatistics()
00243 : m_fulls(0),
00244 m_semis(0)
00245 {
00246 }
00247
00248 std::string VCSetStatistics::Write() const
00249 {
00250 std::ostringstream os;
00251 os << "[\n";
00252 os << "fulls=" << m_fulls << '\n';
00253 os << "semis=" << m_semis << '\n';
00254 os << "fullCounts="; m_fullCounts.Write(os); os << '\n';
00255 os << "semiCounts="; m_semiCounts.Write(os); os << '\n';
00256 os << "fullCountsCell="; m_fullCountsCell.Write(os); os << '\n';
00257 os << "semiCountsCell="; m_semiCountsCell.Write(os); os << '\n';
00258 os << "fullConnectedTo="; m_fullConnectedTo.Write(os); os << '\n';
00259 os << "semiConnectedTo="; m_semiConnectedTo.Write(os); os << '\n';
00260 os << "fullHisto=\n"; m_fullHisto.Write(os); os << '\n';
00261 os << "semiHisto=\n"; m_semiHisto.Write(os); os << '\n';
00262 os << "]\n";
00263 os << '\n';
00264 return os.str();
00265 }
00266
00267 VCSetStatistics VCSetUtil::ComputeStatistics(const VCSet& con,
00268 const Groups& groups,
00269 std::size_t maxConnections,
00270 int numBins)
00271
00272 {
00273 VCSetStatistics stats;
00274 stats.m_fullHisto.Init(0, maxConnections, numBins);
00275 stats.m_semiHisto.Init(0, maxConnections, numBins);
00276 std::vector<size_t> cellFullCounts(BITSETSIZE, 0);
00277 std::vector<size_t> cellSemiCounts(BITSETSIZE, 0);
00278
00279 HexColorSet not_other = HexColorSetUtil::ColorOrEmpty(con.Color());
00280 for (GroupIterator x(groups, not_other); x; ++x)
00281 {
00282 for (GroupIterator y(groups, not_other); &*y != &*x; ++y)
00283 {
00284 std::size_t full_size = con.GetList(VC::FULL, x->Captain(),
00285 y->Captain()).size();
00286 std::size_t semi_size = con.GetList(VC::SEMI, x->Captain(),
00287 y->Captain()).size();
00288 stats.m_fulls += full_size;
00289 stats.m_semis += semi_size;
00290 stats.m_fullCounts.Add(full_size);
00291 stats.m_semiCounts.Add(semi_size);
00292 stats.m_fullHisto.Add(full_size);
00293 stats.m_semiHisto.Add(semi_size);
00294 cellFullCounts[x->Captain()] += full_size;
00295 cellSemiCounts[x->Captain()] += semi_size;
00296 cellFullCounts[y->Captain()] += full_size;
00297 cellSemiCounts[y->Captain()] += semi_size;
00298 }
00299 std::size_t full_connected
00300 = ConnectedTo(con, groups, x->Captain(), VC::FULL).count();
00301 std::size_t semi_connected
00302 = ConnectedTo(con, groups, x->Captain(), VC::SEMI).count();
00303 stats.m_fullConnectedTo.Add(full_connected);
00304 stats.m_semiConnectedTo.Add(semi_connected);
00305 }
00306 for (GroupIterator x(groups, not_other); x; ++x)
00307 {
00308 stats.m_fullCountsCell.Add(cellFullCounts[x->Captain()]);
00309 stats.m_semiCountsCell.Add(cellSemiCounts[x->Captain()]);
00310 }
00311 return stats;
00312 }
00313
00314
00315