diff options
Diffstat (limited to 'src/Openings.cpp')
| -rw-r--r-- | src/Openings.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/Openings.cpp b/src/Openings.cpp new file mode 100644 index 0000000..02a0ba5 --- /dev/null +++ b/src/Openings.cpp @@ -0,0 +1,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(int 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))); + } +}
\ No newline at end of file |
