0

I have been making a quiz for a while now, and wanted to implement a leader board. The leader board should show the name of the user, score

I have checked to see if it is recognising the file and when I remove the score it works fine. The score works fine when I am displaying it on a label in all the other forms.

public partial class frmLeaderboard : Form {enter code here //Setup player list List players = new List();

    public frmLeaderboard()
    {
         //Setup form
         InitializeComponent();
         dgLeaderboard.ColumnCount = 3;
         dgLeaderboard.Columns[0].Name = "Player Name";
         dgLeaderboard.Columns[1].Name = "Score"; 
         dgLeaderboard.Columns[2].Name = "Level";
         SaveScores();
         GetPreviousPlayers();
    }

    private void GetPreviousPlayers()
    {
        //searches for file and loads score
        if(File.Exists("previousplayers.txt"))
        {
            LoadScores();
        }

        dgLeaderboard.Sort(dgLeaderboard.Columns[1], ListSortDirection.Descending);
    }

    private void LoadScores()
    {
        if (File.Exists("previousplayers.txt"))
        {
            //Loads the score
            var playerScores = File.ReadAllLines("previousplayers.txt");

            if (playerScores.Length > 0)
            {
                //bring in the players to the grid
                foreach (var players in playerScores)
                {
                    var splitDetails = players.Split('~');
                    dgLeaderboard.Rows.Add(splitDetails[0], Convert.ToInt32(splitDetails[0]), splitDetails[2]);
                }
            }

            else
            {
                HideGrid();
            }
        }
    }

    private void SaveScores()
    {
        FileStream fileStream = new FileStream("previousplayers.txt", FileMode.Append, FileAccess.Write);
        StreamWriter streamWriter = new StreamWriter(fileStream);

        //Seperate the username, score and level
        try
        {
            foreach(var player in players)
            {
                streamWriter.WriteLine(player.Username + "~" + player.Score + "~" + player.Level);
            }
        }
        catch(Exception)
        {
            MessageBox.Show("Error Loading the scores", "Please try again");
        }
        finally
        {
            streamWriter.Close();
            fileStream.Close();
        }

    }

    private void HideGrid()
    {
        //Sets the grid to invisible
        dgLeaderboard.Visible = false;
    }



}

In the form before I use this code

string filePath = "previousplayers.txt";
        FileStream aFile;
        StreamWriter sw;

        try
        {`enter code here`
            if (!File.Exists(filePath))
            {
                aFile = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            }
            else
            {
                aFile = new FileStream(filePath, FileMode.Append, FileAccess.Write);
            }

            sw = new StreamWriter(aFile);
            sw.WriteLine(frmStart.Player.Username + "~" + frmStart.Player.Score + "~" + frmStart.Player.Level);
            sw.Close();
            aFile.Close();

        }
        catch (Exception ex)
        {
            MessageBox.Show("User's details have not been saved", "Error Occurred");
        }

It crashes with the error: Exception Unhandled, System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

at this line dgLeaderboard.Rows.Add(splitDetails[0], Convert.ToInt32(splitDetails[0]), splitDetails[2]);

Blockquote

2
  • That error happens because you presented an index to the array indexer that was too large (>=array size) or a negative number. Commented Feb 5, 2019 at 21:26
  • Also, note that you don't need to check File.Exists(filePath). FileMode.Append will create the file if it doesn't exist. + Convert.ToInt32(splitDetails[0]): splitDetails[0] is a string here, containing player.Username, since: streamWriter.WriteLine(player.Username + "~" (...). Unless you're mixing different versions of the procedure. Commented Feb 5, 2019 at 21:55

1 Answer 1

1

You're writing the player scores this way:

player.Username + "~" + player.Score + player.Level

So if you're reading it and splitting it on ~, you'll get an array with a length of 2, where [0] is player.Username and [1] is player.Score + player.level. You're trying to access index [2], which is out of bounds.

Sign up to request clarification or add additional context in comments.

5 Comments

Hmm i added that extra "~" between and same error shows
Did you remember to delete the old file after changing the format? Otherwise, even though the new lines are correctly formatted, parsing the old lines will still throw.
Also, isn't it a mistake that you're trying to write the username to both the first and the second column? I'd think it should be dgLeaderboard.Rows.Add(splitDetails[0], Convert.ToInt32(splitDetails[1]), splitDetails[2]);
that must of been a mistake typing here, because it is like that in my code
Excellent, glad to hear it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.