#include "HalfMove.hpp" HalfMove::HalfMove(std::string move) : capture(' ') { this->move = move; fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; } HalfMove::HalfMove(std::string move, std::string fen) : fen(fen), capture(' ') { this->move = move; } HalfMove::~HalfMove() { for (HalfMove *m : variations) { delete m; } } void HalfMove::AddVariation(HalfMove *m) { m->IsBlack = this->IsBlack; m->Number = this->Number; HalfMove::variations.push_back(m); cgeditor::CGEHalfMove::variations.push_back(m); m->SetParent(this); } std::map HalfMove::GetLineCaptures() { std::map captures; HalfMove *m = this; do { char c = m->capture; if (captures.find(c) != captures.end()) { captures[c]++; } else { captures[c] = 1; } m = m->parent; } while (m != NULL); return (captures); } void HalfMove::SetCapture(char c) { capture = c; } void HalfMove::AddMove(HalfMove *m) { if (this->mainline == NULL) { SetMainline(m); } else { if (mainline != NULL) { mainline->AddVariation(m); } } } void HalfMove::SetMainline(HalfMove *m) { if (!this->IsBlack) { m->IsBlack = true; m->Number = this->Number; } else { m->IsBlack = false; m->Number = this->Number + 1; } HalfMove::mainline = m; cgeditor::CGEHalfMove::MainLine = m; if (m != NULL) { m->SetParent(this); } } void HalfMove::SetParent(HalfMove *m) { HalfMove::parent = m; CGEHalfMove::Parent = m; } void HalfMove::RemoveChild(HalfMove *m) { std::uint32_t i = 0; bool found = false; for (i; i < HalfMove::variations.size(); i++) { if (HalfMove::variations[i] == m) { found = true; break; } } if (found) { HalfMove::variations.erase(HalfMove::variations.begin() + i); } if (HalfMove::mainline == m) { HalfMove::mainline = NULL; } cgeditor::CGEHalfMove::RemoveChild((CGEHalfMove *)m); } HalfMove *HalfMove::GetParent() { return (parent); } HalfMove *HalfMove::GetRoot() { HalfMove *m = this; HalfMove *p = HalfMove::parent; while (p != NULL) { if (p->mainline != m) { return (m); } m = p; p = m->HalfMove::parent; } return (m); } void HalfMove::SetAsMainline() { HalfMove *root = GetRoot(); HalfMove *lastRoot; do { lastRoot = root; root->HalfMove::Promote(); root = GetRoot(); } while (root != lastRoot); } HalfMove *HalfMove::GetMainline() { return (mainline); } HalfMove::HalfMove(pgnp::HalfMove *m, std::string initial_fen) { chessarbiter::ChessArbiter arbiter; arbiter.Setup(initial_fen); arbiter.Play(arbiter.ParseSAN(m->move)); this->fen = arbiter.GetFEN(); this->move = m->move; this->IsBlack = m->isBlack; this->SetComment(m->comment); this->Number = m->count; if (m->MainLine != NULL) { this->SetMainline(new HalfMove(m->MainLine, arbiter.GetFEN())); } for (pgnp::HalfMove *v : m->variations) { arbiter.Setup(initial_fen); arbiter.Play(arbiter.ParseSAN(v->move)); this->AddVariation(new HalfMove(v, arbiter.GetFEN())); } } void HalfMove::SetFen(std::string fen) { this->fen = fen; } void HalfMove::Promote() { HalfMove *root = GetRoot(); if (root->parent != NULL) { HalfMove *p = root->parent; if (p->HalfMove::mainline != root) { if (root->parent->HalfMove::parent != NULL) { HalfMove *pp = root->parent->HalfMove::parent; if (pp->HalfMove::mainline == p) { pp->HalfMove::SetMainline(root); } else { pp->AddVariation(root); pp->HalfMove::RemoveChild(p); } } if (p->HalfMove::mainline == root) { p->HalfMove::SetMainline(NULL); } else { p->HalfMove::RemoveChild(root); } root->AddVariation(p); } } } bool HalfMove::IsVariation() { HalfMove *m = this; HalfMove *p = HalfMove::parent; while (p != NULL) { if (p->mainline != m) { return (true); } m = p; p = m->HalfMove::parent; } return (false); } std::string HalfMove::GetFen() { return (fen); } std::string HalfMove::GetPGN() { return (GetPGN(IsBlack)); } std::string HalfMove::GetPGN(bool needDots) { std::string part; bool newNeedDots = false; if (!IsBlack || needDots) { part += std::to_string(Number) + "."; if (needDots) { part += ".."; } } part += move; if (GetNbLineComment() > 0) { part += " {"; part += GetComment(); part += "}"; newNeedDots = true; } if (variations.size() > 0) { newNeedDots = true; for (HalfMove *v : variations) { part += " ("; part += v->GetPGN(IsBlack); part += ")"; } } if (mainline != NULL) { part += " " + mainline->GetPGN(newNeedDots); } return (part); }