选择未知列表中的随机项

时间:2010-02-24 19:37:54

标签: c# list

如何在不创建新对象的情况下更优雅地完成这项工作?

List<Move> playerMoves = clone.getValidSuccessorMoves(0);
List<Move> opponentMoves = clone.getValidSuccessorMoves(1);

Move pmove = playerMoves[rand.Next(playerMoves.Count)];
Move omove = opponentMoves[rand.Next(opponentMoves.Count)];

MapManipulator.applyMove(clone.Map, pmove);
MapManipulator.applyMove(clone.Map, omove);

clone.Player = pmove.Destination;
clone.Opponent = omove.Destination;

2 个答案:

答案 0 :(得分:2)

“选择随机项目位”似乎已完成:

list[random.Next(list.Count)]
只要你正确地创建Random的实例,

就可以了。鉴于我们不知道有太多代码,我们无法真正回答你问题的其他部分 - 你没有展示任何实际创建任何新对象的东西......

答案 1 :(得分:0)

假设你的生成移动功能类似于:

IEnumerable<Move> getValidSuccessorMoves()
{
    if (logic)
        yield return new Move(...);
    if (otherLogic)
        yield return new Move(...);
}

并且生成这个有一些开销(可能没有你认为的那么多),你可以通过使用如下的逻辑来避免每次生成完整列表:

int index = random.Next(MAX_POSSIBLE_MOVES);
List<Move> allMoves = new List<Move>(index);
var moves = getValidSuccessorMoves();
foreach (var move in moves)
{
    if (index == 0)
        return move;
    allMoves.Add(move);
}
index = random.Next(allMoves.Count);
return allMoves[index];

如果RNG选择了一个好数字,这可以让你短路,并且不会对结果产生偏差。当MAX_POSSIBLE_MOVES稍微接近实际产生的移动次数时,这才真正获益。

然而,即使这一切都说完了,你也可能过早地进行优化。这真的是为您描述最糟糕的代码吗? C#通常擅长许多短期分配和解除分配(这就是代际GC的用途)。