|
From: Markus R. <god...@us...> - 2009-07-29 15:35:13
|
Module: performous
Branch: master
Commit: 7e7937546cee1ef1aaebe1a137584dd9ba10ff3e
Author: Markus Raab <un...@ma...>
Date: Thu Jul 23 10:42:16 2009 +0200
highscore implementation
---
game/.gitignore | 3 ++
game/highscore.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++
game/highscore.hh | 27 ++++++++++++++
3 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/game/.gitignore b/game/.gitignore
new file mode 100644
index 0000000..6899cb8
--- /dev/null
+++ b/game/.gitignore
@@ -0,0 +1,3 @@
+.ctags
+Makefile
+highscore.txt
diff --git a/game/highscore.cc b/game/highscore.cc
new file mode 100644
index 0000000..8c67110
--- /dev/null
+++ b/game/highscore.cc
@@ -0,0 +1,102 @@
+#include "highscore.hh"
+#include <boost/lexical_cast.hpp>
+
+#include "unicode.hh"
+
+#include <fstream>
+#include <sstream>
+
+HighScore::HighScore (std::string const& path_, std::string const& filename_) :
+ m_path(path_),
+ m_filename(filename_)
+{
+ std::ifstream in((m_path + m_filename).c_str());
+
+ if (!in.is_open()) throw HighScoreException("Could not open highscore file", 0);
+
+
+ in.seekg(0, std::ios::end);
+ size_t size = in.tellg();
+ if (size < 10 || size > 100000) throw HighScoreException("Does not look like a highscore file (wrong size)", 1);
+ in.seekg(0);
+
+ std::vector<char> data(size);
+ if (!in.read(&data[0], size)) throw HighScoreException("Unexpected I/O error", 0);
+
+ std::stringstream ss;
+ ss.write(&data[0], size);
+
+ convertToUTF8(ss, m_path + m_filename);
+
+ // now parse line by line and build up highscore
+ std::string str;
+ unsigned int linenum = 0;
+ unsigned int playernum = 0;
+ while (std::getline(ss, str))
+ {
+ if (str == "E") break;
+ linenum++;
+ if (playernum > 9) throw HighScoreException("Not more than 10 highscores expected in file", linenum);
+ if (str.empty()) continue; // ignore empty player lines
+ if (str.length() <= 9) throw HighScoreException("Line not long enough for player information", linenum);
+
+ if (str[0] != '#') throw HighScoreException("No # found at begin of line", linenum);
+ if (str.substr(1,6) != "PLAYER") throw HighScoreException("Expected PLAYER not found", linenum);
+
+ unsigned int nr = str[7];
+ if (nr != playernum + '0') throw HighScoreException("Did not find correct playernum", linenum);
+ if (str[8] != ':') throw HighScoreException("Did not find :", linenum);
+
+ std::string name = str.substr(9, str.length()-9);
+ if (name.empty()) throw HighScoreException("Did not find name", linenum);
+ std::cout << "name: " << name << std::endl;
+ m_names.push_back(name);
+
+ std::getline(ss, str);
+ linenum++;
+ if (str.empty()) throw HighScoreException("Expected Score, but found empty line", linenum);
+ if (str.length() <= 8) throw HighScoreException("Line not long enough for score information", linenum);
+
+ if (str[0] != '#') throw HighScoreException("No # found at begin of line", linenum);
+ if (str.substr(1,5) != "SCORE") throw HighScoreException("Expected SCORE not found", linenum);
+
+ nr = str[6];
+ if (nr != playernum + '0') throw HighScoreException("Did not find correct playernum", linenum);
+ if (str[7] != ':') throw HighScoreException("Did not find :", linenum);
+
+ std::string score = str.substr(8, str.length()-8);
+ if (score.empty()) throw HighScoreException("Did not find score", linenum);
+ std::cout << "score: " << score << std::endl;
+
+ try {
+ double dscore = boost::lexical_cast<int>(score) / 10000.0;
+ if (dscore < 0.0 || dscore > 1.0) throw HighScoreException("Number not between 0 and 10000", linenum);
+ if (playernum>0 && m_scores.back() < dscore) throw HighScoreException("Lower ranked highscore is higher", linenum);
+ m_scores.push_back(dscore);
+ } catch (boost::bad_lexical_cast const& blc)
+ {
+ throw HighScoreException("Did not find valid double number", linenum);
+ }
+
+ playernum++;
+ }
+}
+
+HighScore::~HighScore()
+{}
+
+/*
+#include <iostream> // TODO debug
+
+int main()
+{
+ try {
+ HighScore hi ("", "highscore.txt");
+ } catch (HighScoreException const& hie)
+ {
+ std::cerr << "Exception: " << hie.what()
+ << " at line: " << hie.line()
+ << std::endl;
+ }
+}
+*/
diff --git a/game/highscore.hh b/game/highscore.hh
new file mode 100644
index 0000000..5f4d766
--- /dev/null
+++ b/game/highscore.hh
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <stdexcept>
+
+struct HighScoreException: public std::runtime_error {
+ HighScoreException (std::string const& msg, unsigned int linenum) :
+ runtime_error(msg), m_linenum(linenum)
+ {}
+ unsigned int line() const {return m_linenum;}
+ private:
+ unsigned int m_linenum;
+};
+
+class HighScore {
+ public:
+ HighScore (std::string const& path_, std::string const& filename_);
+ ~HighScore ();
+
+ void save();
+ private:
+ std::string m_path;
+ std::string m_filename;
+ std::vector <std::string> m_names;
+ std::vector <double> m_scores;
+};
|