86437913 2019-06-20
这一课新建了几个其他的类以及在做出了第一个小demo
objectivec#import <Foundation/Foundation.h> #import "Card.h" @interface Deck : NSObject - (void)addCard:(Card *)card atTop:(BOOL)atTop; - (void)addCard:(Card *)card; - (Card *)drawRandomCard; @end
老爷爷讲希望能够“通用化”自己建的一些类,比如card,比如deck
所以这里的card,deck不仅仅能用于纸牌
比如我以后要做一个塔罗牌游戏也可以用同样的card deck类
Deck的实现方法
objectivec#import "Deck.h"
@interface Deck ()
@property (strong, nonatomic) NSMutableArray *cards;// of Card
@end
@implementation Deck
- (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;
}
@endPlayingCard是用来描述具体的Card的是怎样的
比如如果我要做一个塔罗牌那么这里就该是TaloCard
然后里面的内容也随之变化?
objectivec//Playingcard.h #import "Card.h" @interface PlayingCard : Card @property (strong, nonatomic) NSString *suit; @property (nonatomic) NSUInteger rank; + (NSArray *)validSuits; + (NSUInteger)maxRank; + (NSArray *)rankStrings; @end
objectivec//PlayingCard.m
#import "PlayingCard.h"
@implementation PlayingCard
- (NSString *) contents
{
NSArray *rankStrings = [PlayingCard rankStrings];
return [rankStrings[self.rank] stringByAppendingString:self.suit];
}
@synthesize suit = _suit;// because we provide setter AND getter
+ (NSArray *)validSuits
{
return @[@"♠︎",@"♣︎",@"♥︎",@"♦︎"];
}
- (void)setSuit:(NSString *)suit
{
if ([[PlayingCard validSuits] containsObject: suit]) {
_suit = suit;
}
}
- (NSString *)suit
{
return _suit ? _suit : @"?";
}
+ (NSArray *)rankStrings
{
return @[@"?",@"A",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"J",@"Q",@"K"];
}
+ (NSUInteger)maxRank{ return [[self rankStrings] count]- 1; }
- (void)setRank:(NSUInteger)rank
{
if (rank <= [PlayingCard maxRank]) {
_rank = rank;
}
}
@end这一段简直是信息量无穷,复制粘贴,磕磕碰碰最终的PlayingCard.m看起来很简洁又好看,信息量太大,我只能随手抓一点:
objectivec//PlayingCardDeck.h #import "Deck.h" @interface PlayingCardDeck : Deck @end
最后出现的这一个类是真实的包含52张牌的PlayingCardDeck,Deck的子类
objectivec//PlayingCardDeck.m
#import "PlayingCardDeck.h"
#import "PlayingCard.h"
@implementation PlayingCardDeck
-(instancetype)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同样,信息量很大
一堂课真的很大的信息量,假装理清楚几个类之间的关系了
Card Deck是通用类
PlayingCard PlayingCardDeck是针对这个游戏的具体类
假设做一个塔罗牌游戏的话,Card,Deck不用改,直接拿来用
PlayingCard → TaloCard 然后相应的内容需要改变
PlayingCardDeck → TaloCardDeck 相应的改变其init的方式,但是Talo的init就不会这么简单了,还要加上正立倒立等参数,drawRandomCard可能需要重写,或者就简单的加上一个概率数
Demo非常的精巧,虽然是一个简单的Flip Card 和 计数 Demo
objectivec#import "CardGameViewController.h"
@interface CardGameViewController ()
@property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
@property (nonatomic) int flipCount;
@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);
}
- (IBAction)touchCardButton:(UIButton *)sender
{
if ([sender.currentTitle length]) {
[sender setBackgroundImage:[UIImage imageNamed:@"cardback"]
forState:UIControlStateNormal];
[sender setTitle:@"" forState:UIControlStateNormal];
} else {
[sender setBackgroundImage:[UIImage imageNamed: @"cardfront"]
forState:UIControlStateNormal];
[sender setTitle:@"A♣︎" forState:UIControlStateNormal];
}
self.flipCount++;
}
@end很精巧,巧妙在于两处
好棒的课程,好大的信息量