私はハイスコアのtop5リストを作成していますが、テキストファイルからデータを並べ替えて、最高のintでtop5を書き出す方法がわかりません。現在、結果をテキストファイルhighscore.txtに書き込むプログラムがあります。
こんな感じにしたいです。
Highscore
1. 500pts
2. 450pts
3. 400pts
4. 350pts
5. 300pts
私はハイスコアのtop5リストを作成していますが、テキストファイルからデータを並べ替えて、最高のintでtop5を書き出す方法がわかりません。現在、結果をテキストファイルhighscore.txtに書き込むプログラムがあります。
こんな感じにしたいです。
Highscore
1. 500pts
2. 450pts
3. 400pts
4. 350pts
5. 300pts
File.ReadLines("highscore.txt")
.Select(line => int.Parse(line))
.OrderByDescending(score => score)
.Take(5)
最適なソリューションは、プラットフォームの制約とテキストファイルのサイズによって異なります。
最も簡単な解決策は、おそらく各行をクラスとして表すことです。テキストファイルの行を読み取り、スコアのリストに入力してから、
public class Score
{
public int Points { get; set; }
public string Player { get; set; }
}
List<Score> top5 = (from s in allScores select s)
.OrderByDescending(s => s.Points)
.Take(5);
テキストファイルのサイズに比べてメモリに制約のあるプラットフォームを使用している場合は、整数カウンターを使用して、現在トップ5にある最低のハイスコアを追跡し、そのカウンターを使用して、ファイルは、手動で維持する上位5つのハイスコアのリストに追加する必要があります。
どちらの方法でも、次のように上位5つを出力できます。
for (int i = 0; i < top5.Count; i++)
{
Score score top5[i];
// e.g. Console.WriteLine((i + 1) + ". " + top5.Points);
// Optionally output player name / initials if that was in the text file
}
代わりに、実際のデータベース、たとえば無料のSql-ServerExpressを使用することをお勧めします。
本当にテキストファイルを使用したい場合は、次のアプローチを使用できます。
IEnumerable<string> top5HighScore = File.ReadLines("highscore.txt")
.Select(line => int.Parse(line))
.OrderByDescending(score => score)
.Take(5)
.Select((score, index) => string.Format("{0}. {1}pts", index + 1, score));
これで、たとえば、を使用しforeach
て文字列を出力できます。
を追加する必要があることに注意してくださいusing System.Linq;
。
データが行ごとである場合、またはファイルのバイトオフセットがわかっている場合は、ファイル全体を効率的に読み取り、メモリを節約して上位5つのスコアを追跡するのは非常に簡単です。
( StreamReaderを介して)ファイルから次のスコアを返す関数があるとすると、コードは次のようになります(スコアは整数であると想定しています)。
System.IO.StreamReader reader = new System.IO.StreamReader(fileName); // create StreamReader for the file
int maxTopScores = 5; // maximum number of scores to retrieve
List<int> topScores = new List<int>(); // create a list to store the top scores in
while (!reader.EndOfStream) // check there is still data to read (or some other check, depending on file format)
{
int tempScore = getScore(reader); // hypothetical function that retrieves the next score (returns an int)
for (int i = 0; i < topScores.Count; i++)
{
if (tempScore > topScores[i])
{
topScores.Insert(i, tempScore); // insert this score before the one that it is bigger than
if (topScores.Count > maxTopScores)
topScores.RemoveAt(topScores.Count - 1); // too many scores, remove the last (lowest)
goto scoreAdded; // sorry about the goto, but I hate breaking through loops with state booleans
}
}
// score not added yet
if (topScores.Count < maxTopScores)
topScores.Add(tempScore); // not enough scores, add it to the end (it's the lowest yet)
scoreAdded:
continue; // annoyingly this is needed
}
これにより、intスコアのリストが表示され、最高のスコアはインデックス0になり、リストを下に移動するとスコアが低くなります。それは多くのメモリを必要とせず、あなたはそれをクラッシュさせるのに苦労するでしょう。topScores
fileName
必要に応じてスコアをリストに挿入し、リストにスコアを超えないようにするために、ファイルをループしますmaxTopScores
。