我是Dart的新人;并且,我创建了一个名为Deck的扑克牌对象列表。我正在尝试选择随机卡,然后从卡座中取出卡片。我正在获得重复,因为看起来随后的卡片在甲板减少之前被挑选。我将如何处理将从牌组中挑选10张独特随机牌的未来事件链?
class Card{
String face;
String suit;
String rank;
String imgSrc;
String holdImgSrc;
Card(
this.face,
this.suit,
this.rank,
this.imgSrc,
this.holdImgSrc
);
}
import 'dart:math' show Random;
Random indexGen = new Random();
getCard1(){
card1 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card1);
return card1;
}
getCard2(){
card2 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card2);
return card2;
}
当我尝试将卡片对象作为未来返回时,我得到:
new Future((getCard1()))
.then((getCard2()))
.then((getCard3()));
键入'卡'不是类型的子类型'()=>动态' '计算'。
当我尝试返回名单时,我得到:
输入'列表'不是类型的子类型'()=>动态' '计算'。
我是否错过了正确的语法,我的逻辑缺陷,或者我是否需要以不同的方式处理列表,可能会注意更改?
编辑添加:期货语法有效,但删除似乎没有正确发生。 我将代码更改为下面Jim-Y建议的代码,除了使用第二个命名构造函数从List预加载新的Card对象。修改后的代码和打印输出如下:
fullDeck[
...
var tenC = new Card.full(17,'10_of_clubs','c','10','10_of_clubs.png','10_of_clubs_h.png');
var tenD = new Card.full(18,'10_of_diamonds','d','10','10_of_diamonds.png','10_of_diamonds_h.png');
var tenS = new Card.full(19,'10_of_spades','s','10','10_of_spades.png','10_of_spades_h.png');
var tenH = new Card.full(20,'10_of_clubs','c','10','10_of_clubs.png','10_of_clubs_h.png');
...]
Deck<Card> deck = new Deck<Card>();
Random indexGen = new Random();
for(var c = 0; c < 20; ++c) {
var card = new Card(c);
deck.add(fullDeck[c]);//List of 52 full card objects
}
for(var i = 0; i < 10; ++i) {
var rnd = indexGen.nextInt(deck.size());
print('${deck.get(rnd).face} Deck size: ${deck.size()}');
}
}
4_of_clubs Deck size: 19
10_of_diamonds Deck size: 18
5_of_clubs Deck size: 17
4_of_spades Deck size: 16
5_of_spades Deck size: 15
10_of_clubs Deck size: 14
10_of_clubs Deck size: 13
3_of_spades Deck size: 12
5_of_diamonds Deck size: 11
3_of_diamonds Deck size: 10
正如你所看到的那样,10个俱乐部被打印两次。那么,如果10在第6遍被删除,为什么它仍然存在于第7阶段?
答案 0 :(得分:3)
如果您想以这种方式链接调用,方法必须返回未来:
警告:我没有测试过代码:
// I don't see what type 'Card' actually is from your code
Future<Card> getCard1(){
return new Future(() {
card1 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card1);
return card1;
});
}
getCard2()
Future<Card> getCard2(){
return new Future(() {
card2 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card2);
return card2;
});
}
你用
打电话getCard1().then((c) => getCard2()).then((c) => print(c));
因为getCard1
和getCard2
基本上是相同的方法,您可以将它们合并为一个
List<Card> cards = [];
Future<Card> getCard(int i){
return new Future(() {
cards[i] = deck[indexGen.nextInt(deck.length)]; // not clear what card is
deck.removeWhere((item) => item == card[i]);
return card[i];
});
}
。
getCard(1).then((c) => getCard(2)).then((c) => print(c));
答案 1 :(得分:1)
我现在无法看到为什么你需要使用Futures。在下面的代码中,我将尝试使用Dart的通用功能来解决从卡组中删除卡的可能更好的方法:)
您的原始卡类,我将其扩展用于演示目的:
class Card {
int id;
String face;
String suit;
String rank;
String imgSrc;
String holdImgSrc;
Card(this.id);
Card.full(this.id, this.face, this.suit, this.rank, this.imgSrc, this.holdImgSrc);
}
然后,您可以为您的卡制作一个通用容器,而不是使用简单的List。
class Deck<T extends Card> {
List<T> _container = new List<T>();
T get(int index) => _container.removeAt(index);
void add(T item) => _container.add(item);
int size() => _container.length;
}
这将使您的示例更容易在以后扩展,并且您可以获得更多的表达能力。
然后,你可以写这样的东西,从甲板上删除10个随机元素。
void main() {
Deck<Card> deck = new Deck<Card>();
Random indexGen = new Random();
for(var c = 0; c < 20; ++c) {
var card = new Card(c);
deck.add(card);
}
for(var i = 0; i < 10; ++i) {
var rnd = indexGen.nextInt(deck.size());
print('${deck.get(rnd).id} Deck size: ${deck.size()}');
}
}
在这个简单的例子中,使用这些简单的卡片对象没有重复。但是,如果需要,可以使用(n)fGet
方法扩展Deck类,这可能是@Günter之前提到的返回Future的方法。
我希望我能给你一些好主意:)
干杯