Search code examples
iosiphoneios7cs193p

Issues about assignment 1 of CS193P


I have learnt first and second lesson of CS193P and finished the first assignment which asks me to make Matchismo flip through an entire deck of playing cards in random order, showing each card one at a time. Here's my code of CardGameViewController.m

#import "CardGameViewController.h"
#import "Deck.h"
#import "PlayingCardDeck.h"

@interface CardGameViewController ()

@property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
@property (nonatomic) int flipCount;
@property (strong, nonatomic) Deck *fullDeck;

@end

@implementation CardGameViewController

- (void)setFlipCount:(int)flipCount{
  _flipCount = flipCount;
  self.flipsLabel.text = [NSString stringWithFormat:@"Flips: %d",self.flipCount];
  NSLog(@"flipCount changed to %d",self.flipCount);
}

- (Deck *)fullDeck{
  if (!_fullDeck)  _fullDeck =[[PlayingCardDeck alloc] init];
  return _fullDeck;
  }

- (IBAction)touchCardButton:(UIButton *)sender {
  if (!sender.currentTitle) {
     [sender setBackgroundImage:[UIImage imageNamed:@"cardfront"]
                       forState:UIControlStateNormal];
     [sender setTitle:[[self.fullDeck drawRandomCard] contents]
             forState:UIControlStateNormal];
  } else {
    [sender setBackgroundImage:[UIImage imageNamed:@"cardback"]
                      forState:UIControlStateNormal];
    [sender setTitle:nil forState:UIControlStateNormal];
}

self.flipCount++;
}

@end

Of course,before doing this, I have deleted the "A♣︎" on the button of teching demo first ,because the hints tell me I should make it come up showing the back of the card instead.I build the application successfully and it seems work very well.

However,the hints of the assignment tell me:

A good solution will have given some thought to what happens if every card in the deck has been shown and the user still keeps flipping. Do something simple and sensible (for example, you should not have to modify the classes in the Model in any way).

But my solution will let the user flip the card infinitely.So I try reaching the goal by adding a if() like this:

- (IBAction)touchCardButton:(UIButton *)sender {

   if (self.flipCount < 53){           /*There are 52 cards in a deck */
   if (!sender.currentTitle) {
      [sender setBackgroundImage:[UIImage imageNamed:@"cardfront"]
                        forState:UIControlStateNormal];
      [sender setTitle:[[self.fullDeck drawRandomCard] contents]
              forState:UIControlStateNormal];
   } else {
      [sender setBackgroundImage:[UIImage imageNamed:@"cardback"]
                      forState:UIControlStateNormal];
      [sender setTitle:nil forState:UIControlStateNormal];
  }

      self.flipCount++;
}
}

Then when I run the application and touch the screen,it will not flip any more when the fliplabel reaches 52.

Is this solution naive and absurd? I have searched github to see others' solution and it seems the hints are ignored.Can you share your idea with me?

Any suggestion would be highly appreciated !!!


Solution

  • you just need to wrap it with an if statement like this

    if (card) {
           //flip the card
    }
    

    remember card is an object of Deck.h, and we already set Deck to return nil when its running out of card. So, it'll stop flipping once the deck is running out of card

    Also, most importantly, no magic number! you can't just throw 53 out of nowhere like that even if you've written a command to explain it. It's just a bad programming practice

    - (IBAction)touchCardButton:(UIButton *)sender {
    
       // No magic number! --> if (self.flipCount < 53){           
    
       if (!sender.currentTitle) {
          Card *card = [self.fullDeck drawRandomCard];
    
          if (card) {  // <----- this is what I'm talking about
              [sender setBackgroundImage:[UIImage imageNamed:@"cardfront"]
                                forState:UIControlStateNormal];
              [sender setTitle:card.contents
                      forState:UIControlStateNormal];
          }
       } else {
          [sender setBackgroundImage:[UIImage imageNamed:@"cardback"]
                          forState:UIControlStateNormal];
          [sender setTitle:nil forState:UIControlStateNormal];
      }
          self.flipCount++;
    }