#include "Openings.hpp" #include /** * @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 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;ipush_back(std::make_tuple( line.substr(0,eco+1), line.substr(eco+2,name-eco-1), line.substr(name+2,pgn-name))); } }