InferiorCells.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "BitsetIterator.hpp"
00015 #include "InferiorCells.hpp"
00016
00017 using namespace benzene;
00018
00019
00020
00021 InferiorCells::InferiorCells()
00022 : m_dominated_computed(false)
00023 {
00024 }
00025
00026
00027
00028 bitset_t InferiorCells::Dominated() const
00029 {
00030 if (!m_dominated_computed) {
00031
00032
00033 Digraph<HexPoint> g(m_dom_graph);
00034 for (BitsetIterator p(Vulnerable()); p; ++p) {
00035 g.RemoveVertex(*p);
00036 }
00037 for (BitsetIterator p(Reversible()); p; ++p) {
00038 g.RemoveVertex(*p);
00039 }
00040
00041 bitset_t captains = InferiorCellsUtil::FindDominationCaptains(g);
00042 bitset_t vertices = BitsetUtil::SetToBitset(g.Vertices());
00043 m_dominated = vertices - captains;
00044 m_dominated_computed = true;
00045
00046
00047 HexAssert((m_dominated & Vulnerable()).none());
00048 HexAssert((m_dominated & Reversible()).none());
00049 }
00050 return m_dominated;
00051 }
00052
00053
00054 bitset_t InferiorCells::All() const
00055 {
00056 return Dead()
00057 | Vulnerable() | Reversible() | Dominated()
00058 | Captured(BLACK) | Captured(WHITE)
00059 | PermInf(BLACK) | PermInf(WHITE)
00060 | MutualFillin(BLACK) | MutualFillin(WHITE);
00061 }
00062
00063 bitset_t InferiorCells::Fillin(HexColor color) const
00064 {
00065 bitset_t ret = Captured(color) | PermInf(color) | MutualFillin(color);
00066 if (color == DEAD_COLOR) ret |= Dead();
00067 return ret;
00068 }
00069
00070
00071
00072 void InferiorCells::AddDead(HexPoint dead)
00073 {
00074 bitset_t b;
00075 b.set(dead);
00076 AddDead(b);
00077 }
00078
00079 void InferiorCells::AddDead(const bitset_t& dead)
00080 {
00081 m_dead |= dead;
00082
00083 RemoveVulnerable(dead);
00084 RemoveReversible(dead);
00085 RemoveDominated(dead);
00086
00087 AssertPairwiseDisjoint();
00088 }
00089
00090 void InferiorCells::AddCaptured(HexColor color, HexPoint captured)
00091 {
00092 bitset_t b;
00093 b.set(captured);
00094 AddCaptured(color, b);
00095 }
00096
00097 void InferiorCells::AddCaptured(HexColor color, const bitset_t& captured)
00098 {
00099 m_captured[color] |= captured;
00100
00101 RemoveVulnerable(captured);
00102 RemoveReversible(captured);
00103 RemoveDominated(captured);
00104
00105 AssertPairwiseDisjoint();
00106 }
00107
00108 void InferiorCells::AddPermInf(HexColor color,
00109 const bitset_t& cells,
00110 const bitset_t& carrier)
00111 {
00112 m_perm_inf[color] |= cells;
00113 m_perm_inf_carrier[color] |= carrier;
00114
00115 RemoveVulnerable(cells);
00116 RemoveReversible(cells);
00117 RemoveDominated(cells);
00118
00119 AssertPairwiseDisjoint();
00120 }
00121
00122 void InferiorCells::AddPermInf(HexColor color, HexPoint cell,
00123 const bitset_t& carrier)
00124 {
00125 bitset_t b;
00126 b.set(cell);
00127 AddPermInf(color, b, carrier);
00128 }
00129
00130 void InferiorCells::AddMutualFillin(HexColor color,
00131 const bitset_t& cells,
00132 const bitset_t& carrier)
00133 {
00134 m_mutual_fillin[color] |= cells;
00135 m_mutual_fillin_carrier[color] |= carrier;
00136
00137 RemoveVulnerable(cells);
00138 RemoveReversible(cells);
00139 RemoveDominated(cells);
00140
00141 AssertPairwiseDisjoint();
00142 }
00143
00144 void InferiorCells::AddMutualFillin(HexColor color, HexPoint cell,
00145 const bitset_t& carrier)
00146 {
00147 bitset_t b;
00148 b.set(cell);
00149 AddMutualFillin(color, b, carrier);
00150 }
00151
00152 void InferiorCells::AddDominated(HexPoint cell, const std::set<HexPoint>& dom)
00153 {
00154 m_dom_graph.AddEdges(cell, dom);
00155 m_dominated_computed = false;
00156
00157
00158 }
00159
00160 void InferiorCells::AddDominated(HexPoint cell, HexPoint dominator)
00161 {
00162 m_dom_graph.AddEdge(cell, dominator);
00163 m_dominated_computed = false;
00164
00165
00166 }
00167
00168 void InferiorCells::AddVulnerable(HexPoint cell,
00169 const std::set<HexPoint>& killers)
00170 {
00171 m_vulnerable.set(cell);
00172
00173
00174 std::set<HexPoint>::iterator it = killers.begin();
00175 for (; it != killers.end(); ++it) {
00176 m_killers[cell].insert(VulnerableKiller(*it));
00177 }
00178
00179
00180 RemoveReversible(cell);
00181 m_dominated_computed = false;
00182
00183 AssertPairwiseDisjoint();
00184 }
00185
00186 void InferiorCells::AddVulnerable(HexPoint cell,
00187 const std::set<VulnerableKiller>& killers)
00188 {
00189 m_vulnerable.set(cell);
00190 m_killers[cell].insert(killers.begin(), killers.end());
00191 RemoveReversible(cell);
00192 m_dominated_computed = false;
00193
00194 AssertPairwiseDisjoint();
00195 }
00196
00197 void InferiorCells::AddVulnerable(HexPoint cell, HexPoint killer)
00198 {
00199 m_vulnerable.set(cell);
00200 m_killers[cell].insert(VulnerableKiller(killer));
00201 RemoveReversible(cell);
00202 m_dominated_computed = false;
00203
00204 AssertPairwiseDisjoint();
00205 }
00206
00207 void InferiorCells::AddVulnerable(HexPoint cell, const VulnerableKiller& killer)
00208 {
00209 m_vulnerable.set(cell);
00210 m_killers[cell].insert(killer);
00211 RemoveReversible(cell);
00212 m_dominated_computed = false;
00213
00214 AssertPairwiseDisjoint();
00215 }
00216
00217 void InferiorCells::AddReversible(HexPoint cell, bitset_t carrier,
00218 HexPoint reverser)
00219 {
00220
00221 bitset_t reversibleCandidates = carrier;
00222 reversibleCandidates.set(cell);
00223
00224
00225 if (m_allReversibleCarriers.test(reverser)) return;
00226 if ((m_allReversers & reversibleCandidates).any()) return;
00227 if (reversibleCandidates.test(reverser)) return;
00228
00229
00230 bool noAdditions = true;
00231 for (BitsetIterator it(reversibleCandidates); it; ++it)
00232 {
00233 if (m_vulnerable.test(*it)) continue;
00234 noAdditions = false;
00235 m_reversible.set(*it);
00236 m_reversers[*it].insert(reverser);
00237 }
00238 if (noAdditions) return;
00239 m_allReversibleCarriers |= reversibleCandidates;
00240 m_allReversers.set(reverser);
00241
00242 m_dominated_computed = false;
00243 AssertPairwiseDisjoint();
00244 }
00245
00246 void InferiorCells::AddReversible(HexPoint cell, bitset_t carrier,
00247 const std::set<HexPoint>& reversers)
00248 {
00249
00250 bitset_t reversibleCandidates = carrier;
00251 reversibleCandidates.set(cell);
00252
00253 bitset_t reverserCandidates;
00254 for (std::set<HexPoint>::iterator it = reversers.begin();
00255 it != reversers.end(); ++it)
00256 {
00257 reverserCandidates.set(*it);
00258 }
00259
00260
00261 if ((m_allReversibleCarriers & reverserCandidates).any()) return;
00262 if ((m_allReversers & reversibleCandidates).any()) return;
00263 if ((reverserCandidates & reversibleCandidates).any()) return;
00264
00265
00266 bool noAdditions = true;
00267 for (BitsetIterator it(reversibleCandidates); it; ++it)
00268 {
00269 if (m_vulnerable.test(*it)) continue;
00270 noAdditions = false;
00271 m_reversible.set(*it);
00272 m_reversers[*it].insert(reversers.begin(), reversers.end());
00273 }
00274 if (noAdditions) return;
00275 m_allReversibleCarriers |= reversibleCandidates;
00276 m_allReversers |= reverserCandidates;
00277
00278 m_dominated_computed = false;
00279 AssertPairwiseDisjoint();
00280 }
00281
00282
00283
00284 void InferiorCells::AddDominatedFrom(const InferiorCells& other)
00285 {
00286 bitset_t vertices=BitsetUtil::SetToBitset(other.m_dom_graph.Vertices());
00287 for (BitsetIterator p(vertices); p; ++p) {
00288 AddDominated(*p, other.m_dom_graph.OutSet(*p));
00289 }
00290
00291 }
00292
00293 void InferiorCells::AddVulnerableFrom(const InferiorCells& other)
00294 {
00295 for (BitsetIterator p(other.Vulnerable()); p; ++p) {
00296 AddVulnerable(*p, other.m_killers[*p]);
00297 }
00298 AssertPairwiseDisjoint();
00299 }
00300
00301 void InferiorCells::AddReversibleFrom(const InferiorCells& other)
00302 {
00303 for (BitsetIterator p(other.Reversible()); p; ++p) {
00304 AddReversible(*p, EMPTY_BITSET, other.m_reversers[*p]);
00305 }
00306 m_allReversibleCarriers |= other.AllReversibleCarriers();
00307 m_allReversers |= other.AllReversers();
00308 AssertPairwiseDisjoint();
00309 }
00310
00311 void InferiorCells::AddPermInfFrom(HexColor color, const InferiorCells& other)
00312 {
00313 m_perm_inf[color] |= other.m_perm_inf[color];
00314 m_perm_inf_carrier[color] |= other.m_perm_inf_carrier[color];
00315 AssertPairwiseDisjoint();
00316 }
00317
00318 void InferiorCells::AddMutualFillinFrom(HexColor color,
00319 const InferiorCells& other)
00320 {
00321 m_mutual_fillin[color] |= other.m_mutual_fillin[color];
00322 m_mutual_fillin_carrier[color] |= other.m_mutual_fillin_carrier[color];
00323 AssertPairwiseDisjoint();
00324 }
00325
00326
00327
00328 void InferiorCells::Clear()
00329 {
00330 ClearDead();
00331 ClearVulnerable();
00332 ClearReversible();
00333 for (BWIterator c; c; ++c) {
00334 ClearCaptured(*c);
00335 ClearPermInf(*c);
00336 ClearMutualFillin(*c);
00337 }
00338 ClearDominated();
00339 }
00340
00341 void InferiorCells::ClearDead()
00342 {
00343 m_dead.reset();
00344 }
00345
00346 void InferiorCells::ClearCaptured(HexColor color)
00347 {
00348 m_captured[color].reset();
00349 }
00350
00351 void InferiorCells::ClearPermInf(HexColor color)
00352 {
00353 m_perm_inf[color].reset();
00354 m_perm_inf_carrier[color].reset();
00355 }
00356
00357 void InferiorCells::ClearMutualFillin(HexColor color)
00358 {
00359 m_mutual_fillin[color].reset();
00360 m_mutual_fillin_carrier[color].reset();
00361 }
00362
00363 void InferiorCells::ClearVulnerable()
00364 {
00365 RemoveVulnerable(m_vulnerable);
00366 m_dominated_computed = false;
00367 }
00368
00369 void InferiorCells::ClearReversible()
00370 {
00371 RemoveReversible(m_reversible);
00372 m_allReversibleCarriers.reset();
00373 m_allReversers.reset();
00374 m_dominated_computed = false;
00375 }
00376
00377 void InferiorCells::ClearDominated()
00378 {
00379 m_dom_graph.Clear();
00380 m_dominated_computed = false;
00381 }
00382
00383
00384
00385 void InferiorCells::RemoveDominated(const bitset_t& dominated)
00386 {
00387 bitset_t vertices = BitsetUtil::SetToBitset(m_dom_graph.Vertices());
00388 for (BitsetIterator p(vertices & dominated); p; ++p) {
00389 m_dom_graph.RemoveVertex(*p);
00390 }
00391 m_dominated_computed = false;
00392 }
00393
00394 void InferiorCells::RemoveVulnerable(const bitset_t& vulnerable)
00395 {
00396 for (BitsetIterator p(vulnerable & m_vulnerable); p; ++p) {
00397 m_killers[*p].clear();
00398 }
00399 m_vulnerable = m_vulnerable - vulnerable;
00400 m_dominated_computed = false;
00401 }
00402
00403 void InferiorCells::RemoveReversible(const bitset_t& reversible)
00404 {
00405 for (BitsetIterator p(reversible & m_reversible); p; ++p) {
00406 m_reversers[*p].clear();
00407 }
00408 m_reversible = m_reversible - reversible;
00409 m_dominated_computed = false;
00410 }
00411
00412 void InferiorCells::RemoveReversible(HexPoint reversible)
00413 {
00414 if (m_reversible.test(reversible)) {
00415 m_reversers[reversible].clear();
00416 m_reversible.reset(reversible);
00417 m_dominated_computed = false;
00418 }
00419 }
00420
00421
00422
00423 void InferiorCells::AssertPairwiseDisjoint() const
00424 {
00425 HexAssert((m_dead & m_vulnerable).none());
00426 HexAssert((m_dead & m_reversible).none());
00427 HexAssert((m_reversible & m_vulnerable).none());
00428 HexAssert((m_allReversibleCarriers & m_allReversers).none());
00429 HexAssert((m_reversible & m_allReversibleCarriers) == m_reversible);
00430 HexAssert(!m_dominated_computed || (m_dead & m_dominated).none());
00431 HexAssert(!m_dominated_computed || (m_vulnerable & m_dominated).none());
00432 HexAssert(!m_dominated_computed || (m_reversible & m_dominated).none());
00433
00434 for (BWIterator c; c; ++c) {
00435 HexAssert((m_captured[*c] & m_dead).none());
00436 HexAssert(!m_dominated_computed
00437 || (m_captured[*c] & m_dominated).none());
00438 HexAssert((m_captured[*c] & m_vulnerable).none());
00439 HexAssert((m_captured[*c] & m_reversible).none());
00440 HexAssert((m_captured[*c] & m_captured[!*c]).none());
00441
00442 HexAssert((m_perm_inf[*c] & m_dead).none());
00443 HexAssert(!m_dominated_computed
00444 || (m_perm_inf[*c] & m_dominated).none());
00445 HexAssert((m_perm_inf[*c] & m_vulnerable).none());
00446 HexAssert((m_perm_inf[*c] & m_reversible).none());
00447
00448 HexAssert((m_captured[*c] & m_perm_inf[*c]).none());
00449 HexAssert((m_captured[*c] & m_perm_inf[!*c]).none());
00450
00451 HexAssert((m_mutual_fillin[*c] & m_dead).none());
00452 HexAssert(!m_dominated_computed
00453 || (m_mutual_fillin[*c] & m_dominated).none());
00454 HexAssert((m_mutual_fillin[*c] & m_vulnerable).none());
00455 HexAssert((m_mutual_fillin[*c] & m_reversible).none());
00456
00457 HexAssert((m_mutual_fillin[*c] & m_captured[*c]).none());
00458 HexAssert((m_mutual_fillin[*c] & m_captured[!*c]).none());
00459 HexAssert((m_mutual_fillin[*c] & m_perm_inf[*c]).none());
00460 HexAssert((m_mutual_fillin[*c] & m_perm_inf[!*c]).none());
00461 }
00462 }
00463
00464
00465
00466 bitset_t InferiorCells::FindPresimplicialPairs() const
00467 {
00468 bitset_t fillin;
00469 std::set<VulnerableKiller>::iterator k1, k2;
00470
00471
00472
00473
00474
00475 for (BitsetIterator x(m_vulnerable); x; ++x) {
00476 if (fillin.test(*x)) continue;
00477
00478 for (k1 = m_killers[*x].begin(); k1 != m_killers[*x].end(); ++k1) {
00479 HexPoint y = k1->killer();
00480 if (fillin.test(y)) continue;
00481 if ((k1->carrier() & fillin).any()) continue;
00482
00483 bool success = false;
00484 for (k2 = m_killers[y].begin(); k2 != m_killers[y].end(); ++k2) {
00485 HexPoint z = k2->killer();
00486 if (z != *x) continue;
00487 if (fillin.test(z)) continue;
00488 if ((k2->carrier() & fillin).any()) continue;
00489
00490
00491
00492 if ((k1->carrier() & k2->carrier()).none()) {
00493 bitset_t both = k1->carrier() | k2->carrier();
00494 if ((both & fillin).none()) {
00495 fillin |= both;
00496 fillin.set(y);
00497 fillin.set(*x);
00498 success = true;
00499 break;
00500 }
00501 }
00502 }
00503
00504
00505
00506 if (success) break;
00507 }
00508 }
00509
00510 return fillin;
00511 }
00512
00513 bitset_t InferiorCells::DeductionSet(HexColor color) const
00514 {
00515 bitset_t deductionSet;
00516 deductionSet = Captured(color);
00517 deductionSet |= PermInf(color);
00518 deductionSet |= PermInfCarrier(color);
00519 deductionSet |= MutualFillin(color);
00520 deductionSet |= MutualFillinCarrier(color);
00521 return deductionSet;
00522 }
00523
00524
00525
00526 std::string InferiorCells::GuiOutput() const
00527 {
00528 std::size_t c = 0;
00529 std::ostringstream out;
00530 for (int i = 0; i < FIRST_INVALID; ++i)
00531 {
00532 HexPoint p = static_cast<HexPoint>(i);
00533 std::ostringstream os;
00534
00535 os << " " << p << " ";
00536 if (Dead().test(i))
00537 {
00538 os << "fd";
00539 os << ((DEAD_COLOR == BLACK) ? "b" : "w");
00540 }
00541 else if (Captured(BLACK).test(i))
00542 os << "fcb";
00543 else if (Captured(WHITE).test(i))
00544 os << "fcw";
00545 else if (PermInf(BLACK).test(i))
00546 os << "fpb";
00547 else if (PermInf(WHITE).test(i))
00548 os << "fpw";
00549 else if (MutualFillin(BLACK).test(i))
00550 os << "fub";
00551 else if (MutualFillin(WHITE).test(i))
00552 os << "fuw";
00553 else if (Vulnerable().test(i))
00554 {
00555 os << "iv[";
00556 bool first=true;
00557 std::set<VulnerableKiller>::const_iterator i;
00558 for (i = m_killers[p].begin(); i != m_killers[p].end(); ++i)
00559 {
00560 if (!first) os << "-";
00561 os << i->killer();
00562 first = false;
00563 }
00564 os << "]";
00565 }
00566 else if (Reversible().test(i))
00567 {
00568 os << "ir[";
00569 bool first=true;
00570 std::set<HexPoint>::const_iterator i;
00571 for (i = m_reversers[p].begin(); i != m_reversers[p].end(); ++i)
00572 {
00573 if (!first) os << "-";
00574 os << *i;
00575 first = false;
00576 }
00577 os << "]";
00578 }
00579 else if (Dominated().test(i))
00580 {
00581 os << "id[";
00582 bool first=true;
00583 std::set<HexPoint>::iterator i;
00584 for (i=m_dom_graph.out_begin(p); i!=m_dom_graph.out_end(p); ++i)
00585 {
00586
00587 if (Vulnerable().test(*i))
00588 continue;
00589 if (!first) os << "-";
00590 os << *i;
00591 first = false;
00592 }
00593 os << "]";
00594 }
00595 else
00596 continue;
00597
00598 std::string str = os.str();
00599 std::size_t t = str.size();
00600 if (c + t > 40)
00601 {
00602 out << '\n';
00603 c = t;
00604 }
00605 else
00606 c += t;
00607
00608 out << str;
00609 }
00610 return out.str();
00611 }
00612
00613
00614
00615 bitset_t
00616 InferiorCellsUtil::FindDominationCaptains(const Digraph<HexPoint>& graph)
00617 {
00618 bitset_t captains;
00619
00620
00621 std::vector<HexPointSet> comp;
00622 graph.FindStronglyConnectedComponents(comp);
00623
00624
00625 for (std::size_t i=0; i < comp.size(); ++i) {
00626
00627 std::set<HexPoint> out;
00628 graph.OutSet(comp[i], out);
00629
00630
00631
00632 std::set<HexPoint>::iterator it;
00633 for (it = comp[i].begin(); it != comp[i].end(); ++it)
00634 out.erase(*it);
00635
00636
00637 if (out.empty()) {
00638 captains.set(*comp[i].begin());
00639 }
00640 }
00641
00642 return captains;
00643 }
00644
00645