Skip to content

Commit

Permalink
- updated the code with the changed from Lecture 3 (Objective-C)
Browse files Browse the repository at this point in the history
- improved the code to work without warning on 64bit as well as 32bit
  • Loading branch information
Jeroen Wesbeek committed Nov 6, 2013
1 parent 3c7a3ed commit f6f625c
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 40 deletions.
6 changes: 6 additions & 0 deletions Matchismo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
904A853318298C800065C691 /* Deck.m in Sources */ = {isa = PBXBuildFile; fileRef = 904A853218298C800065C691 /* Deck.m */; };
904A8539182990900065C691 /* PlayingCard.m in Sources */ = {isa = PBXBuildFile; fileRef = 904A8538182990900065C691 /* PlayingCard.m */; };
904A853C182997770065C691 /* PlayingCardDeck.m in Sources */ = {isa = PBXBuildFile; fileRef = 904A853B182997770065C691 /* PlayingCardDeck.m */; };
904A853F1829A8FE0065C691 /* CardMatchingGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 904A853E1829A8FE0065C691 /* CardMatchingGame.m */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -65,6 +66,8 @@
904A8538182990900065C691 /* PlayingCard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PlayingCard.m; path = Model/PlayingCard.m; sourceTree = "<group>"; };
904A853A182997770065C691 /* PlayingCardDeck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlayingCardDeck.h; path = Model/PlayingCardDeck.h; sourceTree = "<group>"; };
904A853B182997770065C691 /* PlayingCardDeck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PlayingCardDeck.m; path = Model/PlayingCardDeck.m; sourceTree = "<group>"; };
904A853D1829A8FE0065C691 /* CardMatchingGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CardMatchingGame.h; path = Model/CardMatchingGame.h; sourceTree = "<group>"; };
904A853E1829A8FE0065C691 /* CardMatchingGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CardMatchingGame.m; path = Model/CardMatchingGame.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -176,6 +179,8 @@
904A853218298C800065C691 /* Deck.m */,
904A853A182997770065C691 /* PlayingCardDeck.h */,
904A853B182997770065C691 /* PlayingCardDeck.m */,
904A853D1829A8FE0065C691 /* CardMatchingGame.h */,
904A853E1829A8FE0065C691 /* CardMatchingGame.m */,
);
name = Model;
sourceTree = "<group>";
Expand Down Expand Up @@ -282,6 +287,7 @@
904A853318298C800065C691 /* Deck.m in Sources */,
904A8509182971370065C691 /* CardGameAppDelegate.m in Sources */,
904A850F182971370065C691 /* CardGameViewController.m in Sources */,
904A853F1829A8FE0065C691 /* CardMatchingGame.m in Sources */,
904A853C182997770065C691 /* PlayingCardDeck.m in Sources */,
904A8505182971370065C691 /* main.m in Sources */,
904A852F182983A10065C691 /* Card.m in Sources */,
Expand Down
150 changes: 147 additions & 3 deletions Matchismo/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

70 changes: 33 additions & 37 deletions Matchismo/CardGameViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,59 @@

#import "CardGameViewController.h"
#import "PlayingCardDeck.h"
#import "CardMatchingGame.h"

@interface CardGameViewController ()
@property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
@property (nonatomic) int flipCount;
@property (nonatomic, strong) Deck *deck;
@property (nonatomic, strong) CardMatchingGame *game;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
@end

@implementation CardGameViewController

//- (void)viewDidLoad
//{
// [super viewDidLoad];
// // Do any additional setup after loading the view, typically from a nib.
//}
//
//- (void)didReceiveMemoryWarning
//{
// [super didReceiveMemoryWarning];
// // Dispose of any resources that can be recreated.
//}

- (Deck *)deck
- (CardMatchingGame *)game
{
if (!_deck) _deck = [self createDeck];
return _deck;
if (!_game) _game = [[CardMatchingGame alloc] initWithCardCount:[self.cardButtons count]
usingDeck:[self createDeck]];
return _game;
}

- (Deck *)createDeck
{
return [[PlayingCardDeck alloc] init];
}

