Deck
- .h
#import <Foundation/Foundation.h>
@interface Deck : NSObject
- (void)addCard:(Card *)card;
- (void)addCard:(Card *)card atTop:(Bool)atTop;
- (Card *)drawRandomCard;
@end
- .m
#import "Deck.h"
@interface Deck()
@property (strong, nonatomic) NSMutableArray *cards;
@end
@implementation Deck
//一开始 cards 实例变量是 nil,要重写 getter 来初始化
- (NSMutableArray *)cards {
//惰性初始化,即当要使用该变量时才初始化
if (!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}
- (void)addCard:(Card *)card atTop:(Bool)atTop {
if (atTop) {
[self.cards insertObject:card atIndex:0];
} else {
[self.cards addObject:card];
}
}
- (void)addCard:(Card *)card {
[self addCard:card atTop:NO];
}
- (Card *)drawRandomCard {
Card *randomCard = nil;
if ([self.cards count]){}
unsigned index = arc4random() % [self.cards count]
randomCard = self.cards[index];
[self.cards removeObjectAtIndex:index];
}
return randomCard;
}
@end
PlayingCard
-
.h
#import "Card.h" @interface PlayingCard: Card @property (strong, nonatomic) NSString *suit; @property (nonatomic) NSUInteger rank; + (NSArray *)validSuits; + (NSUInteger)maxRank; //外部只需要知道最大牌点是多少,而不需要知道详细有什么牌 @end
-
.m
#import "PlayingCard.h" @implementation PlayingCard - (NSString *)contents { NSArray *rankStrings = [self rankStrings]; return [rankStrings[self.rank] stringByAppendingString:self.suit]; } + (NSArray *)rankStrings { return @[@"?", @"A", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"J", @"Q", @"K"]; } + (NSArray *)validSuits { return @[@"❤️", @"♠️", @"♣️", @"♦️"]; } //上述两个类方法不会影响性能,只是为了可读性 + (NSUInteger)maxRank { return [[self rankStrings] count]-1; } - (void)setRank:(NSUInteger)rank { if (rank M= [PlayingCard maxRank]) { _rank = rank; } } @synthesize suit = _suit; //同时重写 setter 和 getter 时必须手写 synthesize - (void)setSuit:(NSString *)suit { if ([validSuits containsObject:suit]) { _suit = suit; } } - (NSString *)suit { return _suit? : _suit : @"?"; } @end
PlayingCardDeck
-
.h
import "Deck.h" @interface PlayingCardDeck : Deck @end
-
.m
#import "PlayingCardDeck.h" #import "PlayingCard.h" @implementation Deck - (instancetype)init { //instancetype 是 NSObject 中规定的 init 的返回值 //它的意思是这个返回的对象和这个消息将要发送给的对象是同一类型的 self = [super init]; if (self) { for (NSString *suit in [PlayingCard validSuits]) { for (NSUInteger rank = 1; rank <= [PlayingCard maxRank]); ++rank) { PlayingCard *card = [[PlayingCard alloc] init]; card.rank = rank; card.suit = suit; [self addCard: card]; } } } return self; } @end
CardGameViewController
IBAction 和 IBOutlet 实际上都是 typedef void
只是为了方便 xcode,编译时会忽略