I am new at Dart; and, I created a List of playing card objects called Deck. I am trying to select a random card, then remove the card from the deck. I am getting duplicates, as it appears subsequent cards are picked before the deck is reduced. How would I handle a future chain of events that will pick 10 unique random cards from the deck?
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;
}
When I try to return a Card Object as a future I get:
new Future((getCard1()))
.then((getCard2()))
.then((getCard3()));
type 'Card' is not a subtype of type '() => dynamic' of 'computation'.
When I try to return the deck List I get:
type 'List' is not a subtype of type '() => dynamic' of 'computation'.
Am i missing the right syntax, flaw in my logic, or do I need to handle the list differently, by maybe watching for changes?
edit to add: The futures syntax works, however, the deletes do not appear to be happening correctly. I changed the code, to the code suggested by Jim-Y below, except for preloading new Card objects from a List using the second named constructor. The amended code and printout is as follows:
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
As you can see the 10 of Clubs is printed twice. So, If the 10 was removed in pass 6, why is it still there in pass 7?
If you want to chain the calls this way the methods must return a future:
Caution: I have not tested the code:
// 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;
});
}
the same for getCard2()
Future<Card> getCard2(){
return new Future(() {
card2 = deck[indexGen.nextInt(deck.length)];
deck.removeWhere((item) => item == card2);
return card2;
});
}
you call it with
getCard1().then((c) => getCard2()).then((c) => print(c));
as getCard1
and getCard2
are essentially the same methods you could combine them to one
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));