00001 //---------------------------------------------------------------------------- 00002 /** @file HexSgUtil.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgNode.h" 00008 #include "SgProp.h" 00009 #include "SgGameWriter.h" 00010 00011 #include "Hex.hpp" 00012 #include "HexProp.hpp" 00013 #include "HexSgUtil.hpp" 00014 #include "BitsetIterator.hpp" 00015 00016 using namespace benzene; 00017 00018 //---------------------------------------------------------------------------- 00019 00020 SgPoint HexSgUtil::HexPointToSgPoint(HexPoint p, int height) 00021 { 00022 int c, r; 00023 HexPointUtil::pointToCoords(p, c, r); 00024 return SgPointUtil::Pt(1+c, height - r); 00025 } 00026 00027 00028 HexPoint HexSgUtil::SgPointToHexPoint(SgPoint p, int height) 00029 { 00030 int c = SgPointUtil::Col(p); 00031 int r = SgPointUtil::Row(p); 00032 return HexPointUtil::coordsToPoint(c-1, height - r); 00033 } 00034 00035 00036 SgBlackWhite HexSgUtil::HexColorToSgColor(HexColor color) 00037 { 00038 HexAssert(HexColorUtil::isBlackWhite(color)); 00039 if (color == BLACK) return SG_BLACK; 00040 return SG_WHITE; 00041 } 00042 00043 00044 HexColor HexSgUtil::SgColorToHexColor(SgBlackWhite player) 00045 { 00046 HexAssert(player == SG_BLACK || player == SG_WHITE); 00047 if (player == SG_BLACK) return BLACK; 00048 return WHITE; 00049 } 00050 00051 SgVector<SgPoint> HexSgUtil::BitsetToSgVector(const bitset_t& b, int height) 00052 { 00053 SgVector<SgPoint> ret; 00054 std::vector<HexPoint> hp; 00055 for (BitsetIterator i(b); i; ++i) 00056 ret.PushBack(HexSgUtil::HexPointToSgPoint(*i, height)); 00057 return ret; 00058 } 00059 00060 void HexSgUtil::AddMoveToNode(SgNode* node, HexColor color, 00061 HexPoint cell, int height) 00062 { 00063 SgPoint sgcell = HexSgUtil::HexPointToSgPoint(cell, height); 00064 SgBlackWhite sgcolor = HexSgUtil::HexColorToSgColor(color); 00065 HexProp::AddMoveProp(node, sgcell, sgcolor); 00066 } 00067 00068 bool HexSgUtil::NodeHasSetupInfo(SgNode* node) 00069 { 00070 if (node->HasProp(SG_PROP_ADD_BLACK)) return true; 00071 if (node->HasProp(SG_PROP_ADD_WHITE)) return true; 00072 if (node->HasProp(SG_PROP_ADD_EMPTY)) return true; 00073 if (node->HasProp(SG_PROP_PLAYER)) return true; 00074 return false; 00075 } 00076 00077 void HexSgUtil::SetPositionInNode(SgNode* node, const StoneBoard& brd, 00078 HexColor color) 00079 { 00080 int height = brd.Height(); 00081 SgVector<SgPoint> blist = HexSgUtil::BitsetToSgVector(brd.GetBlack() 00082 & brd.Const().GetCells(), height); 00083 SgVector<SgPoint> wlist = HexSgUtil::BitsetToSgVector(brd.GetWhite() 00084 & brd.Const().GetCells(), height); 00085 SgVector<SgPoint> elist = HexSgUtil::BitsetToSgVector(brd.GetEmpty() 00086 & brd.Const().GetCells(), height); 00087 00088 SgPropPlayer* pprop = new SgPropPlayer(SG_PROP_PLAYER); 00089 SgPropAddStone* bprop = new SgPropAddStone(SG_PROP_ADD_BLACK); 00090 SgPropAddStone* wprop = new SgPropAddStone(SG_PROP_ADD_WHITE); 00091 SgPropAddStone* eprop = new SgPropAddStone(SG_PROP_ADD_EMPTY); 00092 00093 pprop->SetValue(HexSgUtil::HexColorToSgColor(color)); 00094 bprop->SetValue(blist); 00095 wprop->SetValue(wlist); 00096 eprop->SetValue(elist); 00097 00098 node->Add(pprop); 00099 node->Add(bprop); 00100 node->Add(wprop); 00101 node->Add(eprop); 00102 } 00103 00104 void HexSgUtil::GetSetupPosition(const SgNode* node, int height, 00105 std::vector<HexPoint>& black, 00106 std::vector<HexPoint>& white, 00107 std::vector<HexPoint>& empty) 00108 { 00109 black.clear(); 00110 white.clear(); 00111 empty.clear(); 00112 if (node->HasProp(SG_PROP_ADD_BLACK)) 00113 { 00114 SgPropPointList* prop = (SgPropPointList*)node->Get(SG_PROP_ADD_BLACK); 00115 const SgVector<SgPoint>& vec = prop->Value(); 00116 for (int i = 0; i < vec.Length(); ++i) 00117 black.push_back(HexSgUtil::SgPointToHexPoint(vec[i], height)); 00118 } 00119 if (node->HasProp(SG_PROP_ADD_WHITE)) 00120 { 00121 SgPropPointList* prop = (SgPropPointList*)node->Get(SG_PROP_ADD_WHITE); 00122 const SgVector<SgPoint>& vec = prop->Value(); 00123 for (int i = 0; i < vec.Length(); ++i) 00124 white.push_back(HexSgUtil::SgPointToHexPoint(vec[i], height)); 00125 } 00126 if (node->HasProp(SG_PROP_ADD_EMPTY)) 00127 { 00128 SgPropPointList* prop = (SgPropPointList*)node->Get(SG_PROP_ADD_EMPTY); 00129 const SgVector<SgPoint>& vec = prop->Value(); 00130 for (int i = 0; i < vec.Length(); ++i) 00131 empty.push_back(HexSgUtil::SgPointToHexPoint(vec[i], height)); 00132 } 00133 } 00134 00135 void HexSgUtil::SetPositionInBoard(const SgNode* node, StoneBoard& brd) 00136 { 00137 std::vector<HexPoint> black, white, empty; 00138 GetSetupPosition(node, brd.Height(), black, white, empty); 00139 brd.StartNewGame(); 00140 for (std::size_t i = 0; i < black.size(); ++i) 00141 brd.PlayMove(BLACK, black[i]); 00142 for (std::size_t i = 0; i < white.size(); ++i) 00143 brd.PlayMove(WHITE, white[i]); 00144 } 00145 00146 00147 bool HexSgUtil::WriteSgf(SgNode* tree, const char* filename, int boardsize) 00148 { 00149 // Set the boardsize property 00150 tree->Add(new SgPropInt(SG_PROP_SIZE, boardsize)); 00151 00152 // @note 11 is the sgf gamenumber for Hex 00153 std::ofstream f(filename); 00154 if (f) 00155 { 00156 SgGameWriter sgwriter(f); 00157 sgwriter.WriteGame(*tree, true, 0, 11, boardsize); 00158 f.close(); 00159 } 00160 else 00161 { 00162 LogWarning() << "Could not open '" << filename << "' " 00163 << "for writing!\n"; 00164 return false; 00165 } 00166 return true; 00167 } 00168 00169 //----------------------------------------------------------------------------