blob: ae963a19ebab71aaafaba855881328a768fad2c6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#include "CMI.hpp"
namespace CMI{
HalfMove::HalfMove(): number(1), isBlack(false){
}
HalfMove::~HalfMove() {
if(mainline!=nullptr)
delete mainline;
for(HalfMove *v:variations)
delete v;
}
void HalfMove::SetParent(CMI::HalfMove* m){
parent=static_cast<HalfMove*>(m);
}
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::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));
}
}
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::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 = GetParent();
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);
auto vars=GetVariations();
vars.push_back(m);
SetVariations(vars);
}
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;
}
bool HalfMove::RemoveChild(HalfMove* m){
if(GetMainline()==m){
SetMainline(nullptr);
return true;
}
return RemoveVariation(m);
}
}
|