Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

VCSet.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file VCSet.cpp
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     // Create a list for each valid pair; also create lists
00024     // for pairs (x,x) for ease of use later on. These lists
00025     // between the same point will also be empty.
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 


6 Jan 2011 Doxygen 1.6.3