aboutsummaryrefslogtreecommitdiff
path: root/src/game_tab/HalfMove.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game_tab/HalfMove.cpp')
-rw-r--r--src/game_tab/HalfMove.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/game_tab/HalfMove.cpp b/src/game_tab/HalfMove.cpp
new file mode 100644
index 0000000..72ee24c
--- /dev/null
+++ b/src/game_tab/HalfMove.cpp
@@ -0,0 +1,213 @@
+#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<char, std::uint8_t> HalfMove::GetLineCaptures() {
+ std::map<char, std::uint8_t> 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);
+}