00001 //---------------------------------------------------------------------------- 00002 /** @file 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef RESISTANCE_HPP 00007 #define RESISTANCE_HPP 00008 00009 #include "Hex.hpp" 00010 #include "HexEval.hpp" 00011 #include "HexBoard.hpp" 00012 #include "Groups.hpp" 00013 00014 _BEGIN_BENZENE_NAMESPACE_ 00015 00016 //---------------------------------------------------------------------------- 00017 00018 /** Adjacency between each pair of cells. */ 00019 class AdjacencyGraph 00020 { 00021 public: 00022 00023 /** Creates an empty adjacency graph. */ 00024 AdjacencyGraph(); 00025 00026 ~AdjacencyGraph(); 00027 00028 std::vector<bool>& operator[](int n); 00029 00030 const std::vector<bool>& operator[](int n) const; 00031 00032 private: 00033 std::vector< std::vector<bool> > m_adj; 00034 }; 00035 00036 inline AdjacencyGraph::AdjacencyGraph() 00037 : m_adj(BITSETSIZE, std::vector<bool>(BITSETSIZE, false)) 00038 { } 00039 00040 inline AdjacencyGraph::~AdjacencyGraph() 00041 { } 00042 00043 inline std::vector<bool>& AdjacencyGraph::operator[](int n) 00044 { 00045 return m_adj[n]; 00046 } 00047 00048 inline const std::vector<bool>& AdjacencyGraph::operator[](int n) const 00049 { 00050 return m_adj[n]; 00051 } 00052 00053 //---------------------------------------------------------------------------- 00054 00055 /** Conductance between different types of groups. */ 00056 struct ConductanceValues 00057 { 00058 /** Conductance between a pair of groups with no connection. */ 00059 double no_connection; 00060 00061 /** Conductance between a pair of empty groups. */ 00062 double empty_to_empty; 00063 00064 /** Conductance between an occupied group and an empty group. */ 00065 double color_to_empty; 00066 00067 /** Conductance between two occupied groups. */ 00068 double color_to_color; 00069 00070 /** Initializes conductance defaults. */ 00071 ConductanceValues() 00072 : no_connection(0.0), 00073 empty_to_empty(1.0), 00074 color_to_empty(2.0), 00075 color_to_color(0.0) 00076 { } 00077 }; 00078 00079 //---------------------------------------------------------------------------- 00080 00081 /** Board evaluation based on circuit flow. */ 00082 class Resistance 00083 { 00084 public: 00085 00086 /** Constructor. */ 00087 explicit Resistance(); 00088 00089 /** Destructor. */ 00090 virtual ~Resistance(); 00091 00092 //---------------------------------------------------------------------- 00093 00094 bool SimulateAndOverEdge() const; 00095 00096 void SetSimulateAndOverEdge(bool enable); 00097 00098 /** Computes the evaluation for the given boardstate; uses 00099 ResistanceUtil::AddAdjacencies() to compute the 00100 conductance graphs for this board. */ 00101 void Evaluate(const HexBoard& brd); 00102 00103 /** Computes the evaluation for the given boardstate with the given 00104 AdjacencyGraphs for each color. 00105 00106 @note Graphs are not constant because if 00107 "resist-simulate-and-over-edge" is true, the graphs will be 00108 augmented. Augmentation is done here so that it is done only 00109 one spot, as opposed to having the augmentation done in all 00110 spots calling Evaluate(). 00111 */ 00112 void Evaluate(const HexBoard& brd, 00113 AdjacencyGraph graph[BLACK_AND_WHITE]); 00114 00115 00116 /** Evaluate on the given groups with the given adjacency 00117 graph. */ 00118 void Evaluate(const Groups& groups, AdjacencyGraph graph[BLACK_AND_WHITE]); 00119 00120 //---------------------------------------------------------------------- 00121 00122 /** Returns the log(resistance) for the given color. */ 00123 double Resist(HexColor color) const; 00124 00125 /** Returns the resistance of the board position from BLACK's 00126 view. That is, the log of the white resistance over the black 00127 resistance. */ 00128 HexEval Score() const; 00129 00130 /** Returns the score for cell and color. A cells score is equal 00131 to the current flowing through it. */ 00132 HexEval Score(HexPoint cell, HexColor color) const; 00133 00134 /** Returns the sum of the BLACK and WHITE scores for this 00135 cell. */ 00136 HexEval Score(HexPoint cell) const; 00137 00138 private: 00139 00140 /** Compute the evaluation for a single color. */ 00141 void ComputeScores(HexColor color, const Groups& brd, 00142 const AdjacencyGraph& graph, 00143 const ConductanceValues& values, 00144 HexEval* out); 00145 00146 /** Returns score as a ration of black's score over white's. */ 00147 void ComputeScore(); 00148 00149 HexEval m_score; 00150 HexEval m_resistance[BLACK_AND_WHITE]; 00151 HexEval m_scores[BLACK_AND_WHITE][BITSETSIZE]; 00152 00153 bool m_simulate_and_over_edge; 00154 }; 00155 00156 inline bool Resistance::SimulateAndOverEdge() const 00157 { 00158 return m_simulate_and_over_edge; 00159 } 00160 00161 inline void Resistance::SetSimulateAndOverEdge(bool enable) 00162 { 00163 m_simulate_and_over_edge = enable; 00164 } 00165 00166 inline HexEval Resistance::Score() const 00167 { 00168 return m_score; 00169 } 00170 00171 inline HexEval Resistance::Score(HexPoint cell) const 00172 { 00173 /** @todo How to handle bad cells? */ 00174 return m_scores[BLACK][cell] + m_scores[WHITE][cell]; 00175 } 00176 00177 inline HexEval Resistance::Score(HexPoint cell, HexColor color) const 00178 { 00179 /** @todo How to handle bad cells? */ 00180 return m_scores[color][cell]; 00181 } 00182 00183 //---------------------------------------------------------------------------- 00184 00185 /** Utilities to compute AdjacencyGraphs, etc. */ 00186 namespace ResistanceUtil 00187 { 00188 /** Must be called before SimulateAndOverEdge() can be called! */ 00189 void Initialize(); 00190 00191 /** Computes AdjacencyGraphs for this board state using a 00192 default ConductanceValues object. */ 00193 void AddAdjacencies(const HexBoard& brd, 00194 AdjacencyGraph graph[BLACK_AND_WHITE]); 00195 00196 /** Tries to simulate the vc set obtained by anding over the edge 00197 by giving connections to cells near the edge. */ 00198 void SimulateAndOverEdge(const HexBoard& brd, 00199 AdjacencyGraph graph[BLACK_AND_WHITE]); 00200 00201 } 00202 00203 //---------------------------------------------------------------------------- 00204 00205 _END_BENZENE_NAMESPACE_ 00206 00207 #endif // RESISTANCE_HPP