【发布时间】:2017-04-09 05:47:17
【问题描述】:
我正在用 C# 编写一个基于骰子的游戏。我希望我所有的游戏逻辑都是纯粹的,所以我设计了一个像这样的掷骰子生成器:
public static IEnumerable<int> CreateDiceStream(int seed)
{
var random = new Random(seed);
while (true)
{
yield return 1 + random.Next(5);
}
}
现在我可以在我的游戏逻辑中使用它:
var playerRolls = players.Zip(diceRolls, (player, roll) => Tuple.Create(player, roll));
问题是下次我从diceRolls 拿走我想跳过我已经拿走的卷:
var secondPlayerRolls = players.Zip(
diceRolls.Skip(playerRolls.Count()),
(player, roll) => Tuple.Create(player, roll));
这已经很丑陋且容易出错。随着代码变得更加复杂,它不能很好地扩展。
这也意味着在函数之间使用掷骰子序列时我必须小心:
var x = DoSomeGameLogic(diceRolls);
var nextRoll = diceRolls.Skip(x.NumberOfDiceRollsUsed).First();
我应该在这里使用一个好的设计模式吗?
请注意,由于同步和播放要求,我的函数保持纯正很重要。
这个问题不是关于正确初始化System.Random。请阅读我写的内容,如果不清楚,请发表评论。
【问题讨论】:
-
您能否提供更多背景信息来说明为什么您甚至有一个
secondPlayerRolls变量?我的意思是说第二回合不就是对同一个函数的另一个调用,而不是它自己的代码和自己的变量吗? -
@sdgfsdh 是的,我是说在编写这样的游戏时永远不会有
secondRolls变量这样的东西,所以你描述的问题就不会发生。跨度> -
@Plutonix 这个问题与您标记为重复的内容完全无关。
-
我的意思是“纯粹”的功能纯度。没有副作用且结果完全由参数决定的函数是纯函数。
标签: c# random functional-programming