Please note, this blog entry is from a previous course. You might want to check out the current one.
Matchismo so far only displays the A♣ over and over. Fix Matchismo so that each time the card is flipped face up, it displays a different random card drawn from the
Deck property you’ve created above. In other words, Matchismo should flip through an entire deck of playing cards in random order, showing each card one at a time.
Because we will draw random cards, we should not start with the As of clubs but with the back of the card. We could do that in various ways, e.g. adjusting the story board (remove the text of the button and set the background to the correct image). If you want to adjust the button from inside the view controller, we need to add an outlet. Now we could use this outlet to access and manipulate the button as soon as the view has loaded. e.g. we could set the background and the title of the button. … because I am lazy I just call the existing method to flip the card using the outlet property as argument:
@property (weak, nonatomic) IBOutlet UIButton *cardButton; ... - (void)viewDidLoad { [super viewDidLoad]; [self touchCardButton:self.cardButton]; self.flipCount = 0; }
Please note that this might not be the best solution, because it has at least one unwanted side effect: It increases the flip count …
When flipping a card, draw it from the deck. If there is no card left, remove the card button from the view:
- (IBAction)touchCardButton:(UIButton *)sender { ... } else { Card *card = [self.deck drawRandomCard]; if (card) { [sender setBackgroundImage:[UIImage imageNamed:@"cardfront"] forState:UIControlStateNormal]; [sender setTitle:card.contents forState:UIControlStateNormal]; } else { [sender removeFromSuperview]; } } ... }
Sadly, the solution above has a problem. After the last card has been shown, the back of a card is shown and disappears only after another click. Also to disappear the button, it is not necessary to remove it from the view, it is also possible to just hide it. When turning a card back, check if there is a card left by drawing another one. If there is no other card, hide the card button. If there is a card left don’t forget to put it back on the deck:
- (IBAction)touchCardButton:(UIButton *)sender { if ([sender.currentTitle length]) { ... Card *nextCard = [self.deck drawRandomCard]; if (nextCard) { [self.deck addCard:nextCard]; } else { sender.hidden = YES; } ... }
The complete code is available on github.
Regarding the end of the deck past.
Doing it this way means that the user sees the back of the card, he believes that there is another one coming, and only when he click to flip the card disappears.
Wouldn’t it be better to use the flip counter and after the last flip (flip 103) just have the button disappear ?
By the way personally I rather use the ‘hidden’ propriety of the UIBotton.
True, I missed that the user is shown the back of the card before it disappears, I will change that. Also using the hidden property is a very good idea I did not think of that.
I don’t agree to use the flip counter, what happens if you have a deck with another number of cards, or you decide not to count flipping a card back?
The only way I can see not to display the back of an in existing last card and without using the flip counter is to query the Deck for the number of cards that it contains before deciding what to display when the card is flipped back.
The problem with that is that you have to modify the model so that you have the possibility to know how many cards are in the deck and that goes agains the instructions.
Any better idea ?
Thinking of it, there is the possibility that just before drawing the back of the card to draw a card from the deck. If you get a card, you print the back of the card and put the card back in the deck. Otherwise (i.e. if you get ‘nil’) you just hide the cards.
Have a look at the end of the post, that’s how I corrected the code 😉
Awesome.
Thx for that.