00001 //---------------------------------------------------------------------------- 00002 /** @file RingGodel.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "RingGodel.hpp" 00007 #include "Pattern.hpp" 00008 00009 using namespace benzene; 00010 00011 //---------------------------------------------------------------------------- 00012 00013 RingGodel::GlobalData::GlobalData() 00014 { 00015 // Compute scores adjusted by slice 00016 for (int s=0; s<Pattern::NUM_SLICES; ++s) 00017 { 00018 for (ColorIterator color; color; ++color) 00019 { 00020 color_slice_score[*color].push_back 00021 (AdjustScoreBySlice(Score(*color), s)); 00022 } 00023 mask_slice_score.push_back(AdjustScoreBySlice(SLICE_MASK, s)); 00024 } 00025 00026 // Compute the empty ring godel 00027 empty = 0; 00028 for (int s=0; s<Pattern::NUM_SLICES; ++s) 00029 empty |= color_slice_score[EMPTY][s]; 00030 } 00031 00032 //---------------------------------------------------------------------------- 00033 00034 RingGodel::RingGodel() 00035 : m_value(0) 00036 { 00037 } 00038 00039 RingGodel::RingGodel(int value) 00040 : m_value(value) 00041 { 00042 } 00043 00044 RingGodel::~RingGodel() 00045 { 00046 } 00047 00048 RingGodel::GlobalData& RingGodel::GetGlobalData() 00049 { 00050 static GlobalData s_data; 00051 return s_data; 00052 } 00053 00054 void RingGodel::AddColorToSlice(int slice, HexColor color) 00055 { 00056 m_value |= GetGlobalData().color_slice_score[color][slice]; 00057 } 00058 00059 void RingGodel::RemoveColorFromSlice(int slice, HexColor color) 00060 { 00061 m_value &= ~GetGlobalData().color_slice_score[color][slice]; 00062 } 00063 00064 void RingGodel::SetSliceToColor(int slice, HexColor color) 00065 { 00066 // zero the slice 00067 m_value &=~GetGlobalData().mask_slice_score[slice]; 00068 00069 // set slice to color 00070 m_value |= GetGlobalData().color_slice_score[color][slice]; 00071 } 00072 00073 void RingGodel::SetEmpty() 00074 { 00075 m_value = GetGlobalData().empty; 00076 } 00077 00078 int RingGodel::Index() const 00079 { 00080 return GetValidGodelData().godel_to_index[m_value]; 00081 } 00082 00083 //---------------------------------------------------------------------------- 00084 00085 PatternRingGodel::PatternRingGodel() 00086 : RingGodel(), 00087 m_mask(0) 00088 { 00089 } 00090 00091 PatternRingGodel::~PatternRingGodel() 00092 { 00093 } 00094 00095 void PatternRingGodel::SetEmpty() 00096 { 00097 RingGodel::SetEmpty(); 00098 m_mask = 0; 00099 } 00100 00101 void PatternRingGodel::AddSliceToMask(int slice) 00102 { 00103 m_mask |= AdjustScoreBySlice(SLICE_MASK, slice); 00104 } 00105 00106 bool PatternRingGodel::MatchesGodel(const RingGodel& other) const 00107 { 00108 // check that on our mask the colors in other's slices are 00109 // supersets of our slices. 00110 int other_ring = other.Value() & m_mask; 00111 return (other_ring & m_value) == (m_value & m_mask); 00112 } 00113 00114 //---------------------------------------------------------------------------- 00115 00116 RingGodel::ValidGodelData& RingGodel::GetValidGodelData() 00117 { 00118 static ValidGodelData s_valid_godels; 00119 return s_valid_godels; 00120 } 00121 00122 const std::vector<RingGodel>& RingGodel::ValidGodels() 00123 { 00124 return GetValidGodelData().valid_godel; 00125 } 00126 00127 /** Computes the set of valid godels. This skips godels where a slice 00128 is empty and either black or white. Also computes the godel to 00129 index vector for fast lookups -- using a map is apparently too 00130 slow. 00131 */ 00132 RingGodel::ValidGodelData::ValidGodelData() 00133 { 00134 //std::cout << "RingGodel::ComputeValid()" << std::endl; 00135 00136 int num_possible_godels = 1<<(BITS_PER_SLICE*Pattern::NUM_SLICES); 00137 00138 const GlobalData& data = GetGlobalData(); 00139 for (int g=0; g<num_possible_godels; ++g) 00140 { 00141 bool valid = true; 00142 for (int s=0; valid && s<Pattern::NUM_SLICES; ++s) 00143 { 00144 if ((g & data.mask_slice_score[s]) == 0) 00145 { 00146 valid = false; 00147 } 00148 else if (g & data.color_slice_score[EMPTY][s]) 00149 { 00150 if ((g & data.color_slice_score[BLACK][s]) || 00151 (g & data.color_slice_score[WHITE][s])) 00152 { 00153 valid = false; 00154 } 00155 } 00156 } 00157 00158 if (valid) 00159 { 00160 godel_to_index.push_back(valid_godel.size()); 00161 valid_godel.push_back(g); 00162 } 00163 else 00164 { 00165 godel_to_index.push_back(-1); 00166 } 00167 } 00168 00169 //std::cout << "Possible godels: " << num_possible_godels << std::endl; 00170 //std::cout << "Valid godels: " << valid_godel.size() << std::endl; 00171 } 00172 00173 //----------------------------------------------------------------------------