aboutsummaryrefslogtreecommitdiff
path: root/src/Openings.cpp
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2023-01-16 14:55:48 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2023-01-16 14:55:48 +0100
commit3b11b9d4f3eee5faa656d7ee61077e80726bdc36 (patch)
tree7817c036843c18eac0012298ec7808d795411f58 /src/Openings.cpp
parentb7667d1d40045ecd840b9b192c2740e5f83e7eba (diff)
Improve openings database code
Diffstat (limited to 'src/Openings.cpp')
-rw-r--r--src/Openings.cpp106
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