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
|
#include "Openings.hpp"
#include <sstream>
/**
* @brief Count the number of similar moves in between two lines
*
* @param m1
* @param m2
* @return int
*/
inline int CompareMainlines(const pgnp::HalfMove *m1,const pgnp::HalfMove *m2){
int count=0;
const pgnp::HalfMove *n1=m1;
const pgnp::HalfMove *n2=m2;
while(n1 && n2 != nullptr){
if(n1->move == n2->move)
count++;
else
break;
n1=n1->MainLine;
n2=n2->MainLine;
}
return count;
}
Openings::Openings() {
std::string tsv(a_tsv);
LoadVolume(tsv,&A);
tsv=std::string(b_tsv);
LoadVolume(tsv,&B);
tsv=std::string(c_tsv);
LoadVolume(tsv,&C);
tsv=std::string(d_tsv);
LoadVolume(tsv,&D);
tsv=std::string(e_tsv);
LoadVolume(tsv,&E);
}
void Openings::SearchOpening(const pgnp::HalfMove *moves,std::string &name, std::string &eco){
// Now goto the right volume
std::vector<Volume*> vols={&A,&B,&C,&D,&E};
if(moves->GetLength()>=2){
if(moves->move == "e4"){
if(moves->MainLine->move == "e6"|| moves->MainLine->move == "e5")
vols={&C};
else
vols={&B};
}
// TODO: Improve volumes filtering
}
// Then search for opening name:
int matches=0;
for(Volume *v: vols){
for(auto &entry: *v){
std::string &eco_=std::get<0>(entry);
std::string &name_=std::get<1>(entry);
std::string &pgn_=std::get<2>(entry);
pgnp::HalfMove *moves_=new pgnp::HalfMove();
pgnp::ParseSANMoves(pgn_,moves_);
int nmatches=CompareMainlines(moves,moves_);
if(nmatches>matches && nmatches == moves_->GetLength()){
name=name_;
eco=eco_;
matches=nmatches;
if(moves->GetLength()==moves_->GetLength()){
delete moves_;
return;
}
}
delete moves_;
}
}
}
void Openings::GuessOpening(const std::string &SANMoves, std::string &name, std::string &eco){
pgnp::HalfMove *m=new pgnp::HalfMove();
pgnp::ParseSANMoves(SANMoves,m);
SearchOpening(m,name,eco);
delete m;
}
void Openings::GuessOpening(const pgnp::HalfMove *moves, std::string &name, std::string &eco){
SearchOpening(moves,name,eco);
}
void Openings::LoadVolume(const std::string &tsv, Volume *vol){
std::istringstream f(tsv);
std::string line;
while (std::getline(f, line)) {
int eco=-1,name=-1,pgn=-1;
for(std::size_t i=0;i<line.size();i++){
if(line[i]=='\t'){
if(eco == -1)
eco=i-1;
else if(name==-1)
name=i-1;
else
pgn=i;
}
}
vol->push_back(std::make_tuple(
line.substr(0,eco+1),
line.substr(eco+2,name-eco-1),
line.substr(name+2,pgn-name)));
}
}
|