如果玩家“从”评分中“取消”,该如何去除其结果?

时间:2019-05-31 10:59:11

标签: c# winforms

如果玩家“飞行”超出评分(例如,排名第六),我需要将其从词典和文件中删除。 我有一个主意,可以通过Dictionary.Remove,然后将其覆盖在文件中。

我制定了一个动作算法: 读取文件,删除内存中的行,然后将内容返回文件(覆盖)。如果文件很大,您可以阅读该行的内容并创建一个临时文件,稍后再替换原始文件。

以下是将它们分类到位的代码,也许有些帮助:

private static Dictionary<string, int> AllNames()
    {
        return File
          .ReadLines(@"C:\Users\HP\Desktop\картинки\results.txt")
          .Where(line => !string.IsNullOrWhiteSpace(line))
          .Select(item => item.Split(' '))
          .ToDictionary(items => items[0],
                        items => int.Parse(items[1]));
    }


    private void updateRatingLabels()
    {
        var tops = AllNames()
          .OrderBy(pair => pair.Value)                      
          .ThenBy(pair => pair.Key, StringComparer.Ordinal) 
          .Take(5)                                           
          .ToArray();


        for (int i = 18; i <= 22; ++i)
            Controls.Find($"label{i}", true).First().Text = "";

        for (int i = 28; i <= 32; ++i)
            Controls.Find($"label{i}", true).First().Text = "";


        for (int i = 0; i < tops.Length; ++i)
        {
            Controls.Find($"label{i + 18}", true).First().Text = tops[i].Key;
            Controls.Find($"label{i + 28}", true).First().Text = $"{tops[i].Value / 60}:{tops[i].Value % 60:00}";
        }
    }

1 个答案:

答案 0 :(得分:1)

Let's put the question in a different way: we are going keep (not remove) at most 5 top players. We have to consider what we should do in case of tie (i.e. 2 or more players have the same score). I think it'll be honest to keep all such players (so that the actual dictionary can be longer than 5 records):

var newDictionary = AllNames()
  .GroupBy(pair => pair.Value)  // groups by scores                    
  .OrderBy(chunk => chunk.Key)  // less seconds the better
  .Take(5)                      // at most 5 groups (ties preserved)                     
  .SelectMany(chunk => chunk)   // flatten back ("ungroup")
  .ToDictionary(pair => pair.Key, 
                pair => pair.Value);

To save the data into the file, try File.WriteAllLines; let's use "Name Value" format

 File.WriteAllLines(@"c:\TopPlayers.txt", newDictionary
   .Select(pair => $"{pair.Key} {pair.Value}"));

Edit: If we have to add an user, with name and score we can do it in 2 ways:

Whatever score is remove 5th place and add new user:

 var newDictionary = AllNames()
  .GroupBy(pair => pair.Value)  // groups by scores                    
  .OrderBy(chunk => chunk.Key)  // less seconds the better
  .Take(4)                      // at most 4 groups (ties preserved)                     
  .SelectMany(chunk => chunk)   // flatten back ("ungroup")
  .ToDictionary(pair => pair.Key, 
                pair => pair.Value);

 newDictionary.Add(name, score);

Add new user, then take top 5 (note, that new user can be excluded as a lower performer)

 var newDictionary = AllNames()
  .Concat(new KeyValuePair<string, int>[] { 
     new KeyValuePair<string, int>(name, score)} // All new users here
   )
  .GroupBy(pair => pair.Value)  // groups by scores                    
  .OrderBy(chunk => chunk.Key)  // less seconds the better
  .Take(5)                      // at most 5 groups (ties preserved)                     
  .SelectMany(chunk => chunk)   // flatten back ("ungroup")
  .ToDictionary(pair => pair.Key, 
                pair => pair.Value);

Edit 2: So you can implement a method like

 private void SaveNewUser(string name, int score) {
   var newDictionary = AllNames()
     .GroupBy(pair => pair.Value)     // groups by scores                    
     .OrderBy(chunk => chunk.Key)     // less seconds the better
     .Take(4)                         // at most 4 groups (ties preserved)         
     .SelectMany(chunk => chunk)      // flatten back ("ungroup")
     .ToDictionary(pair => pair.Key, 
                  pair => pair.Value);

   newDictionary.Add(name, score);

   File.WriteAllLines(@"c:\TopPlayers.txt", newDictionary
     .Select(pair => $"{pair.Key} {pair.Value}"));
 }

which you can call somewhere on, say, a button click:

 private void saveButton_Click(object sender, EventArgs e) {
   SaveNewUser(textBoxWithName.Text, int.Parse(textBoxWithScore.Text));
 }