【问题标题】:C# trivia game: What to do in case of a tie?C# 琐事游戏:如果出现平局怎么办?
【发布时间】:2012-04-29 06:33:40
【问题描述】:

我目前正在开发一款问答游戏。我写了一个 Team 类、一个 Question 类和一个 Round 类。

这是我的 Team 类(我不会发布属性、构造函数和方法,因为它们与我的问题无关)。

public class Team
{
    private int _teamNumber = 0;
    private int _score = 0;
}

这是我的 Round 课程:

public class Round
{
    Team[] _teams = new Team[4];
    Question[] _questions = new Clue[30];
    bool _done = true; 
}

我遇到的问题是如果出现平局该怎么办。有8支球队。前两轮各有两名获胜者(每队 4 支)将有资格参加第三轮和最后一轮。

所以万一发生这种情况:

currentRound.Teams[0].Score = 300;
currentRound.Teams[1].Score = 300;
currentRound.Teams[2].Score = 100;
currentRound.Teams[3].Score = 350;

如您所见,第二名并列。

我知道我可以检查重复,但如果球队的分数像这样

500、400、200、200

500、500、200、100

在这种情况下,不需要抢七,因为只有前两支球队晋级下一轮。

所以我想知道是否有人可以帮助我想出一种算法来帮助确定我是否需要进行决胜局比赛。如果我这样做,我们应该选择哪支球队,最后每轮的前两支球队是什么。

感谢阅读!

【问题讨论】:

  • 你的数据源是SQL吗?如果是这样,它有一个非常方便的RANK() 函数可以解决您的问题。

标签: c# arrays loops


【解决方案1】:

如何使用 LINQ 来确定是否有并列第二的团队?

var orderedResults = currentRound.Teams.OrderBy(x=>x.Score).ToList();
if(orderedResults.Any(x=>x.Score == orderedResults[1].Score))
    var team2 = RunTieBreaker(
        orderedResults.Where(x=>x.Score == orderedResults[1].Score).ToList());

如果您使用此实现,您甚至可以删除 if 并执行 RunTieBreaker:

Team RunTieBreaker(List<Team> teamsToTieBreak)
{
    if(teamsToTieBreak.Count == 1)
        return teamsToTieBreak[0];
    //Do tiebreaker
}

或者,您可以使用OrderByTake(2)。然后你可以使用Where 和/或Any 对抗第二支队伍。

【讨论】:

    【解决方案2】:

    做这样的事情:

    var result = currentRound.Teams.OrderBy(t => t.Score).GroupBy(t => t.Score).Take(2);
    if (result.Sum(m => m.Count()) > 2)
    {
        //Need extra round
    }
    else
    {
        //No extra round
    }
    

    【讨论】:

      【解决方案3】:

      我总是喜欢在我的程序中始终确保不可能出现平局。所以如果这是一个掷硬币的游戏,我总是会有奇数的掷球。有了这样的东西,你可能会加入时间,或者你可以添加奖励积分来表示准确性。或者,您可以列出连续正确回答的大多数答案。

      【讨论】:

        【解决方案4】:

        按分数对团队进行排序并取第二个元素。只选择得分大于或等于该分数的球队。如果您获得超过 2 支球队 - 所有得分等于该分数的球队都将进入决胜局。

        【讨论】:

          【解决方案5】:

          获得排位线以上的最低分数,并计算有多少支球队获得该分数或更高:

          int qualifyingCount = 2;
          int score =
            currentRound.Teams.Select(t => t.Score)
            .OrderByDescending(s => s)
            .Take(qualifyingCount).Last();
          
          if (currentRound.Teams.Count(t => t.Score >= score) > qualifyingCount) {
            // tie break needed
          }
          

          【讨论】:

            【解决方案6】:
            List<Team> n = [total teams in round];
            int x = [number moving to next round];
            
            OrderTeamsByScore(n);
            // get participants by score uses value of x to determine whether tie-break is needed
            Team p = RunTieBreaker(GetTeamsByScore(n[x-1].Score, x)); //zero based array
            

            注意:如果只有1支球队的得分为“n[x-1].Score”,则默认为抢七;如果不需要抢七,默认返回“n[x-1]”

            【讨论】:

              【解决方案7】:

              按照这些步骤,您将获得获胜者名单和并列球队名单。 通过这两个列表,您可以回答您的三个问题。

              1) 按分数排序。 2) 确定并列球队的得分。如果没有平局,则设置-1。 3) 获取未绑定的获胜者列表。如果每个人都被捆绑,则此列表为空。 4) 获取并列球队的名单。如果没有平局,则此列表为空。 5) 检查获胜者,是否有平局或任何您需要的。

              var orderedTeams = currentRound.Teams.OrderBy(t => t.Score).ToList();
              int tieScore = orderedTeams[1].Score == orderedTeams[2].Score ? orderedTeams[1].Score : -1;
              List<Team> winers = tieScore > 0 ? orderedTeams.Where(t => t.Score > tieScore) : orderedTeams.Take(2).ToList();
              List<Team> tiedTeams = orderedTeams.Where(t => t.Score == tieScore).ToList();
              bool needTieBreak = tiedTeams.Count > 0;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2019-12-08
                • 1970-01-01
                • 1970-01-01
                • 2016-11-22
                • 2018-06-04
                • 1970-01-01
                • 2011-06-22
                • 2013-11-06
                相关资源
                最近更新 更多