mirror of
https://gitlab.com/manzerbredes/ochess.git
synced 2025-04-06 10:06:29 +02:00
213 lines
4.7 KiB
C++
213 lines
4.7 KiB
C++
#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);
|
|
}
|