aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/HalfMove.cpp13
-rw-r--r--src/HalfMove.hpp6
-rw-r--r--src/PGN.cpp42
-rw-r--r--src/PGN.hpp1
-rw-r--r--tests/tests.cpp3
5 files changed, 50 insertions, 15 deletions
diff --git a/src/HalfMove.cpp b/src/HalfMove.cpp
index 7c7a85e..290587a 100644
--- a/src/HalfMove.cpp
+++ b/src/HalfMove.cpp
@@ -63,4 +63,17 @@ void HalfMove::Copy(HalfMove *copy) {
var->Copy(new_var);
}
}
+
+HalfMove *HalfMove::GetHalfMoveAt(int distance) {
+ HalfMove *tmp=this;
+ while(distance>0){
+ if(tmp==NULL){
+ throw HalfMoveOutOfRange();
+ }
+ distance--;
+ tmp=tmp->MainLine;
+ }
+ return(tmp);
+}
+
} // namespace pgnp \ No newline at end of file
diff --git a/src/HalfMove.hpp b/src/HalfMove.hpp
index dc238cd..e049571 100644
--- a/src/HalfMove.hpp
+++ b/src/HalfMove.hpp
@@ -34,5 +34,11 @@ public:
std::string Dump();
/// @brief Perform a deep copy of a HalfMove
void Copy(HalfMove *copy);
+ /// @brief Get HalfMove located x down the MainLine
+ HalfMove* GetHalfMoveAt(int);
+};
+
+struct HalfMoveOutOfRange : public std::exception {
+ const char *what() const throw() { return "HalfMove distance is out of range"; }
};
} // namespace pgnp \ No newline at end of file
diff --git a/src/PGN.cpp b/src/PGN.cpp
index e77bcde..018473b 100644
--- a/src/PGN.cpp
+++ b/src/PGN.cpp
@@ -33,7 +33,7 @@ void PGN::FromFile(std::string filepath) {
void PGN::FromString(std::string pgn_content) {
this->pgn_content = pgn_content;
- moves = NULL;
+ moves = new HalfMove();
int loc = 0;
while (!IS_EOF(loc)) {
char c = pgn_content[loc];
@@ -41,9 +41,11 @@ void PGN::FromString(std::string pgn_content) {
if (c == '[') {
loc = ParseNextTag(loc);
} else if (IS_DIGIT(c)) {
- moves = new HalfMove();
loc = ParseHalfMove(loc, moves);
break;
+ } else if (c=='{') {
+ loc = ParseComment(loc,moves);
+ continue; // No need loc++
}
}
loc++;
@@ -82,6 +84,27 @@ bool PGN::HasTag(std::string key) {
return (std::find(tags.begin(), tags.end(), key) != tags.end());
}
+int PGN::ParseComment(int loc, HalfMove *hm) {
+ // Goto next char
+ loc = NextNonBlank(loc);
+ EOF_CHECK(loc);
+ char c = pgn_content[loc];
+
+ if(c=='{'){
+ loc++;
+ EOF_CHECK(loc);
+ c = pgn_content[loc];
+ while(c!='}'){
+ hm->comment+=c;
+ loc++;
+ EOF_CHECK(loc);
+ c = pgn_content[loc];
+ }
+ loc++; // Skip '}'
+ }
+ return(loc);
+}
+
int PGN::ParseHalfMove(int loc, HalfMove *hm) {
// Goto next char
loc = NextNonBlank(loc);
@@ -147,19 +170,8 @@ int PGN::ParseHalfMove(int loc, HalfMove *hm) {
return (loc);
}
- // Check for comment
- loc = NextNonBlank(loc);
- if (!IS_EOF(loc) && pgn_content[loc] == '{') {
- loc++; // Skip '{'
- c = pgn_content[loc];
- while (c != '}') {
- hm->comment += c;
- loc++;
- EOF_CHECK(loc);
- c = pgn_content[loc];
- }
- loc++; // Skip '}'
- }
+ // Parse comment
+ loc=ParseComment(loc,hm);
// Check for variations
loc = NextNonBlank(loc);
diff --git a/src/PGN.hpp b/src/PGN.hpp
index 6da955b..0f59bd0 100644
--- a/src/PGN.hpp
+++ b/src/PGN.hpp
@@ -47,6 +47,7 @@ private:
int NextNonBlank(int);
/// @brief Parse a HalfMove at a specific location into @a pgn_content
int ParseHalfMove(int, HalfMove *);
+ int ParseComment(int,HalfMove *);
};
struct UnexpectedEOF : public std::exception {
diff --git a/tests/tests.cpp b/tests/tests.cpp
index 551e9d4..f376f33 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -58,6 +58,7 @@ TEST_CASE("Valid PGN", "[valid/pgn1]") {
CHECK_THROWS_AS(pgn.GetTagValue("InvalidTagName"), InvalidTagName);
}
+ CHECK(m_backup->GetHalfMoveAt(4)->move == "c4");
CHECK(pgn.GetResult() == "*");
}
@@ -69,6 +70,8 @@ TEST_CASE("Valid PGN", "[valid/pgn2]") {
pgn.GetMoves(m);
REQUIRE(m->GetLength() == 66);
CHECK(pgn.GetResult() == "0-1");
+ CHECK(m->comment == " A00 Hungarian Opening ");
+ CHECK(m->GetHalfMoveAt(7)->comment == " (0.22 → 0.74) Inaccuracy. dxc4 was best. ");
}
TEST_CASE("Seven Tag Roster", "[std/pgn1]") {