Jump to content
  • Advertisement
Sign in to follow this  
Ekim_Gram

Problem with my high score board

This topic is 4876 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

New problem down below Alright, to start off I'm just polishing up my Tetris clone. I'm currently working on a high score board and everything is going well except for one small problem - scores that are not higher than the top one are not added to the board. I have the following struct:
struct SHigh_Score
{
	int Lines;
	int Rank;
	int Score;
};
And the following function whenever the score board is accessed (note, the global int Score is initially set to 0 at the beginning of the game)
bool AddHighScore()
{
	// First copy all the scores to the High_Scores[] array
	GetHighScores();
	int position=0;
	bool looping = true;
	// Loop through the list and check if the current score can make the list
	while (looping)
	{
		if (Score > High_Scores[position].Score)
		{
			// Score is greater, terminate the loop
			looping = false;

			// Now make a temp list and copy all the scores higher than the score stored at
			// [position]
			SHigh_Score Temp_Scores[10];
			for (int i=0; i<position; i++)
			{
				Temp_Scores.Lines = High_Scores.Lines;
				Temp_Scores.Rank = i+1;
				Temp_Scores.Score = High_Scores.Score;
			}

			// Now put in the new score
			Temp_Scores[position].Lines = Lines;
			Temp_Scores[position].Rank = position+1;
			Temp_Scores[position].Score = Score;

			// Ok, now that's done. Next we gotta take the rest of the list from [position] on
			// until 10 and add it to the list.
			for (int i=position+1; i<10; i++)
			{
				Temp_Scores.Lines = High_Scores[i-1].Lines;
				Temp_Scores.Rank = i+1;
				Temp_Scores.Score = High_Scores[i-1].Score;
			}

			// Almost there! All that needs to be done is to write it all to the highscores file
			// But first, you have to clear the file
			std::ofstream fout;
			fout.open("data/bin/highscores.dat",std::ios::binary);
			fout.close(); 
			for (int i=0; i<10; i++)
			{
				WriteHighScoreToFile(Temp_Scores);
			}

			// And all that's left is to close the loop
		}
		position++;
		return true;
	}
	return false;
}


I went through it twice, wrote everything out on paper but unfortunately I am unable to find the problem. Help is greatly appreciated.
[Edited by - Ekim_Gram on June 16, 2005 10:49:32 AM]

Share this post


Link to post
Share on other sites
Advertisement
It might have to do with your having a "return true;" statment at the end of the loop, so the loop will only ever execute once.

Share this post


Link to post
Share on other sites
You might also want to consider a more efficient algorithm. You're doing a lot of unnecessary looping shifting the scores down when one needs to be inserted.

Consider the following:

bool AddHighScore()
{
// First copy all the scores to the High_Scores[] array
GetHighScores();
int position=0;

// find a score higher than Score
while(High_Scores[position].Score < Score && position < 10)
{
position++;
}

// if position > 0, then we have a new high score
if(0 < position)
{
// move everything below position down one spot, if position > 1
if(position > 1)
{
memcpy(High_Scores, High_Scores+1, sizeof(SHigh_Score)*(position-1));

// re-sequence the "Rank".. though I'm not sure this even needs to be part
// of the SHigh_Score struct.
for(int nPos=0; nPos < position-1; nPos++)
High_Scores[nPos].Rank = nPos+1;
}

// insert the new score into position
High_Scores[position-1].Score = Score;
High_Scores[position-1].Rank = position;
High_Scores[position-1].Lines = Lines;

//
// save your high-score file here.
//
return true;
}

return false;

}








