aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2022-01-25 10:53:10 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2022-01-25 10:53:10 +0100
commit4f1d7c524744861ee9cd3052c2ec9e42e83a32ca (patch)
treef2be23409388665dc0766be9ba89ee94db9c9379
parente817ac6bed46737839b592b4308c6d525d70aa2d (diff)
Refactoring
-rw-r--r--CMakeLists.txt6
-rw-r--r--src/HalfMove.cpp66
-rw-r--r--src/HalfMove.hpp38
-rw-r--r--src/PGN.cpp (renamed from src/pgnp.cpp)83
-rw-r--r--src/PGN.hpp (renamed from src/pgnp.hpp)50
5 files changed, 137 insertions, 106 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 237f223..2381751 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,13 +2,15 @@ cmake_minimum_required(VERSION 3.10)
project(pgnp)
# Shared library
-add_library(pgnp SHARED src/pgnp.cpp)
+add_library(pgnp SHARED src/PGN.cpp src/HalfMove.cpp)
# Includes
set(PGNP_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/includes) # For conveniance
set(PGNP_INCLUDE_DIR ${PGNP_INCLUDE_DIR} PARENT_SCOPE) # To be used by other projects with add_subdirectory()
file(MAKE_DIRECTORY ${PGNP_INCLUDE_DIR})
-configure_file(src/pgnp.hpp ${PGNP_INCLUDE_DIR} COPYONLY)
+configure_file(src/PGN.hpp ${PGNP_INCLUDE_DIR}/pgnp.hpp COPYONLY)
+configure_file(src/HalfMove.hpp ${PGNP_INCLUDE_DIR} COPYONLY)
+
include_directories(${PGNP_INCLUDE_DIR})
# Unit tests
diff --git a/src/HalfMove.cpp b/src/HalfMove.cpp
new file mode 100644
index 0000000..7c7a85e
--- /dev/null
+++ b/src/HalfMove.cpp
@@ -0,0 +1,66 @@
+#include "HalfMove.hpp"
+
+namespace pgnp {
+
+HalfMove::HalfMove() : count(-1), isBlack(false), MainLine(NULL) {}
+
+HalfMove::~HalfMove() {
+ for (auto *move : variations) {
+ delete move;
+ }
+}
+
+std::string HalfMove::NestedDump(HalfMove *m, int indent) {
+ std::stringstream ss;
+
+ for (int i = 0; i < indent; i++) {
+ ss << " ";
+ }
+ ss << " "
+ << " Move=" << m->move << " Count=" << m->count << " Comment=\""
+ << m->comment << "\""
+ << " IsBlack=" << m->isBlack << " Variations=" << m->variations.size()
+ << std::endl;
+
+ for (auto *var : m->variations) {
+ ss << NestedDump(var, indent + 1);
+ }
+
+ if (m->MainLine != NULL) {
+ ss << NestedDump(m->MainLine, indent);
+ }
+ return (ss.str());
+}
+
+std::string HalfMove::Dump() { return (NestedDump(this, 0)); }
+
+int HalfMove::GetLength() {
+ int length = 0;
+ HalfMove *m = this;
+ while (m != NULL) {
+ length++;
+ m = m->MainLine;
+ }
+ return length;
+}
+
+void HalfMove::Copy(HalfMove *copy) {
+ copy->count = count;
+ copy->isBlack = isBlack;
+ copy->move = move;
+ copy->comment = comment;
+
+ // Copy MainLine
+ if (MainLine != NULL) {
+ copy->MainLine = new HalfMove();
+ MainLine->Copy(copy->MainLine);
+ }
+
+ // Copy variation
+ for (HalfMove *var : variations) {
+ HalfMove *new_var = new HalfMove();
+ copy->variations.push_back(new_var);
+ var->Copy(new_var);
+ }
+}
+} // namespace pgnp \ No newline at end of file
diff --git a/src/HalfMove.hpp b/src/HalfMove.hpp
new file mode 100644
index 0000000..dc238cd
--- /dev/null
+++ b/src/HalfMove.hpp
@@ -0,0 +1,38 @@
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace pgnp {
+
+/**
+ * Most members are public for conveniance sake
+ */
+class HalfMove {
+private:
+ /// @brief Recursive dump
+ std::string NestedDump(HalfMove *, int);
+
+public:
+ /// @brief Contains current move count
+ int count;
+ /// @brief Is this move for black
+ bool isBlack;
+ /// @brief The SAN move
+ std::string move;
+ /// @brief Comment associated to the move
+ std::string comment;
+ /// @brief Next HalfMove link to this line
+ HalfMove *MainLine;
+ /// @brief Next HalfMove links to variation of this line
+ std::vector<HalfMove *> variations;
+
+ HalfMove();
+ ~HalfMove();
+ /// @brief Get number of HalfMove in the MailLine
+ int GetLength();
+ /// @brief Dump move and all its variations
+ std::string Dump();
+ /// @brief Perform a deep copy of a HalfMove
+ void Copy(HalfMove *copy);
+};
+} // namespace pgnp \ No newline at end of file
diff --git a/src/pgnp.cpp b/src/PGN.cpp
index 3262a5e..e77bcde 100644
--- a/src/pgnp.cpp
+++ b/src/PGN.cpp
@@ -16,65 +16,6 @@
namespace pgnp {
-HalfMove::HalfMove() : count(-1), isBlack(false), MainLine(NULL) {}
-
-HalfMove::~HalfMove() {
- for (auto *move : variations) {
- delete move;
- }
-}
-
-void HalfMove::NestedDump(HalfMove *m, int indent) {
- for (int i = 0; i < indent; i++) {
- std::cout << " ";
- }
- std::cout << " "
- << " Move=" << m->move << " Count=" << m->count << " Comment=\""
- << m->comment << "\""
- << " IsBlack=" << m->isBlack
- << " Variations=" << m->variations.size() << std::endl;
-
- for (auto *var : m->variations) {
- NestedDump(var, indent + 1);
- }
-
- if (m->MainLine != NULL) {
- NestedDump(m->MainLine, indent);
- }
-}
-
-void HalfMove::Dump() { NestedDump(this, 0); }
-
-int HalfMove::GetLength() {
- int length = 0;
- HalfMove *m = this;
- while (m != NULL) {
- length++;
- m = m->MainLine;
- }
- return length;
-}
-
-void HalfMove::Copy(HalfMove* copy){
- copy->count=count;
- copy->isBlack=isBlack;
- copy->move=move;
- copy->comment=comment;
-
- // Copy MainLine
- if(MainLine!=NULL){
- copy->MainLine=new HalfMove();
- MainLine->Copy(copy->MainLine);
- }
-
- // Copy variation
- for(HalfMove *var:variations){
- HalfMove *new_var=new HalfMove();
- copy->variations.push_back(new_var);
- var->Copy(new_var);
- }
-}
-
PGN::~PGN() {
if (moves != NULL)
delete moves;
@@ -101,7 +42,7 @@ void PGN::FromString(std::string pgn_content) {
loc = ParseNextTag(loc);
} else if (IS_DIGIT(c)) {
moves = new HalfMove();
- loc = ParseLine(loc, moves);
+ loc = ParseHalfMove(loc, moves);
break;
}
}
@@ -141,7 +82,7 @@ bool PGN::HasTag(std::string key) {
return (std::find(tags.begin(), tags.end(), key) != tags.end());
}
-int PGN::ParseLine(int loc, HalfMove *hm) {
+int PGN::ParseHalfMove(int loc, HalfMove *hm) {
// Goto next char
loc = NextNonBlank(loc);
EOF_CHECK(loc);
@@ -225,7 +166,7 @@ int PGN::ParseLine(int loc, HalfMove *hm) {
while (!IS_EOF(loc) && pgn_content[loc] == '(') {
loc++; // Skip '('
HalfMove *var = new HalfMove;
- loc = ParseLine(loc, var);
+ loc = ParseHalfMove(loc, var);
hm->variations.push_back(var);
loc++; // Skip ')'
}
@@ -235,7 +176,7 @@ int PGN::ParseLine(int loc, HalfMove *hm) {
if (!IS_EOF(loc)) {
HalfMove *next_hm = new HalfMove;
next_hm->count = hm->count;
- loc = ParseLine(loc, next_hm);
+ loc = ParseHalfMove(loc, next_hm);
// Check if move parsed successfuly
if (next_hm->move.size() > 0) {
hm->MainLine = next_hm;
@@ -285,7 +226,7 @@ int PGN::ParseNextTag(int start_loc) {
return (valueloc + 1); // +1 For the last char of the tag which is ']'
}
-void PGN::GetMoves(HalfMove* copy) { moves->Copy(copy); }
+void PGN::GetMoves(HalfMove *copy) { moves->Copy(copy); }
std::vector<std::string> PGN::GetTagList() { return tagkeys; }
@@ -296,16 +237,18 @@ std::string PGN::GetTagValue(std::string key) {
return tags[key];
}
-void PGN::Dump() {
- std::cout << "---------- PGN DUMP ----------" << std::endl;
- std::cout << "Tags:" << std::endl;
+std::string PGN::Dump() {
+ std::stringstream ss;
+ ss << "---------- PGN DUMP ----------" << std::endl;
+ ss << "Tags:" << std::endl;
for (auto &tag : GetTagList()) {
- std::cout << " " << tag << "=" << GetTagValue(tag) << std::endl;
+ ss << " " << tag << "=" << GetTagValue(tag) << std::endl;
}
- std::cout << "Moves:" << std::endl;
+ ss << "Moves:" << std::endl;
if (moves != NULL)
- moves->Dump();
+ ss << moves->Dump();
+ return (ss.str());
}
int PGN::NextNonBlank(int loc) {
diff --git a/src/pgnp.hpp b/src/PGN.hpp
index 492dfc0..6da955b 100644
--- a/src/pgnp.hpp
+++ b/src/PGN.hpp
@@ -1,70 +1,52 @@
+#include "HalfMove.hpp"
#include <algorithm>
#include <exception>
#include <fstream>
-#include <iostream>
-#include <sstream>
-#include <streambuf>
-#include <string>
#include <unordered_map>
-#include <vector>
namespace pgnp {
-class HalfMove {
-private:
- /// @brief Recursive dump
- void NestedDump(HalfMove *, int);
-
-public:
- int count;
- bool isBlack;
- std::string move;
- std::string comment;
- HalfMove *MainLine;
- std::vector<HalfMove *> variations;
-
- HalfMove();
- ~HalfMove();
- /// @brief Get number of HalfMove in the MailLine
- int GetLength();
- /// @brief Dump move and all its variations
- void Dump();
- void Copy(HalfMove* copy);
-};
-
class PGN {
private:
+ /// @brief Contains tags data
std::unordered_map<std::string, std::string> tags;
+ /// @brief Contains the tags list in parsed order
std::vector<std::string> tagkeys;
+ /// @brief Contains game result (last PGN word)
std::string result;
-
+ /// @brief COntains the parsed PGN moves
HalfMove *moves;
+ /// @brief Contains the PGN data
std::string pgn_content;
public:
~PGN();
void FromFile(std::string);
void FromString(std::string);
+ /// @brief Check if PGN contains a specific tag
bool HasTag(std::string);
/// @brief Perform a Seven Tag Roster compliance check
void STRCheck();
- /// @brief Dump parsed PGN
- void Dump();
+ /// @brief Dump parsed PGN into a string
+ std::string Dump();
+ /// @brief Retrieve parsed tag list
std::vector<std::string> GetTagList();
+ /// @brief Access to the value of a tag
std::string GetTagValue(std::string);
+ /// @brief Get game result based on the last PGN word
std::string GetResult();
- void GetMoves(HalfMove*);
+ /// @brief Fetch PGN moves as HalfMove structure
+ void GetMoves(HalfMove *);
private:
/// @brief Populate @a tags with by parsing the one starting at location in
/// argument
int ParseNextTag(int);
-
/// @brief Get the next non-blank char location starting from location in
/// argument
int NextNonBlank(int);
-
- int ParseLine(int, HalfMove *);
+ /// @brief Parse a HalfMove at a specific location into @a pgn_content
+ int ParseHalfMove(int, HalfMove *);
};
struct UnexpectedEOF : public std::exception {