Sign in to follow this  

highscore structs

This topic is 4595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys decided to add a high scores list to my tetris clone, im having a few initial problems. I have the name and score read in from a file to a temporary struct this struct is then pushed into a stack. This is repeated 10 times. Everything seems to compile but im not sure how to access the struct members in the stack. heres the code i have for the function:
struct HScores //structure for scores and names
{
       char name[3];
       int score;
};

stack<HScores> HighScoreStack; //stack to put 10 HScore structs into


void HighScores() //function to handle the highscores
{

    ifstream input("scores.dat"); //file to read in from
    for (int m = 0; m < 10; ++m)
    {
      HScores SBuffer;
      input >> SBuffer.name;
      input >> SBuffer.score;
      HighScoreStack.push(SBuffer);
    }
      
      input.close();
}



Im unsure if this is even working as im not sure how to access the members. anyhelp appreciated lone

Share this post


Link to post
Share on other sites
Pop it into a buffer and access it from there. Seems a bit overkill, though, I'd just use a normal array. Access everything directly. No overhead for the pop/push functions. Meh.

Share this post


Link to post
Share on other sites
i want to be able to sort the scores by top score ect, could i do that with a normal array? also i havnt really worked with structs and stacks before could you give me a quick example of how to acces one of them ?

cheers
lone

Share this post


Link to post
Share on other sites
Yeah, you could do manual sorting on an array.

Anyways, to access the struct in the stack I'd do:

//pseudo code
struct foo{
int x;
int y;
}

stack<foo> foostack;

// Push stuff on somewhere in here.


// Now to get it off
foo bar;
bar = foostack.pop();
cout << bar.x << " " << bar.y;

Share this post


Link to post
Share on other sites
And for sorting on an array, here's the bubble sort. Hugely inefficient, but simple to program, and doesn't really matter how bad it is, if it's used on an array of 10.

for(x = 0; x < ARRAY_SIZE; x++)
for(y = 0; y < ARRAY_SIZE-1; y++)
if(iarray[y] > iarray[y+1]) {
holder = iarray[y+1];
iarray[y+1] = iarray[y];
iarray[y] = holder;
}


You could look it up on wikipedia if you wanted to know how it works.

Share this post


Link to post
Share on other sites
Oh, and come to think of it, you wouldn't want to use a stack if you're going to sort. A stack's entire purpose is first in last out. Unless you're loading the scores in the opposite order of how you want to read them, it doesn't make much sense.

Share this post


Link to post
Share on other sites
When I did a high score table I used a list<> of structures. That way inserting new scores, when a new high score is achieved, in the middle of the list is easy.

Also, if the high score file is always in order then you'll read them a line at a time, construct your stucture and push_back() onto the list, so the high scores should always be in order...:)

Share this post


Link to post
Share on other sites
If you are only going to have 10 high scores then skip the stack
and just do an array. Why write a pop, push, insert, delete etc...
for something so simple?

Create an array of structs
Read in from a high score text file (already sorted)
At the end of a game check

if (currentScore > highScore[9]) // if current score is greater
{ // than the lowest high score

highScore[9] = currentScore; // replace lowest score with current score

sortArray(); // sort the array to put new
// score into correct position

writeToHighScoreTextFile(); // writes new sorted high scores to
// the text file; or you could do this
// when the player quits the game
}

Share this post


Link to post
Share on other sites
the main problem im having is i want to have the player names in the array also, would it be better to just have 2 arrays one with names and one with scores? im unsure how id get a name and a number into an array that are somehow related to each other but only sorting by the highscore. that was my main reason for the structs. any ideas? :|

Share this post


Link to post
Share on other sites
Quote:
Original post by Lonefox1
the main problem im having is i want to have the player names in the array also, would it be better to just have 2 arrays one with names and one with scores? im unsure how id get a name and a number into an array that are somehow related to each other but only sorting by the highscore. that was my main reason for the structs. any ideas? :|


if i understand your question, you can have an array of structs. then you can sort by highscore[i].score for example.

Share this post


Link to post
Share on other sites
I made a highscore wrapper using TinyXML and some encryption a while ago. Let me see if I can find it.... Here it is:

