Random()为相同类型的新对象分配相同的值

时间:2018-05-04 01:04:26

标签: c# random

我为我不太明确的标题道歉,我发现很难深入描述这个问题。我尝试在SO中研究Random的类似问题,然后实施这些建议,但没有成功。

我有以下代码模拟体育比赛。逻辑的核心在于Game类。当我模拟锦标赛时,分配给第一轮比赛中的球员的结果很好,就像按照预期随机分配一样。然而,当我模拟第二轮和第三轮等时,赢得第一轮的玩家获得与第一轮完全相同的分数。它好像系统记住它们,而不是生成新的随机值。我确定它与Random有关,但我无法绕过它。有没有人对我如何解决这个问题有任何建议?

RnDGen:

public class RndGen
{
    private static Random random = new Random();

    public static int Get(int min, int max)
    {
        return random.Next(min, max);
    }
}

赛:

public class Tournament : IAggregateRoot
{
    public string Name { get; set; }

    public int Year { get; set; }

    public List<Round> Rounds { get; set; }

    public GameMaster GameMaster { get; set; }

    public Tournament(string name, int year)
    {
        Rounds = new List<Round>();
        Name = name;
        Year = year;
    }

    public void Simulate(List<Player> players)
    {
        var playersStillInTournament = players;
        int roundNumber = 1;

        while (playersStillInTournament.Count > 1)
        {
            var round = new Round(roundNumber);

            round.Simulate(playersStillInTournament);
            playersStillInTournament = round.Winners;

            Rounds.Add(round);

            roundNumber++;
        }
    }
}

回合:

public class Round
{
    public int Number { get; private set; }

    public List<Game> Games { get; set; }

    public List<Player> Winners => Games.Select(g => g.Winner).ToList();

    public Round(int number)
    {
        Number = number;
        Games = new List<Game>();
    }

    public void Simulate(List<Player> players)
    {
        for(int i = 0; i != players.Count; i = i + 2)
        {
            var playersToAdd = players.Skip(i).Take(2).ToList();
            var game = new Game(playersToAdd);
            Games.Add(game);
        }
    }
}

游戏:

public class Game
{
    public List<Player> Players { get; private set; }

    private int MaxSets => (Players.First().Gender == Gender.Male) ? 5 : 3;

    public Player Winner => Players.Find(p => p.SetPoints.Count(px => px == 6) == ((MaxSets + 2 - 1) / 2));

    public Game(List<Player> players)
    {
        Players = players;
        Simulate();
    }

    private void Simulate()
    {
        while (Winner == null)
        {
            var winnerId = Players[RndGen.Get(0, Players.Count)].Id;
            var loserPoints = RndGen.Get(0, 5);

             Players.Find(p => p.Id == winnerId).SetPoints.Add(6);
             Players.Find(p => p.Id != winnerId).SetPoints.Add(loserPoints);
        }
    }
}

播放器

public class Player : Person
{
public List<int> SetPoints;

public int Points
{
    get
    {
        return SetPoints.Sum();
    }
}

public Player(string[] textFileLines, Gender gender)
    : base(textFileLines, gender)
{
    SetPoints = new List<int>();
}

public abstract class Person
    {
        public int Id { get; private set; } 

        public string FirstName { get; private set; }

        public string MiddleName { get; private set; }

        public string LastName { get; private set; } 

        public DateTime Birthday { get; private set; } 

        public string Country { get; private set; }

        public string CountryCode { get; private set; }

        public Gender Gender { get; set; }

        // Returns the age as an integer
        public int GetAge => DateTime.Now.Year - Birthday.Year;

        protected Person(string[] textFileLines, Gender gender)
        {
            Id = Convert.ToInt32(textFileLines[0]);
            FirstName = textFileLines[1];
            MiddleName = textFileLines[2];
            LastName = textFileLines[3];
            Birthday = Convert.ToDateTime(textFileLines[4]);
            Country = textFileLines[5];
            CountryCode = textFileLines[6];
            Gender = gender;
        }

    }

2 个答案:

答案 0 :(得分:4)

Simulate()更改为

private void Simulate()
{
    while (Winner == null)
    {
        var winnerId = Players[RndGen.Get(0, Players.Count)].Id;
        var loserPoints = RndGen.Get(0, 5);

            Players.Find(p => p.Id == winnerId).SetPoints.Add(6);
            Players.Find(p => p.Id != winnerId).SetPoints.Add(loserPoints);
    }

    Console.WriteLine(Winner.Id);
    Players.ForEach(p => p.SetPoints = new List<int>());
}

这样你就可以在回合结束时重置每个玩家SetPoints

运行5次模拟后,我得到了这个输出

5
2
2
1
1

答案 1 :(得分:1)

如果在Game中找到Winner,则while循环不会在Simulate()方法中执行,因此SetPoints不会改变。当你再次运行它时,它会再次找到相同的赢家,因为设定点没有改变。