我正在尝试写一个简单的纸牌游戏。为了提出一个好的改组算法,我遇到了Jeff Atwood的post编码恐怖片。
但是,当我在调用构造函数后查看对象的内容时,它们不会被洗牌。
以下是我尝试使用杰夫的解决方案:
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);
}
}
我应该改变什么来改变洗牌工作?
答案 0 :(得分:14)
LINQ方法不会改变现有的集合。所以这句话什么都不做:this.OrderBy(a => Guid.NewGuid());
另外,我很确定你不能分配给this
,所以你必须要么不继承List<T>
(这很好),要么做这样的事情:
var sorted = this.OrderBy(a => Guid.NewGuid()).ToList();
this.Clear();
this.AddRange(sorted);
另外看看这个SO answer,还有更正确的改组算法。
答案 1 :(得分:6)
试试这个
public void Shuffle()
{
Random r = new Random();
this.Sort((x, y) => r.Next(-1, 1));
}
由于Linq的后续执行,后续行不会被执行。
this.OrderBy(a => Guid.NewGuid());
这只是创建查询但从未执行过。即使执行它也不会改变你的收藏。
不要忘记Linq是一种查询数据的方法,而不是改变它。
答案 2 :(得分:6)
使用此扩展方法
public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
{
Random rnd = new Random();
return source.OrderBy<T, int>((item) => rnd.Next());
}
答案 3 :(得分:1)
Linq无法通过引用工作。
你应该把结果变成一个变量。 在类中创建列表对象,而不是从列表继承,如下所示:
class MainDeck
{
public List<Card> lstCards;
public MainDeck()
{
this.lstCards.Add(new Card(1, "Hearts"));
this.lstCards.Add(new Card(2, "Hearts"));
this.lstCards.Add(new Card(3, "Hearts"));
...
this.lstCards = this.lstCards.OrderBy(a => Guid.NewGuid()).ToList();
}
}
如果这个答案有帮助,请标记为答案或有帮助。