Search code examples
listunity-game-enginestreamreaderstreamwriter

Unity Iterate over a list to sort by the number value


I have a text file called highscore.txt and I know the format of the data going into the file which works in the following way:

Username:score

I then need to search through the whole file to see where the new score needs to be added such that the file is in order of score from largest to smallest

    List<string> tempoaryList = new List<string>();
    List<int> valueList = new List<int>();
    string lineValues = "";

    using (StreamReader sr = new StreamReader(finalPath))
    {
        while (sr.EndOfStream == false)
        {
            lineValues = sr.ReadLine();
            tempoaryList.Add(lineValues);
            int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
            valueList.Add(data);
        }

    }
    valueList.Sort();
    for(int i =0; i > valueList.Count; i++)
    {
        if(valueList[i] <= playerScore)
        {
            tempoaryList.Insert(i - 1, playerScore.ToString());
        }
    }
    using (StreamWriter sw = new StreamWriter(finalPath, false))
    {
        for (int i = 0; i < tempoaryList.Count; i++)
        {
            sw.WriteLine(tempoaryList[i]);
            Debug.Log(tempoaryList[i]);
        }
    }

The above just simply doesn't change the text file and leaves it as it was found, any ideas of what I am doing wrong?


Solution

  • You should change your code to this:

    ScoreList.cs

    using UnityEngine;
    using System;
    using System.IO;
    using System.Collections.Generic;
    
    public class ScoreList : MonoBehaviour {
    
        private void Start() {
            GameOver.GameOverEvent += UpdateScoreBoardFile;
        }
    
        private void UpdateScoreBoardFile(string playerName, int playerScore) {
            string lineValues;
            string finalPath = "[ScoreBoard File Location]";
            List<string> tempoaryList = new List<string>();
            List<int> valueList = new List<int>();
            bool isScoreLowest = true;
    
            using (StreamReader sr = new StreamReader(finalPath)) {
                while (sr.EndOfStream == false) {
                    lineValues = sr.ReadLine();
                    tempoaryList.Add(lineValues);
                    int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
                    valueList.Add(data);
                }
            }
    
            if (tempoaryList != null) {
                for (int i = 0; i < valueList.Count; i++) {
                    if (valueList[i] <= playerScore) {
                        tempoaryList.Insert(i, playerName + ":" + playerScore.ToString());
                        isScoreLowest = false;
                        break;
                    }
                }
            }
    
            if (isScoreLowest) {
                tempoaryList.Add(playerName + ":" + playerScore.ToString());
            }
    
            using (StreamWriter sw = new StreamWriter(finalPath, false)) {
                for (int i = 0; i < tempoaryList.Count; i++) {
                    sw.WriteLine(tempoaryList[i]);
                    Debug.Log(tempoaryList[i]);
                }
            }
        }
    }
    

    GameOver.cs (or wherever you manage the game over condition):

    using UnityEngine;
    using System;
    
    public class GameOver : MonoBehaviour {
    
        public static event Action<string, int> GameOverEvent;
        string playerName;
        int finalScore;
    
        private void GameOver() {
            //Do other stuff when the game is over
            GameOverEvent(playerName, finalScore);
        }
    }
    

    Explanation of the changes:

    isScoreLowest is needed to Add the new lowest score at the end of the list, since the for loop won't add it by itself.

    The if (tempoaryList != null) check is done to skip the for loop when the scoreboard is empty.

    And you saved yourself from doing a Sort, which is always a good thing. :)