- (void)setFlipCount:(int)flipCount {
_flipCount = flipCount;
self.flipsLabel.text = [NSString stringWithFormat:@"Flips: %d", self.flipCount];
NSLog(@"flipcount = %d", self.flipCount);
- (IBAction)touchCardButton:(UIButton *)sender {
NSUInteger cardIndex = [self.cardButtons indexOfObject:sender];
[self.game chooseCardAtIndex:cardIndex];
[self updateUI];
}

- (IBAction)touchCardButton:(UIButton *)sender {
if ([sender.currentTitle length]) {
// show the back of a card
[sender setBackgroundImage:[UIImage imageNamed:@"cardBack"]
forState:UIControlStateNormal];
[sender setTitle:@"" forState:UIControlStateNormal];
self.flipCount++;
} else {
// draw random card from the deck
Card *card = [self.deck drawRandomCard];
- (void)updateUI
{
for (UIButton *cardButton in self.cardButtons) {
NSUInteger cardIndex = [self.cardButtons indexOfObject:cardButton];
Card *card = [self.game cardAtIndex:cardIndex];

// show the card, if there is one (e.g. deck not empty)
if (card) {
[sender setBackgroundImage:[UIImage imageNamed:@"cardFront"]
[cardButton setTitle:[self titleForCard:card] forState:UIControlStateNormal];
[cardButton setBackgroundImage:[self backgroundImageForCard:card]
forState:UIControlStateNormal];
[sender setTitle:card.contents forState:UIControlStateNormal];
self.flipCount++;
}
cardButton.enabled = !card.isMatched;
}

// %ld and explicit typecast to long to support 32bit as well as 64bit
self.scoreLabel.text = [NSString stringWithFormat:@"Score: %ld", (long) self.game.score];
}

- (NSString *)titleForCard:(Card *)card
{
return (card.isChosen) ? card.contents : @"";
}

- (UIImage *)backgroundImageForCard:(Card *)card
{
return [UIImage imageNamed:(card.isChosen) ? @"cardFront" : @"cardBack"];
}

@end
23 changes: 23 additions & 0 deletions Matchismo/Model/CardMatchingGame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// CardMatchingGame.h
// Matchismo
//
// Created by Jeroen Wesbeek on 05/11/13.
// Copyright (c) 2013 MyCompany. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Deck.h"

@interface CardMatchingGame : NSObject

// designated initializer
- (instancetype)initWithCardCount:(NSUInteger)count
usingDeck:(Deck *)deck;

- (void)chooseCardAtIndex:(NSUInteger)index;
- (Card *)cardAtIndex:(NSUInteger)index;

@property (nonatomic, readonly) NSInteger score; // make score read only in public API

@end
93 changes: 93 additions & 0 deletions Matchismo/Model/CardMatchingGame.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// CardMatchingGame.m
// Matchismo
//
// Created by Jeroen Wesbeek on 05/11/13.
// Copyright (c) 2013 MyCompany. All rights reserved.
//

#import "CardMatchingGame.h"

@interface CardMatchingGame()
@property (nonatomic, readwrite) NSInteger score; // make score writable in out private API
@property (nonatomic, strong) NSMutableArray *cards; // of Card
@end

@implementation CardMatchingGame

- (NSMutableArray *)cards
{
if (!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}

- (instancetype)initWithCardCount:(NSUInteger)count
usingDeck:(Deck *)deck
{
self = [super init];

if (self) {
for (NSUInteger i = 0; i < count; i++) {
Card *card = [deck drawRandomCard];

if (card) {
[self.cards addObject:card];
} else {
self = nil;
break;
}
}
}

return self;
}

//#define MISMATCH_PENALTY 2 // it's a matter of preference what to use, however:
static const int MISMATCH_PENALTY = 2; // this is typed so it will show in the debugger
static const int MATCH_BONUS = 4;
static const int COST_TO_CHOOSE = 1;

- (void)chooseCardAtIndex:(NSUInteger)index
{
Card *card = [self cardAtIndex:index];

if (!card.isMatched) {
if (card.isChosen) {
card.chosen = NO;
} else {
// match against another card
for (Card *otherCard in self.cards) {
if (otherCard.isChosen && !otherCard.isMatched) {
int matchScore = [card match:@[otherCard]];

if (matchScore) {
// increase score
self.score += (matchScore * MATCH_BONUS);

// mark cards as matched
card.matched = YES;
otherCard.matched = YES;
} else {
// mismath penalty when cards do no match
self.score -= MISMATCH_PENALTY;

// flip othercard
otherCard.chosen = NO;
}

break;
}
}

self.score -= COST_TO_CHOOSE;
card.chosen = YES;
}
}
}

- (Card *)cardAtIndex:(NSUInteger)index
{
return (index < [self.cards count]) ? self.cards[index] : nil;
}

@end
18 changes: 18 additions & 0 deletions Matchismo/Model/PlayingCard.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@

@implementation PlayingCard

// override 'match' inherited from Card
- (int)match:(NSArray *)otherCards
{
int score = 0;

if ([otherCards count] == 1) {
PlayingCard *otherCard = [otherCards firstObject];

if ([self.suit isEqualToString:otherCard.suit]) {
score = 1;
} else if (self.rank == otherCard.rank) {
score = 4;
}
}

return score;
}

- (NSString *)contents
{
NSArray *rankStrings = [PlayingCard rankStrings];
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This is the code for the _Matchismo_ project for the Computer Science [CS139p](h
## Lecture(s)
This code covers the _Matchismo_ project from Lecture 2 and Assignments 1.

## UI
Note that I have developed this with 4" screen (iPhone 5 & 5S) in mind. Running this on a 3.5" screen or simulator may result in los of UI.

## Versions
The code has been tagged in different versions to represent the different stages of development and progressing through the Lectures, Slides and Assignments. From bottom (oldest) to top (most recent) the different stages of development are tagged:

Expand Down

0 comments on commit f6f625c

Please sign in to comment.