00001 //---------------------------------------------------------------------------- 00002 /** @file 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef TWODISTANCE_HPP 00007 #define TWODISTANCE_HPP 00008 00009 #include "Hex.hpp" 00010 #include "HexEval.hpp" 00011 #include "HexBoard.hpp" 00012 00013 _BEGIN_BENZENE_NAMESPACE_ 00014 00015 //---------------------------------------------------------------------------- 00016 00017 /** TwoDistance Evaluation Function. 00018 00019 Computes the two distance from each cell to each of the four 00020 edges. The two distance is the second shortest distance between 00021 two cells (1 if they are adjacent, and infinity if fewer than two 00022 connecting paths exist). 00023 00024 This evaluation function requires that the VCs be precalculated 00025 for the given board state. This calcuation runs in O(n^2) time, 00026 where n is the number of cells on the board. 00027 00028 @bug if NeighbourType is FULL_VC then the distance returned is not 00029 accurate since one cell we have a vc with could affect another 00030 cell we have a vc with. 00031 */ 00032 class TwoDistance 00033 { 00034 public: 00035 00036 /** Two types of cell neighbourhoods: ADJACENT and FULL_VC. 00037 ADJACENT: standard adjacency, going through stones of like 00038 color. 00039 FULL_VC: two cells are adjacent if a FULL vc exists 00040 between them. */ 00041 typedef enum { ADJACENT, FULL_VC } NeighbourType; 00042 00043 /** Compute the TwoDistance on the given HexBoard (with up-to-date 00044 VCs) and NeighbourType. */ 00045 explicit TwoDistance(NeighbourType ntype = ADJACENT); 00046 00047 /** Destructor. */ 00048 virtual ~TwoDistance(); 00049 00050 /** Computes the evaluation. */ 00051 virtual void Evaluate(const HexBoard& brd); 00052 00053 /** Returns the computed score for BLACK, that is: 00054 00055 Score = SCALE*(B_m - W_m) + (B_mc - W_mc); 00056 00057 Where SCALE is an arbitrary scaling factor (hex setting 00058 "twod-scale-factor"), B_m and W_m are the minimum BLACK and WHITE 00059 cell scores, and B_mc and W_mc are equal to 00060 the number of times B_m and W_m appear on the board. 00061 00062 B_mc and W_mc are tie breaking values. The intuition here is 00063 that a position with many cells with minimum potential is 00064 better than a position with only a single cell with minimum 00065 potential. */ 00066 virtual HexEval Score() const; 00067 00068 /** Returns the sum of the BLACK and WHITE scores for this 00069 cell. */ 00070 virtual HexEval Score(HexPoint cell) const; 00071 00072 /** Returns the score for cell and color. This is the sum of 00073 the twodistances between both edges for cell. */ 00074 virtual HexEval Score(HexPoint cell, HexColor color) const; 00075 00076 private: 00077 00078 void ComputeScores(HexColor color, HexEval* out); 00079 00080 void FindBest(HexEval* po, HexPoint& who, int& count); 00081 00082 void ComputeScore(); 00083 00084 void ComputeDistanceToEdge(HexColor color, HexPoint edge1, HexEval* out); 00085 00086 bool IsAdjacent(HexColor color, HexPoint p1, HexPoint p2); 00087 00088 void SetAllToInfinity(HexEval* out); 00089 00090 const HexBoard* m_brd; 00091 NeighbourType m_ntype; 00092 00093 HexEval m_score; 00094 HexEval m_scores[BLACK_AND_WHITE][BITSETSIZE]; 00095 }; 00096 00097 inline HexEval TwoDistance::Score() const 00098 { 00099 return m_score; 00100 } 00101 00102 inline HexEval TwoDistance::Score(HexPoint cell, HexColor color) const 00103 { 00104 // @todo How to handle bad cells? 00105 return m_scores[color][cell]; 00106 } 00107 00108 inline HexEval TwoDistance::Score(HexPoint cell) const 00109 { 00110 // @todo How to handle bad cells? 00111 return m_scores[BLACK][cell] + m_scores[WHITE][cell]; 00112 } 00113 00114 //---------------------------------------------------------------------------- 00115 00116 namespace TwoDistUtil 00117 { 00118 /** Add two distances without mangling infinites. */ 00119 HexEval AddDistance(HexEval a, HexEval b); 00120 } 00121 00122 //---------------------------------------------------------------------------- 00123 00124 _END_BENZENE_NAMESPACE_ 00125 00126 #endif // TWODISTANCE_HPP