highscorelist.h
#if !defined(_HIGHSCORELIST_H_)
#define _HIGHSCORELIST_H_

#include <string>
#include <vector>

namespace System{
namespace File{

// TODO Descending order

class HighScoreItem{
public:
std::string Name;
int Score;
HighScoreItem(std::string name, int score) : Name(name), Score(score) { }
};

class HighScoreList{
public:
bool Load(std::string Filename);
bool Save(std::string Filename, int NumberOfRecords = -1);
int AddRecord(std::string Name, int Score);
void ClearList();
std::string Name(int Position);
int Score(int position);
~HighScoreList(){
ClearList();
}
HighScoreList() : m_descending(true), m_key("lucid") {

}
void Sort();

int NumberOfRecords(){ return list.size(); }
bool DescendingOrder(bool desc){ m_descending = desc; Sort(); return m_descending; }
bool DescendingOrder(){ return m_descending; }

std::string Key(){ return m_key; }
std::string Key(std::string key){ return m_key = key; }

private:
std::vector<HighScoreItem*> list;
bool m_descending;
std::string m_key;
};

}
}

#endif



highscorelist.cpp
#include "highscorelist.h"

#include "tinyxml/tinyxml.h"
#include "file.h"
#include "../text/encoding.h"

#include <string>
#include <vector>
#include <algorithm>
#include <sstream>

namespace System{
namespace File{



bool HighScoreItem_comp(HighScoreItem* i1, HighScoreItem* i2){
return (i1->Score > i2->Score);
}

bool HighScoreItem_comp2(HighScoreItem* i1, HighScoreItem* i2){
return (i1->Score < i2->Score);
}

void HighScoreList::Sort(){
if(m_descending)
std::sort(list.begin(), list.end(), HighScoreItem_comp);
else
std::sort(list.begin(), list.end(), HighScoreItem_comp2);
}

bool HighScoreList::Load(std::string Filename){
std::string filecontents;
if(System::File::DecryptFromFile(Filename,filecontents,m_key)){
if(filecontents == "") return true;

TiXmlDocument doc;
try{
doc.Parse(filecontents.c_str());
if(doc.Error())
return System::File::WriteContents(Filename,"");
} catch(std::exception a){
return System::File::WriteContents(Filename,"");
}

TiXmlHandle docHandle( &doc );
TiXmlElement* child = docHandle.FirstChild("record").Element();
for( child; child; child=child->NextSiblingElement() )
AddRecord(child->Attribute("name"), System::Text::ToInteger(child->Attribute("score")));

return true;
}
return System::File::WriteContents(Filename,"");

}

bool HighScoreList::Save(std::string Filename, int NumberOfRecords){
if(NumberOfRecords == 0) return true;
std::stringstream output;

if(NumberOfRecords < 0){
for(std::vector<HighScoreItem*>::iterator pos = list.begin(); pos != list.end(); pos++){
output << "<record name=\"" << (*pos)->Name << "\" score=\"" << (*pos)->Score << "\"/>";
}
} else {
for(std::vector<HighScoreItem*>::iterator pos = list.begin(); pos != list.end(); pos++){
if(NumberOfRecords-- > 0)
output << "<record name=\"" << (*pos)->Name << "\" score=\"" << (*pos)->Score << "\"/>";
else
break;
}
}
std::string s = output.str();
return System::File::EncryptToFile(Filename, s, m_key);
}

std::string HighScoreList::Name(int Position){
try{
HighScoreItem* item = list.at(Position);
return item->Name;
}catch(std::exception a){
return "Nobody";
}
}
int HighScoreList::Score(int Position){
try{
HighScoreItem* item = list.at(Position);
return item->Score;
}catch(std::exception a){
return 0;
}
}

int HighScoreList::AddRecord(std::string Name, int Score){
list.push_back(new HighScoreItem(Name, Score));
Sort();
}

void HighScoreList::ClearList(){
while(!list.empty()){
delete list.back();
list.pop_back();
}
list.clear();
}

}
}




It uses some of the other backbone from the engine, but it's easy to understand what it's doing. Enjoy.

Share this post


Link to post
Share on other sites

This topic is 4595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this