Click here to Skip to main content
15,885,365 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm trying to create a leaderboard, but here's what I have so far and I'm a bit stuck.
class utilizeLeaderboard
    {

        string mode;
        bool gameover;

        string playername;
        int playerscore;

        StreamReader sreader;
        StreamWriter swriter;

        List<string> playernames = new List<string>();
        List<int> playerscores = new List<int>();
         //Not sure why it doesn't have a type, just followed an example.
        ArrayList highlist = new ArrayList();
        


        public utilizeLeaderboard(string name, int score)
        {
            //new information to be supposedly added to highlist to be sorted with the rest of the stored scores (from the .txt file)
            playername = name;
            playerscore = score;



        }

        public void setType(string s)
        {
            mode = s;
            gameover = true;
        }

        void loadScores()
        {
            switch (mode)
            {
                case "Endless":
                    sreader = new StreamReader(@"C:\Users\Endless.txt");
                    //load player names
                    //load player scores
                    //add to highlist to be sorted together with the newly added info - playername & playerscore
                    break;
                case "Timed":
                    sreader = new StreamReader(@"C:\Users\Timed.txt");
                    break;
                case "Moves":
                    sreader = new StreamReader(@"C:\Users\Moves.txt");
                    break;
                    
            }
        }

        void evaluateScores()
        {
            //sort highlist

            playernames.Add(playername);
            playerscores.Add(playerscore);

            for (int u = 0; u < playernames.Count; u++)
            {
                //Not sure yet how this part works, just followed an example. 
                //Maybe some kind soul can explain how it works?
                highlist.Add(new utilizeLeaderboard(playernames[u], playerscores[u]));
            }
        }

        void writeScores()
        {
            //write sorted highlist to .txt file

            switch (mode)
            {
                case "Endless":
                    swriter = new StreamWriter(@"C:\Users\Endless.txt");
                    //load player names
                    //load player scores
                    //add to highlist to be sorted together with the newly added info - playername & playerscore
                    //for (int u = 0; u < highlist.Count; u++)
                    //{
                    //    swriter.Write(playernames[u]+ " " + playerscores[u] + Environment.NewLine);
                    //}
                    break;
                case "Timed":
                    swriter = new StreamWriter(@"C:\Users\Timed.txt");
                    break;
                case "Moves":
                    swriter = new StreamWriter(@"C:\Users\Moves.txt");
                    break;

            }
        }
        
    }


1. How will I sort the scores but making sure that each score doesn't lose the name of the player owning it?
2. Java has the hasNext() which can be used to check if you have reached the last line,read.Next() for reading only string and read.NextInt() for reading only int. What are their equivalents in C#? I will be using them to read the scores from the .txt file, as the format of the information in the txt file will be like this:
John 23
Anne 29
Peter 21
3. Can you drop a few hints on some possible ways on how the program can sort the scores from highest to lowest?
4. Why doesn't highlist have a type? Sorry that sounds stupid, I just followed an example.
5. If ever I'm wrong in some of my assumptions, feel free to point them out. :)
Posted
Updated 28-Sep-14 23:22pm
v5
Comments
Sinisa Hajnal 29-Sep-14 5:23am    
Don't use two lists. Make Player class that contains both name and score and make a list of players...then sorting and keeping names together becomes non-issue
BillWoodruff 29-Sep-14 5:44am    
I think you're making good progress in adapting to C#, and I think you are at the place where you could focus on the overall object structure of your game ... time to start thinking of a "Player" as a Class, or struct, etc. To think of your Application as a "collection of Games" where a 'Game is a Class containing a List of Players, a score, etc.

If I have time today, I will respond with an example I hope will give you some ideas.

'ArrayList is the hold-anything-of-any-Type data structure that was available from the first versions of .NET; it is much better, now, to use strongly typed generic collections.
kmllev 29-Sep-14 5:54am    
Thank you, Bill!
Yes, I would greatly appreciate an example, as the one I have now confuses me (actually with the code above, I followed the pattern of the example I have, but admittedly I am confused by how some of its parts work).
And with the public utilizeLeaderboard, that's simply the constructor (as I have followed from the example I have).
And with regards to the ArrayList, thank you for that, I'm confident I will understand it much much better why I should opt for typed generic collections with the example you will give me.
BillWoodruff 29-Sep-14 6:29am    
Okay, my bad: I didn't see (not enough caffeine yet ?) that 'utilizeLeaderBoard was the Class name.

I'd really like to see you get started implementing/modeling your Application as a container for a collection of 'Games and all the necessary "state" information that you need to access, and to design a specific 'Game Class, creating appropriate Public Properties for all the attributes you think could be necessary/useful. The goal is to end-up with a solid object-oriented design that can be easily serialized, and de-serialized, can be easily sorted, analyzed by any criteria you can imagine, or need.

