Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

Groups.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file Groups.cpp 
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 } // anonymous namespace
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 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3