#include "PGNGameBase.hpp" #include PGNGameBase::PGNGameBase(std::string pgn_file) : pgn(new pgnp::PGN()) { file = pgn_file; pgn->FromFile(pgn_file); } PGNGameBase::~PGNGameBase() { delete pgn; // Should never fail since pgn is never NULL } bool PGNGameBase::NextGame() { bool game_found = false; try { pgn->ParseNextGame(); game_found = true; } catch (...) { game_found = false; } return (game_found); } std::string PGNGameBase::GetTag(std::string tag) { if (pgn->HasTag(tag)) { return (pgn->GetTagValue(tag)); } return (""); } void PGNGameBase::CreateDatabaseFile(std::string path){ wxFile empty_pgn(path, wxFile::write); empty_pgn.Close(); } std::shared_ptr PGNGameBase::GetCurrentGame() { pgnp::HalfMove *pgnp_moves = new pgnp::HalfMove(); pgn->GetMoves(pgnp_moves); std::string fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; if (pgn->HasTag("FEN")) { fen = pgn->GetTagValue("FEN"); } // Init game object Game *g; if(pgnp_moves->count == -1){ // Check if PGN contains at least a move g=new Game(fen); } else { HalfMove *m = new HalfMove(pgnp_moves); m->SetFen(fen); g=new Game(m, fen); } // Setup game object for (std::string &s : pgn->GetTagList()) { g->SetTag(s, pgn->GetTagValue(s)); } g->SetResult(pgn->GetResult()); // Finish return (std::shared_ptr(g)); } void PGNGameBase::Reset() { delete pgn; pgn = new pgnp::PGN(); pgn->FromFile(file); } std::shared_ptr PGNGameBase::GetGame(std::uint32_t id) { Reset(); std::uint32_t curid = 0; while (NextGame()) { if (id == curid) { return (GetCurrentGame()); } curid++; } return nullptr; } void PGNGameBase::Save(std::vector to_delete, std::vector databases_to_import, std::vector> games_to_import) { wxStandardPaths stdPaths = wxStandardPaths::Get(); wxString tmp = stdPaths.GetTempDir() + "/save_pgn_tmp.pgn"; wxFile new_pgn(tmp, wxFile::write); Reset(); std::uint32_t id = 0; bool several = false; while (NextGame()) { if (std::find(to_delete.begin(), to_delete.end(), id) == to_delete.end()) { if (several) { new_pgn.Write("\n\n"); } else { several = true; } std::shared_ptr g = GetCurrentGame(); new_pgn.Write(GetPGN(g)); } id++; } // Now add new games for(auto dbpath: databases_to_import){ std::shared_ptr current=OpenDatabase(dbpath); while (current->NextGame()) { if (several) { new_pgn.Write("\n\n"); } else { several = true; } std::shared_ptr g = current->GetCurrentGame(); new_pgn.Write(GetPGN(g)); } } for (std::shared_ptr g : games_to_import) { if (several) { new_pgn.Write("\n\n"); } else { several = true; } new_pgn.Write(GetPGN(g)); } new_pgn.Close(); wxCopyFile(tmp, file); wxRemoveFile(tmp); } void PGNGameBase::Export(std::shared_ptr base) { wxFile new_pgn(file, wxFile::write); base->Reset(); bool several = false; while (base->NextGame()) { if (several) { new_pgn.Write("\n\n"); } else { several = true; } std::shared_ptr g = base->GetCurrentGame(); new_pgn.Write(GetPGN(g)); } new_pgn.Close(); } std::string PGNGameBase::GetPGN(std::shared_ptr g) { std::string pgn; HalfMove *m=g->GetMoves(); for (auto const &element : g->ListTags()) { pgn += '[' + element + " \"" + g->GetTag(element) + "\"]\n"; } if(m !=nullptr){ pgn += GetMovesPGN(m,m->IsABlackMove()); pgn += " "; } pgn += g->GetResult(); return (pgn); } std::string PGNGameBase::GetMovesPGN(HalfMove *m, bool needDots) { std::string part; bool newNeedDots = false; if (!m->IsABlackMove() || needDots) { part += std::to_string(m->Number) + "."; if (needDots) { part += ".."; } } part += m->move; if (m->comment.size() > 0) { part += " {"; part += m->comment; part += "}"; newNeedDots = true; } if (m->GetVariations().size() > 0) { newNeedDots = true; for (HalfMove *v : m->GetVariations()) { part += " ("; part += GetMovesPGN(v, m->IsABlackMove()); part += ")"; } } if (m->GetMainline() != nullptr) { part += " " + GetMovesPGN(m->GetMainline(), !m->IsABlackMove() && newNeedDots); } return (part); }