If you are taking a class in school, however, it may be better to wait until the focus is on object-oriented design ... it all depends on the class, and the instructor.
kmllev 29-Sep-14 6:46am    
I'll try my best, Bill, but I really can't promise anything.
Yes, I am taking a class in school, but they only teach the fundamentals, and it's up to us to learn about the rest. We haven't done an in-depth discussion of the OOP concepts (and I don't think where going to), just an overview. I'd buy a book but I have limited budget as of the moment so it's not really an option.
Nevertheless, I'm still counting on that example! I'm pretty sure it'd help me give some ideas on how I can solve the problem with a better (and hopefully easier) approach.

Hi,
I find it a little strange to use text files to store data that is serializable.
Why don't you use XML files for example and take advantage of the OO capabilities of .Net classes.
I believe it will be more convenient in your situation to use it.

Anyways for sorting purposes I found this article useful, hope it helps you:

Sorting Algorithms In C#[^]
 
Share this answer
 
Comments
kmllev 29-Sep-14 5:46am    
Thank you!
I'm only beginning to learn C# so my instructor advised to use .txt files for now, until we get into the deeper parts of the language :)
Re the issue asked about in the title of the question:

1. Assumes the delimiter character is a comma.

2. illustrates some elementary error-checking and reporting, use of 'throw, etc. but, by no means thoroughly checks the file being read for correctness.
C#
private Dictionary<string, int> PlayerHighScores = new Dictionary<string, int>();

// for testing only
private string baseFilePath = @"C:\Users\Uruk\Desktop\";

// for testing only
private string mode = "Endless";

private void loadScores()
{
    // clear the Dictionary
    PlayerHighScores.Clear();

    // to use in splitting lines in the file
    char[] splitChars = new char[] {','};

    // to hold the result of splitting the line
    string[] splitLine = new string[2];

    string line;

    int testInt = 0;

    // should you check to make sure the value of 'mode is valid here
    // and throw an error if it is not valid ?

    using (StreamReader sReader = new StreamReader(baseFilePath + mode + ".txt"))
    {
        int lineCount = 0;

        while (! sReader.EndOfStream)
        {
            lineCount++;

            line = sReader.ReadLine();

            try
            {
                splitLine = line.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);

                string playerName = splitLine[0];

                // valid score data ?
                if (! Int32.TryParse(splitLine[1], out testInt))
                {
                    throw new ArgumentException(message: "bad entry for score in line: " + lineCount.ToString());
                }

                // add the new data to the Dictionary
                PlayerHighScores.Add(splitLine[0], testInt);
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine("Invalid line in High Score file in line:" + lineCount.ToString());
            }
        }
    }
}
Here's a demonstration of using Linq to return the scores ordered from highest to lowest:
C#
List<int> highScores = PlayerHighScores.Values.OrderByDescending(s => s).ToList();
 
Share this answer
 
v3
Comments
kmllev 29-Sep-14 9:43am    
Just what I've been looking for. You're the best, Bill, thank you!
Roberta Mafessoni 2-Oct-14 7:14am    
Pretty Straight-Forward Solution. Thanks from me too.
1. You can use Dictionary for storing user score with their name as keys and scores as values.

For Storing operation check below link or try googling for sorting operation on dictionary object.

http://www.dotnetperls.com/sort-dictionary[
title="New Window">^
]
 
Share this answer
 
Comments
kmllev 29-Sep-14 5:25am    
I will look into that, thank you!
Hi,

You can read the file in a string array with File.ReadAllLines(yourfilenamehere);.
Then create a class which encapsulates a player.
Create two fields into it: name (string) and points (int or float or whatever numeric type you want).
Make the class implements IComparable
You will now have this method
C#
int CompareTo(object other){

}


Inside it declare a variable of type Player and make the object other of that type (with the as operator)

Then try to compare the istances and return -1 if the other player has to be before (come before in the leaderboard) the player encapsulated by your class, 0 if they have the same place, 1 if the player encapsulated by your class must come before the player represented by other. Hint: compare the points fields with if statements.

You can now convert your string array into a players array with some string tricks (string static class is helpful).

Then sort the array you've found with the method Sort of the array class (I.E. <yourarray>.Sort())

Use the array in whatever method you want.

Make your class override ToString method and write into it:
return this.name + " " + this.points;

Reconvert your array to a string array, or list, by using a foreach loop And the tostring method you created.

If you've chosen to use a list, convert the list to a string array and use File.WriteAllLines(yourstringarray) to rewrite your file.


This is a solution which I think is the most compatible with your code, but there is another:
You can use serialization.
Create a custom list which implements ISerializable class and use it instead of the string array in the upper solution. Use serialization to create streams and the StreamWriter to write the stream, but, as I've understood, those files are already existant and you need to convert them before start using serialization.

Hope this helped.

LG
 
Share this answer
 
You can use the TextReader TextWriter classes instead of StreamReader/Writer.
 
Share this answer
 
Comments
LLLLGGGG 29-Sep-14 5:30am    
Actually the File static class is more handy to do this type of work with light files.
:)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900