#include "CMI.hpp" namespace CMI{ HalfMove::HalfMove(): number(1), isBlack(false){ } HalfMove::~HalfMove() { if(mainline!=nullptr) delete mainline; for(HalfMove *v:variations) delete v; } void HalfMove::SetParent(CMI::HalfMove* m){ parent=static_cast(m); } std::vector HalfMove::GetVariations() const { std::vector vars; for(HalfMove *v:variations){ vars.push_back(static_cast(v)); } return vars; } void HalfMove::SetVariations(std::vector vars){ variations.clear(); for(auto *v: vars){ variations.push_back(static_cast(v)); } } void HalfMove::SetMainline(CMI::HalfMove* m) { mainline = static_cast(m); if(m!=nullptr){ if (!this->isBlack) { m->SetIsBlack(true); m->SetNumber(this->number); } else { m->SetIsBlack(false); m->SetNumber(this->number + 1); } m->SetParent(static_cast(this)); } } CMI::HalfMove* HalfMove::GetMainline() const {return mainline;}; CMI::HalfMove* HalfMove::GetParent() const {return parent;}; std::string HalfMove::GetSAN() const {return SAN;}; void HalfMove::SetSAN(std::string newSAN) {SAN=newSAN;}; std::uint16_t HalfMove::GetNumber() const {return number;}; void HalfMove::SetNumber(std::uint16_t n) {number=n;}; std::uint8_t HalfMove::GetNAG() const {return NAG;}; void HalfMove::SetNAG(std::uint8_t n) {NAG=n;}; std::string HalfMove::GetComment() const {return comment;}; void HalfMove::SetComment(std::string c) { comment=c;}; bool HalfMove::IsBlack() const {return isBlack;}; void HalfMove::SetIsBlack(bool b) {isBlack=b;}; // ---------- Implementation of various common operations ---------- void HalfMove::Promote(){ HalfMove *broot=GetBranchRoot(); if(broot!=nullptr){ HalfMove *parent=broot->GetParent(); if (parent != nullptr) { if (parent->GetMainline() != broot) { HalfMove *pparent=parent->GetParent(); // First update parent of parent: if (pparent != nullptr) { if (pparent->GetMainline() == parent) pparent->SetMainline(broot); else { pparent->AddVariation(broot); pparent->RemoveChild(parent); } } // Now update parent: parent->RemoveChild(broot); broot->AddVariation(parent); } } } } void HalfMove::SetAsMainline(){ HalfMove *broot = GetBranchRoot(); HalfMove *lastRoot; // Just promote until we cannot anymore do { lastRoot = broot; broot->Promote(); broot = GetBranchRoot(); } while (broot != lastRoot); } HalfMove* HalfMove::GetBranchRoot(){ HalfMove *m = this; HalfMove *p = GetParent(); while (p != nullptr) { if (p->GetMainline() != m) { return (m); } m = p; p = m->GetParent(); } return m; } void HalfMove::AddVariation(HalfMove* m){ m->SetIsBlack(IsBlack()); m->SetNumber(GetNumber()); m->SetParent(this); auto vars=GetVariations(); vars.push_back(m); SetVariations(vars); } bool HalfMove::RemoveVariation(HalfMove* m){ std::vector vars; bool removed=false; for(HalfMove *v: GetVariations()){ if(m!=v) vars.push_back(v); else removed=true; } if(removed) SetVariations(vars); return removed; } bool HalfMove::RemoveChild(HalfMove* m){ if(GetMainline()==m){ SetMainline(nullptr); return true; } return RemoveVariation(m); } }