#include "HalfMove.hpp" HalfMove::HalfMove(std::string move_absolute,std::string move_san) : capture(' ') { SetAbsoluteMove(move_absolute); SetSAN(move_san); fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; } HalfMove::HalfMove(std::string move_absolute, std::string move_san, std::string fen) : fen(fen), capture(' ') { SetAbsoluteMove(move_absolute); SetSAN(move_san); } void HalfMove::SetOpening(const std::string &name, const std::string &eco){ HalfMove *m=this; while(m!=nullptr){ m->opening=name; m->eco=eco; if(m->GetParent() != nullptr && static_cast(m->GetParent()->GetMainline())==m) m=static_cast(m->GetParent()); else break; } } void HalfMove::GetOpening(std::string &name, std::string &eco){ name=this->opening; eco=this->eco; } std::vector HalfMove::GetLine(){ std::vector line; HalfMove *m=this; while(m!=nullptr){ line.push_back(m); // Check if in a variation: if(m->GetParent()!=nullptr && static_cast(m->GetParent()->GetMainline())!=m) m=static_cast(m->GetParent()->GetParent()); // Because we are in a variation else m=static_cast(m->GetParent()); } // Reverse the order to get it in the played order: std::reverse(line.begin(), line.end()); return line; } std::string HalfMove::GetLineAsSAN(){ // If not, get the current move line (or first move) // and try to guess opening auto line=GetLine(); // Vector of HalfMove std::string pgn; int count=1; for(std::size_t i=0;iGetSAN() +" "; } return pgn; } HalfMove::HalfMove(HalfMove *m){ src=m->src; dst=m->dst; SetSAN(m->GetSAN()); fen=m->fen; capture=m->capture; SetIsBlack(m->IsBlack()); SetNumber(m->GetNumber()); SetNAG(m->GetNAG()); SetComment(m->GetComment()); if(m->GetMainline() != nullptr){ SetMainline(static_cast(new HalfMove(static_cast(m->GetMainline())))); } for (CMI::HalfMove *v: m->GetVariations()) { AddVariation(new HalfMove(static_cast(v))); } } 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 = static_cast(m->GetParent()); } while (m != nullptr); return (captures); } void HalfMove::SetCapture(char c) { capture = c; } void HalfMove::AddMove(HalfMove *m) { if (GetMainline() == nullptr) { SetMainline(m); } else { if(GetMainline()!=nullptr) GetMainline()->AddVariation(m); } } void HalfMove::SetAbsoluteMove(const std::string &move_absolute){ this->src=move_absolute.substr(0,2); this->dst=move_absolute.substr(2,2); } HalfMove::HalfMove(CMI::HalfMove *m) : capture(' ') { SetSAN(m->GetSAN()); SetNAG(m->GetNAG()); SetIsBlack(m->IsBlack()); SetComment(m->GetComment()); SetNumber(m->GetNumber()); if (m->GetMainline() != nullptr) { SetMainline(new HalfMove(m->GetMainline())); } for (CMI::HalfMove *v : m->GetVariations()) { AddVariation(new HalfMove(v)); } } void HalfMove::GetAbsoluteMove(std::string &src,std::string &dst){ src=this->src; dst=this->dst; } void HalfMove::SetFen(std::string fen) { this->fen = fen; } bool HalfMove::HasParent(HalfMove*m){ return m==static_cast(GetParent()); } bool HalfMove::HasChild(HalfMove*m){ if(m==nullptr) return false; if(static_cast(GetMainline())==m){ return true; } for(auto var: GetVariations()){ if(static_cast(var) == m) return true; } return false; } bool HalfMove::IsVariation() { HalfMove *m = this; HalfMove *p = static_cast(GetParent()); while (p != nullptr) { if (static_cast(p->GetMainline()) != m) { return (true); } m = p; p = static_cast(m->GetParent()); } return (false); } std::string HalfMove::GetFen() { return (fen); } HalfMove* HalfMove::GetCurrentMoveWithFEN(const std::string fen){ if(this->fen == fen){ return this; } else { for(auto var: GetVariations()){ HalfMove* m=static_cast(var); if(m->fen == fen) return m; } } return nullptr; } void HalfMove::BuildAndVerify(HalfMove *m, std::string fen) { arbiter.Setup(fen); std::string move_absolute=arbiter.ParseSAN(m->GetSAN()); m->SetAbsoluteMove(move_absolute); bool work = arbiter.Play(move_absolute,arbiter.ParseSANPromotion(m->GetSAN())); if (!work) { wxLogDebug("Bug! %s", m->GetSAN()); } char capture = arbiter.GetCapture(); if (capture != ' ') { m->capture = capture; } m->fen = arbiter.GetFEN(); if (m->GetMainline() != nullptr) { BuildAndVerify(static_cast(m->GetMainline()), arbiter.GetFEN()); } else { // Otherwise we are on a leaf! So, guess the opening: std::string name,eco; wxGetApp().GetBook().GuessOpening(m->GetLineAsSAN(),name,eco); if(eco.size()>0) m->SetOpening(name,eco); } for (CMI::HalfMove *v : m->GetVariations()) { BuildAndVerify(static_cast(v), fen); } } void HalfMove::BuildAndVerify(std::string initial_fen) { BuildAndVerify(this, initial_fen); }