Groups.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "BitsetIterator.hpp"
00007 #include "Groups.hpp"
00008
00009 using namespace benzene;
00010
00011
00012
00013 namespace {
00014
00015
00016
00017 void Flow(const StoneBoard& brd, HexPoint start, HexColor color,
00018 bitset_t& members, bitset_t& nbs)
00019 {
00020 HexAssert(!members.test(start));
00021 HexAssert(brd.GetColor(start) == color);
00022 members.set(start);
00023 for (BoardIterator p(brd.Const().Nbs(start)); p; ++p)
00024 {
00025 if (members.test(*p))
00026 continue;
00027 if (color != EMPTY && brd.GetColor(*p) == color)
00028 Flow(brd, *p, color, members, nbs);
00029 else
00030 nbs.set(*p);
00031 }
00032 HexAssert((members & nbs).none());
00033 }
00034
00035
00036
00037 }
00038
00039
00040
00041 void GroupBuilder::Build(const StoneBoard& brd, Groups& groups)
00042 {
00043 bitset_t visited;
00044 groups.m_brd = const_cast<StoneBoard*>(&brd);
00045 groups.m_groups.clear();
00046 groups.m_group_index.resize(FIRST_INVALID);
00047 for (BoardIterator p(brd.Const().EdgesAndInterior()); p; ++p)
00048 {
00049 if (visited.test(*p))
00050 continue;
00051 bitset_t nbs, members;
00052 HexColor color = brd.GetColor(*p);
00053 Flow(brd, *p, color, members, nbs);
00054 HexAssert((visited & members).none());
00055 visited |= members;
00056 for (BitsetIterator m(members); m; ++m)
00057 groups.m_group_index[*m] = groups.m_groups.size();
00058 groups.m_groups.push_back(Group(&groups, color, *p, members, nbs));
00059 }
00060 for (std::size_t i = 0; i < groups.m_groups.size(); ++i)
00061 {
00062 Group& g = groups.m_groups[i];
00063 g.m_nbs = groups.CaptainizeBitset(g.m_nbs);
00064 for (BitsetIterator p(g.m_nbs); p; ++p)
00065 g.m_nbs_index.push_back(groups.m_group_index[*p]);
00066 }
00067 }
00068
00069
00070
00071 std::size_t Groups::NumGroups(HexColorSet colorset) const
00072 {
00073 std::size_t num = 0;
00074 for (GroupIterator g(*this, colorset); g; ++g)
00075 ++num;
00076 return num;
00077 }
00078
00079 std::size_t Groups::GroupIndex(HexPoint point, HexColorSet colorset) const
00080 {
00081 std::size_t count = 0;
00082 for (GroupIterator g(*this, colorset); g; ++g)
00083 {
00084 if (g->IsMember(point))
00085 break;
00086 ++count;
00087 }
00088 return count;
00089 }
00090
00091 bool Groups::IsGameOver() const
00092 {
00093 return (GetWinner() != EMPTY);
00094 }
00095
00096 HexColor Groups::GetWinner() const
00097 {
00098 for (BWIterator c; c; ++c)
00099 if (m_group_index[HexPointUtil::colorEdge1(*c)] ==
00100 m_group_index[HexPointUtil::colorEdge2(*c)])
00101 return *c;
00102 return EMPTY;
00103 }
00104
00105 bitset_t Groups::CaptainizeBitset(bitset_t locations) const
00106 {
00107 HexAssert(m_brd->Const().IsLocation(locations));
00108 bitset_t captains;
00109 for (BitsetIterator i(locations); i; ++i)
00110 captains.set(CaptainOf(*i));
00111 return captains;
00112 }
00113
00114
00115
00116 const bitset_t& Group::Nbs(HexColorSet colorset) const
00117 {
00118 if (!m_colorsets_computed)
00119 {
00120 ComputeColorsetNbs();
00121 m_colorsets_computed = true;
00122 }
00123 return m_nbs_colorset[colorset];
00124 }
00125
00126 void Group::ComputeColorsetNbs() const
00127 {
00128 for (int cs = 0; cs < NUM_COLOR_SETS; ++cs)
00129 {
00130 HexColorSet colorset = static_cast<HexColorSet>(cs);
00131 for (std::size_t i = 0; i < m_nbs_index.size(); ++i)
00132 {
00133 const Group* nb = &m_groups->m_groups[m_nbs_index[i]];
00134 if (HexColorSetUtil::InSet(nb->Color(), colorset))
00135 m_nbs_colorset[colorset].set(nb->Captain());
00136 }
00137 }
00138 }
00139
00140