[Edited by - pragma Fury on June 15, 2005 10:12:25 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by pragma Fury
You might also want to consider a more efficient algorithm. You're doing a lot of unnecessary looping shifting the scores down when one needs to be inserted.

Consider the following:
*** Source Snippet Removed ***


Here's my modified version of your method:


bool AddHighScore()
{
// First copy all the scores to the High_Scores[] array
GetHighScores();
int position=0;

// find a score higher than Score
while(High_Scores[position].Score < Score && position < 10)
{
position++;
}

// if position > 0, then we have a new high score
if(position > 0)
{
// move everything below position down one spot, if position > 1
if(position > 1)
{
memcpy(&High_Scores[position].Lines, &High_Scores[position+1].Lines, sizeof(SHigh_Score)*(position-1));
memcpy(&High_Scores[position].Rank, &High_Scores[position+1].Rank, sizeof(SHigh_Score)*(position-1));
memcpy(&High_Scores[position].Score, &High_Scores[position+1].Score, sizeof(SHigh_Score)*(position-1));
}

// insert the new score into position
memcpy(&High_Scores[position-1].Score, &Score, sizeof(SHigh_Score));

// Save it all
std::ofstream fout;
fout.open("data/bin/highscores.dat",std::ios::binary);
fout.close();
for (int i=0; i<10; i++)
{
WriteHighScoreToFile(High_Scores);
}
return true;
}

return false;
}



All this does it set the higher score to 10th place. Ranks 1st through 9th are all just set to the default values.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hmm, sounds like a good place to use Priority_Queues, as I believe they auto-sort to be largest to smallest. I know for sure they always put the largest item at the top, not sure if it sorts the rest though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ekim_Gram
Quote:
Original post by pragma Fury
You might also want to consider a more efficient algorithm. You're doing a lot of unnecessary looping shifting the scores down when one needs to be inserted.

Consider the following:
*** Source Snippet Removed ***


Here's my modified version of your method:

*** Source Snippet Removed ***

All this does it set the higher score to 10th place. Ranks 1st through 9th are all just set to the default values.


So.. the highest score goes in the 10th array position? That's what my code did.
Further, not only will your code not work as advertised, it will cause EAccessViolations.
Why are you copying the lines,ranks, and scores separately, as though they were individual arrays, and using the sizeof(SHigh_Score), when they're ints?

I'm really not sure at all what your goal is here.

Regarding the original problem, Is there a reason why "Rank" is a part of your SHigh_Score struct? It seems pretty much implied by the score's position in the High_Scores array.


Share this post


Link to post
Share on other sites
Ok, I redid some things and I'm going to state the new problem - With the code pragma Fury gave me, the highest score is placed in the 10th array position. I don't want that, it should be the first. I have the following struct:


struct SHigh_Score
{
int Lines;
int Score;
};


and the following function:


bool AddHighScore()
{
// First copy all the scores to the High_Scores[] array
GetHighScores();
int position=0;

// find a score higher than Score
while(High_Scores[position].Score < Score && position < 10)
{
position++;
}

// if position > 0, then we have a new high score
if(position > 0)
{
// move everything below position down one spot, if position > 1
if(position > 1)
{
memcpy(&High_Scores[position].Lines, &High_Scores[position+1].Lines, sizeof(int));
memcpy(&High_Scores[position].Score, &High_Scores[position+1].Score, sizeof(int));
}

// insert the new score into position
memcpy(&High_Scores[position-1].Score, &Score, sizeof(int));

// Save it all
std::ofstream fout;
fout.open("data/bin/highscores.dat",std::ios::binary);
fout.close();
for (int i=0; i<10; i++)
{
WriteHighScoreToFile(High_Scores);
}
return true;
}

return false;
}



I can't figure out how to set it so that the highest score is at High_Scores[0] rather than High_Scores[1]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Try this: (copied from my own tetris clone that I made a while back :) )


You had an array of 10 scores:

struct high_score
{
int score; int lines;
}

high_score scores[10];


Then when the game ended:


for(int i = 0; i < 10; i++)
if(current_score > scores.score)
{
//Move all the lower scores down
for(j = 8; j >= which_score; j--)
scores[j+1] = scores[j];

scores.score = current_score;
scores.lines = current_lines;
break;
}


Share this post


Link to post
Share on other sites
Okay, first there is this:

// find a score higher than Score
while(High_Scores[position].Score < Score && position < 10)
{
position++;
}


What this does is increase position by one while High_Scores[position].Score is less than Score. What you want is to increase position while High_Scores[position].Score is greater than Score.

// find a score higher than Score
while(High_Scores[position].Score > Score && position < 10)
{
position++;
}


Next there is this piece of code:

if(position > 0)
{
...

I don't understand this at all. Presuming you have made the change I suggested above, if Score was greater than High_Scores[0].Score then position would have a value of 0 (as it would be the new high score).
Change this to:

if(position < 10)
{
...


Well...that code is actually quite horrible but I think I pointed out some of the problems you were having. Try this on for size, it's just a modified version of your current code that actually works.


bool AddHighScore()
{
// First copy all the scores to the High_Scores[] array
GetHighScores();
int position=0;

// find a score higher than Score
while(High_Scores[position].Score > Score && position < 10)
{
position++;
}

// if position <10, then we have a new high score
if(position <10)
{
// shift the high scores down
for(int p=9; p>position; p--)
{
memcpy(&High_Scores

, &High_Scores[p-1], sizeof(SHigh_Score));
}

// insert the new score
High_Scores[position].Score = Score;
High_Scores[position].Rank = Rank;
High_Scores[position].Lines = Lines;

// Save it all
std::ofstream fout;
fout.open("data/bin/highscores.dat",std::ios::binary);
for (int i=0; i<10; i++)
{
WriteHighScoreToFile(High_Scores);
}
fout.close();

return true;
}

return false;
}




[Edited by - MrP on June 16, 2005 3:22:56 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!