00001 //---------------------------------------------------------------------------- 00002 /** @file RingGodel.hpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef RING_GODEL_HPP 00007 #define RING_GODEL_HPP 00008 00009 #include "Hex.hpp" 00010 00011 _BEGIN_BENZENE_NAMESPACE_ 00012 00013 //---------------------------------------------------------------------------- 00014 00015 /** Base Ring godel class. */ 00016 class RingGodel 00017 { 00018 public: 00019 00020 /** Constructor. */ 00021 RingGodel(); 00022 00023 /** Initializes godel with given value: use only if you know what 00024 you are doing! */ 00025 RingGodel(int value); 00026 00027 /** Destructor. */ 00028 virtual ~RingGodel(); 00029 00030 //------------------------------------------------------------------------ 00031 00032 /** Adds BLACK, WHITE or EMPTY to slice in ring_godel. */ 00033 void AddColorToSlice(int slice, HexColor color); 00034 00035 /** Removes a color from a slice: color can be BLACK, WHITE, EMPTY. */ 00036 void RemoveColorFromSlice(int slice, HexColor color); 00037 00038 /** Sets the color of slice: color can be BLACK, WHITE, EMPTY. */ 00039 void SetSliceToColor(int slice, HexColor color); 00040 00041 /** Sets the godel to have all empty slices. */ 00042 virtual void SetEmpty(); 00043 00044 /** Returns the index of this ring_godel; use to hash into arrays. */ 00045 int Index() const; 00046 00047 /** Returns godel as an integer. */ 00048 int Value() const; 00049 00050 //------------------------------------------------------------------------ 00051 00052 /** Returns the valid ring godels. */ 00053 static const std::vector<RingGodel>& ValidGodels(); 00054 00055 protected: 00056 00057 /** The actual godel value. */ 00058 int m_value; 00059 00060 /** Number of bits to use for each slice in the ring godel. */ 00061 static const int BITS_PER_SLICE = 3; 00062 00063 /** Sould be 1<<(BITS_PER_SLICE) - 1. */ 00064 static const int SLICE_MASK = 7; 00065 00066 /** Score for color in a slice. */ 00067 static int Score(HexColor color); 00068 00069 /** Adjusts a score by the slice. */ 00070 static int AdjustScoreBySlice(int score, int slice); 00071 00072 private: 00073 00074 struct GlobalData 00075 { 00076 /** Value of empty ring godel. */ 00077 int empty; 00078 00079 /** Scores adjusted for each slice.*/ 00080 std::vector<int> color_slice_score[BLACK_WHITE_EMPTY]; 00081 00082 /** Mask for each slice. */ 00083 std::vector<int> mask_slice_score; 00084 00085 GlobalData(); 00086 }; 00087 00088 static GlobalData& GetGlobalData(); 00089 00090 struct ValidGodelData 00091 { 00092 std::vector<RingGodel> valid_godel; 00093 std::vector<int> godel_to_index; 00094 00095 ValidGodelData(); 00096 }; 00097 00098 static ValidGodelData& GetValidGodelData(); 00099 00100 }; 00101 00102 inline int RingGodel::Value() const 00103 { 00104 return m_value; 00105 } 00106 00107 inline int RingGodel::AdjustScoreBySlice(int score, int slice) 00108 { 00109 return (score << (slice*BITS_PER_SLICE)); 00110 } 00111 00112 inline int RingGodel::Score(HexColor color) 00113 { 00114 switch(color) 00115 { 00116 case EMPTY: return 1; 00117 case BLACK: return 2; 00118 case WHITE: return 4; 00119 } 00120 HexAssert(false); 00121 return 0; 00122 } 00123 00124 //---------------------------------------------------------------------------- 00125 00126 /** Standard RingGodel with an added mask to use when checking if two 00127 RingGodels match. */ 00128 class PatternRingGodel : public RingGodel 00129 { 00130 public: 00131 00132 /** Constructs pattern ring godel with empty mask. */ 00133 PatternRingGodel(); 00134 00135 /** Destructor. */ 00136 virtual ~PatternRingGodel(); 00137 00138 /** Sets the godel and mask to empty. */ 00139 virtual void SetEmpty(); 00140 00141 /** Adds the given slice to the mask. */ 00142 void AddSliceToMask(int slice); 00143 00144 /** Returns true if we match godel on our mask. For a match to 00145 occur, each corresponding slice in godel must be a superset of 00146 the slice in this godel. If godel has BW, then B or W or BW 00147 will match it, but if we have BW, only BW in godel will 00148 match. */ 00149 bool MatchesGodel(const RingGodel& godel) const; 00150 00151 private: 00152 int m_mask; 00153 }; 00154 00155 //---------------------------------------------------------------------------- 00156 00157 _END_BENZENE_NAMESPACE_ 00158 00159 #endif // RING_GODEL_HPP