【问题标题】:Shuffling list of competitors, each month different competitor洗牌竞争对手名单,每个月都有不同的竞争对手
【发布时间】:2018-12-18 07:52:49
【问题描述】:

对于我朋友的体育比赛,每个玩家每个月必须与其他玩家进行 1 场比赛。现在,如果我有一个包含 20 名左右球员的名单,那么在第一个月随机化并不难,所以我有 10 场比赛。

在那之后的所有月里,尽管我不确定如何让随机发生器工作,这样他们就不会与他们曾经交手过的玩家进行匹配。

现在我用 Players(Name, (int)Id, Email) , Matches(Id, Player1ID, Player2ID) 制作了一个 sql 数据库

我正在考虑随机化列表并检查每个匹配项是否不包含数据库中匹配项的 2 个 id。如果有 1 个匹配项,则重做该月的整个随机化。

但我不确定这是否是最好的方法。

这是我目前所拥有的,在我将一些“leden”和“matches”添加到我的数据库后,我还没有对其进行测试。

    private void MaakMatchen(Maand maand)
    {
        List<Lid> leden = new List<Lid>();
        var dbManager = new Manager();
        using (var conGildenhof = dbManager.GetConnection())
        {
            using (var comLeden = conGildenhof.CreateCommand())
            {
                comLeden.CommandType = CommandType.Text;
                comLeden.CommandText = "select * from dbo.Leden";
                conGildenhof.Open();
                using (var alleleden = comLeden.ExecuteReader())
                {
                    Int32 voornaamPos = alleleden.GetOrdinal("Voornaam");
                    Int32 familienaamPos = alleleden.GetOrdinal("Familienaam");
                    Int32 LidNummerPos = alleleden.GetOrdinal("LidNummer");

                    while (alleleden.Read())
                    {
                        leden.Add(new Classes.Lid(alleleden.GetString(voornaamPos), alleleden.GetString(familienaamPos), alleleden.GetInt32(LidNummerPos)));
                    }
                    leden = Randomize(leden);
                }
            }

            using (var comInsert = conGildenhof.CreateCommand())
            {
                comInsert.CommandType = CommandType.Text;
                comInsert.CommandText = "Insert into dbo.Matches (Lid1Id, Lid2Id, Maand) values (@lid1, @lid2, @maand)";

                var parLid1 = comInsert.CreateParameter();
                parLid1.ParameterName = "@lid1";
                comInsert.Parameters.Add(parLid1);

                var parLid2 = comInsert.CreateParameter();
                parLid2.ParameterName = "@lid2";
                comInsert.Parameters.Add(parLid2);

                var parMaand = comInsert.CreateParameter();
                parMaand.ParameterName = "@maand";
                comInsert.Parameters.Add(parMaand);


                int lengte = leden.Count();
                for (int i = 0; i < lengte; i = i + 2)
                {
                    parLid1.Value = leden[i].LidNummer;
                    parLid2.Value = leden[i + 1].LidNummer;
                    parMaand.Value = (int)maand;

                    comInsert.ExecuteNonQuery();
                }
            }
        }
    }

    private List<Lid> Randomize(List<Lid> leden)
    {
        for (int i=0;i<100;i++)
        {
            leden = Shuffle(leden);
        }
        int temp = CheckUp(leden);
        while (temp != 100)
        {
            leden = Shuffle(leden, temp);
            temp = CheckUp(leden);
        }
        return leden;
    }

    private List<Lid> Shuffle(List<Lid> leden)
    {
        Random rnd = new Random();
        int a = rnd.Next(1, leden.Count() + 1);
        int b = rnd.Next(1, leden.Count() + 1);

        var temp = new Lid();
        temp = leden[a];
        leden[a] = leden[b];
        leden[b] = temp;

        return leden;
    }

    private List<Lid> Shuffle(List<Lid> leden, int id)
    {
        Random rnd = new Random();
        int a = rnd.Next(1, leden.Count() + 1);
        int b = id;

        var temp = new Lid();
        temp = leden[a];
        leden[a] = leden[b];
        leden[b] = temp;

        return leden;
    }

    private int CheckUp(List<Lid> leden)
    {
        int lengte = leden.Count();
        List<Matches> matches = new List<Matches>();
        var dbManager = new Manager();
        using (var conGildenhof = dbManager.GetConnection())
        {
            using (var comMatches = conGildenhof.CreateCommand())
            {
                comMatches.CommandType = CommandType.Text;
                comMatches.CommandText = "select * from dbo.Matches";
                conGildenhof.Open();
                using (var allematches = comMatches.ExecuteReader())
                {
                    Int32 lid1Pos = allematches.GetOrdinal("Lid1Id");
                    Int32 lid2Pos = allematches.GetOrdinal("Lid2Id");
                    Int32 maandPos = allematches.GetOrdinal("Maand");

                    while (allematches.Read())
                    {
                        matches.Add(new Classes.Matches(allematches.GetInt32(lid1Pos), allematches.GetInt32(lid2Pos), (Maand)allematches.GetInt32(maandPos)));
                    }
                }
            }
        }
        for (int i=0;i<lengte;i=i+2)
        {
            foreach (Matches match in matches)
            {
                if (leden[i].LidNummer == match.Lid1Id)
                {
                    if (leden[i + 1].LidNummer == match.Lid2Id)
                        return leden[i].LidNummer;
                }
                if (leden[i].LidNummer == match.Lid2Id)
                {
                    if (leden[i + 1].LidNummer == match.Lid1Id)
                        return leden[i].LidNummer;
                }
            }
        }
        return 100;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var maand = new int();
        int.TryParse(TextBoxMaand.Text, out maand);
        if (maand == 0)
            TextBoxMaand.Text = "GETAL!";
        else
        {
            MaakMatchen((Maand)maand);
        }
    }

【问题讨论】:

  • 匹配真的需要是随机的,还是只需要所有可能的匹配组合?
  • 我猜你需要制定一个循环赛程。也许是 20 个随机列表,将 0 与 10 匹配,将 1 与 11 匹配,依此类推,直到您到达 9-19。然后,您只需在列表中切换位置,使最后一项成为第一项,并将每个项目向上移动一个位置。冲洗并重复,直到您完成所有计划。

标签: c# random shuffle


【解决方案1】:

我会先洗牌球员,然后在第二次迭代中创建比赛

List<Player> players = GetPlayers();
Random _rnd = new Random();
// shuffle players
players = players.OrderBy(_ => _rnd.Next()).ToList();
// create matches
var matches = players.Take(players.Count / 2).Zip(players.Skip(players.Count / 2), (p1, p2) => new Match(p1,p2));

https://dotnetfiddle.net/sGxbx4

【讨论】:

  • 比赛必须是随机的,如果玩家 1 和 2 必须在一月份互相对抗,那么在所有其他月份他们都无法互相匹配。
  • @Dylan,您应该编辑您的问题以包含您的代码,并解释它还需要做什么。
  • 是的,我编辑了它,我意识到我现在应该把我的代码也写成英文
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 2018-12-10
  • 2010-11-29
  • 1970-01-01
相关资源
最近更新 更多