Generic high-scores stuff:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
// highscores.hpp
#ifndef HIGHSCORES_HPP
#define HIGHSCORES_HPP
#include <iostream>
#include <string>
#include <vector>
namespace highscores
{
struct highscore
{
string playername;
unsigned score;
highscore( const unsigned& score = 0, const string& playername = string() ):
playername( playername ),
score( score )
{ }
};
bool operator < ( const highscore& left, const highscore& right );
bool operator == ( const highscore& left, const highscore& right );
istream& operator >> ( istream& ins, highscore& hs );
ostream& operator << ( ostream& outs, const highscore& hs );
class highscores: vector <highscore>
{
private:
unsigned f_count;
void validate();
public:
highscores( unsigned count = 10 ):
vector <highscore> ( count ),
f_count( count )
{ }
template <typename InputIterator>
highscores( InputIterator begin, InputIterator end );
unsigned count() const { return f_count; }
void count( unsigned newcount );
bool load( const string& filename );
bool save( const string& filename );
void push_back( const highscore& hs );
void push_back( unsigned score, const string& playername )
{
push_back( highscore( score, playername ) );
}
};
}
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// highscores.cpp
#include <algorithm>
#include <fstream>
#include <iterator>
using namespace std;
#include "highscores.hpp"
bool operator < ( const highscores::highscore& left, const highscores::highscore& right )
{
return left.score < right.score;
}
bool operator == ( const highscores::highscore& left, const highscores::highscore& right )
{
return left.score == right.score;
}
istream& operator >> ( istream& ins, highscore::highscore& hs )
{
ins >> hs.score;
ins >> ws;
getline( ins, hs.playername );
return ins;
}
ostream& operator << ( ostream& outs, const highscore::highscore& hs )
{
outs << hs.score << ' ' << hs.playername << endl;
return outs;
}
void highscores::validate()
{
sort( rbegin(), rend() );
if (size() > f_count) erase( begin() +f_count, end() );
}
template <typename InputIterator>
highscores::highscores( InputIterator begin, InputIterator end )
{
while (begin != end)
push_back( *begin++ );
f_count = size();
validate();
}
void highscores::count( unsigned newcount )
{
f_count = newcount;
validate();
}
bool highscores::load( const string& filename )
{
clear();
ifstream f( filename.c_str() );
if (!f) return false;
copy(
istream_iterator <highscore> ( f ),
istream_iterator <highscore> (),
back_inserter( *this )
);
f_count = size();
validate();
return f.good();
}
bool highscores::save( const string& filename )
{
validate();
ofstream f( filename.c_str(), ios::trunc );
if (!f) return false;
copy(
begin(),
end(),
ostream_iterator <highscore> ( f )
);
return f.good();
}
void highscores::push_back( const highscore& hs )
{
vector <highscore> ::push_back( hs );
validate();
}
|
Have fun!
(Yeah, I was bored. Oh, I just typed this in. Errors and typos may have occurred. Find any? Let me know and I'll fix them above.)
[edit] OK, some quick documentation.
load() loads the specified file. Check count() to see how many HS there were in that file.
save() overwrites the specified file.
count() is the
maximum number of entries. There may be fewer.
There is no reason why you can't use other methods inherited from vector.
push_back(), load(), and save() always sort the scores in non-ascending order and enforce the maximum count.
You don't actually have to supply a player name. (So, for
kartracer12, you can load your scores file, and save it:
1 2 3 4 5
|
highscores::highscores hs;
if (!hs.load( "highscore.txt" )) complain();
if (hs.count() != 1) complain();
if (hs[ 0 ].score < newscore) hs[ 0 ].score = 99;
hs.save( "highscore.txt" );
|
If you want more comparison operators, #include <utility> and say
using namespace rel_ops
.
The highscore constructor is not
explicit, so you should be able to compare highscores with integers. (But again, I haven't tested that...)
Hmm... that's all I can think of.
[edit] fixed typo