00001 //---------------------------------------------------------------------------- 00002 /** @file GoBoardUpdater.cpp */ 00003 //---------------------------------------------------------------------------- 00004 00005 #include "SgSystem.h" 00006 #include "GoBoardUpdater.h" 00007 00008 #include "GoBoard.h" 00009 #include "GoSetupUtil.h" 00010 #include "SgNode.h" 00011 #include "SgUtil.h" 00012 00013 using namespace std; 00014 00015 //---------------------------------------------------------------------------- 00016 00017 namespace { 00018 00019 SgEmptyBlackWhite GetPlayer(const SgNode* node) 00020 { 00021 if (! node->HasProp(SG_PROP_PLAYER)) 00022 return SG_EMPTY; 00023 SgPropPlayer* prop = 00024 dynamic_cast<SgPropPlayer*>(node->Get(SG_PROP_PLAYER)); 00025 return prop->Value(); 00026 } 00027 00028 } // namespace 00029 00030 //---------------------------------------------------------------------------- 00031 00032 void GoBoardUpdater::Update(const SgNode* node, GoBoard& bd) 00033 { 00034 SG_ASSERT(node != 0); 00035 m_nodes.clear(); 00036 while (node != 0) 00037 { 00038 m_nodes.push_back(node); 00039 node = node->Father(); 00040 } 00041 const SgNode* root = m_nodes[m_nodes.size() - 1]; 00042 int size = GO_DEFAULT_SIZE; 00043 SgPropInt* boardSize = static_cast<SgPropInt*>(root->Get(SG_PROP_SIZE)); 00044 if (boardSize) 00045 { 00046 size = boardSize->Value(); 00047 SG_ASSERT(SgUtil::InRange(size, SG_MIN_SIZE, SG_MAX_SIZE)); 00048 } 00049 bd.Init(size); 00050 for (vector<const SgNode*>::reverse_iterator it = m_nodes.rbegin(); 00051 it != m_nodes.rend(); ++it) 00052 { 00053 const SgNode* node = *it; 00054 SgEmptyBlackWhite player = GetPlayer(node); 00055 if (node->HasProp(SG_PROP_ADD_EMPTY) 00056 || node->HasProp(SG_PROP_ADD_BLACK) 00057 || node->HasProp(SG_PROP_ADD_WHITE)) 00058 { 00059 // Compute the new initial setup position to re-initialize the 00060 // board with 00061 GoSetup setup = GoSetupUtil::CurrentPosSetup(bd); 00062 if (player != SG_EMPTY) 00063 setup.m_player = player; 00064 if (node->HasProp(SG_PROP_ADD_BLACK)) 00065 { 00066 SgPropAddStone* prop = 00067 dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_BLACK)); 00068 const SgVector<SgPoint>& addBlack = prop->Value(); 00069 for (SgVectorIterator<SgPoint> it2(addBlack); it2; ++it2) 00070 { 00071 SgPoint p = *it2; 00072 setup.m_stones[SG_WHITE].Exclude(p); 00073 if (! setup.m_stones[SG_BLACK].Contains(p)) 00074 setup.AddBlack(p); 00075 } 00076 } 00077 if (node->HasProp(SG_PROP_ADD_WHITE)) 00078 { 00079 SgPropAddStone* prop = 00080 dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_WHITE)); 00081 const SgVector<SgPoint>& addWhite = prop->Value(); 00082 for (SgVectorIterator<SgPoint> it2(addWhite); it2; ++it2) 00083 { 00084 SgPoint p = *it2; 00085 setup.m_stones[SG_BLACK].Exclude(p); 00086 if (! setup.m_stones[SG_WHITE].Contains(p)) 00087 setup.AddWhite(p); 00088 } 00089 } 00090 if (node->HasProp(SG_PROP_ADD_EMPTY)) 00091 { 00092 SgPropAddStone* prop = 00093 dynamic_cast<SgPropAddStone*>(node->Get(SG_PROP_ADD_EMPTY)); 00094 const SgVector<SgPoint>& addEmpty = prop->Value(); 00095 for (SgVectorIterator<SgPoint> it2(addEmpty); it2; ++it2) 00096 { 00097 SgPoint p = *it2; 00098 setup.m_stones[SG_BLACK].Exclude(p); 00099 setup.m_stones[SG_WHITE].Exclude(p); 00100 } 00101 } 00102 bd.Init(bd.Size(), setup); 00103 } 00104 else if (player != SG_EMPTY) 00105 bd.SetToPlay(player); 00106 if (node->HasProp(SG_PROP_MOVE)) 00107 { 00108 SgPropMove* prop = 00109 dynamic_cast<SgPropMove*>(node->Get(SG_PROP_MOVE)); 00110 SgPoint p = prop->Value(); 00111 if (p == SG_PASS || ! bd.Occupied(p)) 00112 bd.Play(p, prop->Player()); 00113 } 00114 } 00115 } 00116 00117 //----------------------------------------------------------------------------