diff options
Diffstat (limited to 'src/CMI.cpp')
| -rw-r--r-- | src/CMI.cpp | 294 |
1 files changed, 164 insertions, 130 deletions
diff --git a/src/CMI.cpp b/src/CMI.cpp index ae963a1..a57bceb 100644 --- a/src/CMI.cpp +++ b/src/CMI.cpp @@ -1,149 +1,183 @@ #include "CMI.hpp" -namespace CMI{ +namespace CMI { - HalfMove::HalfMove(): number(1), isBlack(false){ - } +HalfMove::HalfMove() + : number(1), isBlack(false), NAG(0), parent(nullptr), mainline(nullptr) {} - HalfMove::~HalfMove() { - if(mainline!=nullptr) - delete mainline; - for(HalfMove *v:variations) - delete v; - } +HalfMove::HalfMove(const std::string &SAN) + : number(1), isBlack(false), parent(nullptr), mainline(nullptr) {} - void HalfMove::SetParent(CMI::HalfMove* m){ - parent=static_cast<HalfMove*>(m); - } +HalfMove::HalfMove(const std::string &SAN, const std::string &comment, + std::uint16_t number, std::uint8_t NAG, bool isBlack) + : SAN(SAN), comment(comment), number(number), NAG(NAG), isBlack(isBlack), + parent(nullptr), mainline(nullptr) {} +HalfMove::~HalfMove() { + if (mainline != nullptr) + delete mainline; + for (HalfMove *v : variations) + delete v; +} - std::vector<CMI::HalfMove*> HalfMove::GetVariations() const { - std::vector<CMI::HalfMove*> vars; - for(HalfMove *v:variations){ - vars.push_back(static_cast<CMI::HalfMove*>(v)); - } - return vars; - } - void HalfMove::SetVariations(std::vector<CMI::HalfMove*> vars){ - variations.clear(); - for(auto *v: vars){ - variations.push_back(static_cast<HalfMove*>(v)); - } - } +void HalfMove::SetParent(HalfMove *m) { parent = m; } +std::vector<HalfMove *> HalfMove::GetVariations() const { return variations; } - void HalfMove::SetMainline(CMI::HalfMove* m) { - mainline = static_cast<HalfMove*>(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<CMI::HalfMove*>(this)); - } - } +HalfMove *HalfMove::GetMainline() const { return mainline; }; +HalfMove *HalfMove::GetParent() const { return parent; }; +std::string HalfMove::GetSAN() const { return SAN; }; - 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::SetSAN(const std::string &newSAN) { SAN = newSAN; }; - void HalfMove::SetAsMainline(){ - HalfMove *broot = GetBranchRoot(); - HalfMove *lastRoot; - // Just promote until we cannot anymore - do { - lastRoot = broot; - broot->Promote(); - broot = GetBranchRoot(); - } while (broot != lastRoot); - } +std::uint16_t HalfMove::GetNumber() const { return number; }; - 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::SetNumber(std::uint16_t n) { number = n; }; - void HalfMove::AddVariation(HalfMove* m){ - m->SetIsBlack(IsBlack()); - m->SetNumber(GetNumber()); - m->SetParent(this); - auto vars=GetVariations(); - vars.push_back(m); - SetVariations(vars); - } +std::uint8_t HalfMove::GetNAG() const { return NAG; }; - bool HalfMove::RemoveVariation(HalfMove* m){ - std::vector<HalfMove*> vars; - bool removed=false; - for(HalfMove *v: GetVariations()){ - if(m!=v) - vars.push_back(v); - else - removed=true; - } - if(removed) - SetVariations(vars); - return removed; - } +void HalfMove::SetNAG(std::uint8_t n) { NAG = n; }; + +std::string HalfMove::GetComment() const { return comment; }; + +void HalfMove::SetComment(const std::string &c) { comment = c; }; - bool HalfMove::RemoveChild(HalfMove* m){ - if(GetMainline()==m){ - SetMainline(nullptr); - return true; +bool HalfMove::IsBlack() const { return isBlack; }; + +void HalfMove::SetIsBlack(bool b) { isBlack = b; }; + +void HalfMove::ClearVariations() { variations.clear(); } + +void HalfMove::SetMainline(HalfMove *m) { + mainline = 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(this); + } +} + +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); + } } - return RemoveVariation(m); + // 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 = parent; + 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); + variations.push_back(m); +} + +bool HalfMove::RemoveVariation(HalfMove *m) { + std::vector<HalfMove *> vars; + bool removed = false; + for (HalfMove *v : GetVariations()) { + if (m != v) + vars.push_back(v); + else + removed = true; + } + if (removed) + variations = vars; + return removed; +} + +bool HalfMove::RemoveChild(HalfMove *m) { + if (GetMainline() == m) { + mainline = nullptr; + return true; + } + return RemoveVariation(m); +} + +bool HalfMove::Contains(HalfMove *m) const { + if (m == nullptr) + return false; + else if (this == m) + return true; + else if (mainline != nullptr && mainline->Contains(m)) { + return true; + } else { + for (HalfMove *v : variations) { + if (v->Contains(m)) + return true; } -}
\ No newline at end of file + } + return false; +} + +bool HalfMove::IsConsistent() const { + // Check mainline + if (mainline != nullptr) { + if (isBlack == mainline->isBlack) + return false; + if (isBlack && number + 1 != mainline->number) + return false; + if (!isBlack && number != mainline->number) + return false; + if (mainline->parent != this) + return false; + if (!mainline->IsConsistent()) + return false; + } + // Check variations + for (HalfMove *v : variations) { + if (number != v->number || isBlack != v->isBlack || v->parent != this) + return false; + if (!v->IsConsistent()) + return false; + } + return true; +} +} // namespace CMI
\ No newline at end of file |
