jeudi 24 novembre 2016

Functionally pure dice rolls in C#

I am writing a dice-based game in C#. I want all of my game-logic to be pure, so I have devised a dice-roll generator like this:

public static IEnumerable<int> CreateDiceStream(int seed)
{
    var random = new Random(seed);

    while (true)
    {
        yield return 1 + random.Next(5);
    }
}

Now I can use this in my game logic:

var playerRolls = players.Zip(diceRolls, (player, roll) => Tuple.Create(player, roll));

The problem is that the next time I take from diceRolls I want to skip the rolls that I have already taken:

var secondPlayerRolls = players.Zip(
    diceRolls.Skip(playerRolls.Count()), 
    (player, roll) => Tuple.Create(player, roll));

This is already quite ugly and error prone. It doesn't scale well as the code becomes more complex.

It also means that I have to be careful when using a dice roll sequence between functions:

var x = DoSomeGameLogic(diceRolls);

var nextRoll = diceRolls.Skip(x.NumberOfDiceRollsUsed).First();

Is there a good design pattern that I should be using here?

Note that it is important that my functions remain pure due to syncronisation and play-back requirements.




Aucun commentaire:

Enregistrer un commentaire