10

我正在尝试编写一个简单的纸牌游戏。为了想出一个好的改组算法,我偶然发现了 Jeff Atwood在 Coding Horror 上的帖子。

但是,当我在调用构造函数后查看对象的内容时,它们不会被打乱。

这是我尝试使用 Jeff 的解决方案:

class MainDeck : List<Card>
{
   public MainDeck()
    {
        this.Add(new Card(1, "Hearts"));
        this.Add(new Card(2, "Hearts"));
        this.Add(new Card(3, "Hearts"));
        ...

        this.OrderBy(a => Guid.NewGuid());
    }
}

这是卡的代码:

class Card
    {
        string suit;
        int value;

        public Card(int value, string suit)
        {
            this.value = value;
            this.suit = suit;
        }

        bool isFaceCard()
        {
            if (value >= 11 || value == 1)
                return true;
            else
                return false;
        }

        public override string ToString()
        {
            return (value +", " + suit);
        }
    }

我应该改变什么才能使洗牌工作?

4

3 回答 3

27

LINQ 方法不会改变现有集合。所以这个语句根本没有做任何事情:this.OrderBy(a => Guid.NewGuid()); 另外,我很确定你不能分配 to this,所以你要么不继承自List<T>(这很好),要么做这样的事情:

var sorted = this.OrderBy(a => Guid.NewGuid()).ToList();
this.Clear();
this.AddRange(sorted);

也看看这个SO answer,有更正确的洗牌算法。

于 2013-10-05T19:01:20.887 回答
15

使用此扩展方法

public static class Extensions
{
    public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
    {
        Random rnd = new Random();
        return source.OrderBy((item) => rnd.Next());
    }
}
于 2017-12-20T06:59:43.933 回答
6

尝试这个

 public void Shuffle()
 {
     Random r = new Random();
     this.Sort((x, y) => r.Next(-1, 1));
 }

由于 Linq 的延迟执行,以下行没有被执行。

this.OrderBy(a => Guid.NewGuid());

这只是创建查询但从未执行。即使执行它也不会改变你的收藏。

不要忘记 Linq 是一种查询数据的方法,而不是对其进行变异。

于 2013-10-05T19:04:15.410 回答