码迷,mamicode.com
首页 > 编程语言 > 详细

用swift重写stanford CS193P的纸牌游戏 (2)- PlayingCard,PlayingDeck和ViewCotronller

时间:2014-10-20 16:49:59      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   io   os   ar   for   

本系列编号基本对应stanford CS193P的课程编号,可能有一两节课的误差:比如我标(1)就对应Lecture 1,但有时我做得快了就变成(1)对应lecture 1的全部和lecture 2的一部分。

正文:

本文包括三个类,PlayingCard和PlayingDeck,两个单元测试类,和两个单元测试的用到的工具类。

写完之后的感觉:只要写完view controller这个程序就能在iphone上有个用户界面可以点了,刚做出来的时候还是挺有成就感的。在看swift的电子书只看了一两章的时候我就想把这个做出来,但是没写对。

后来在网上一搜发现别人也有在做这个,而且也在问这个怎么写。然后我借鉴他贴的代码把这个写出来了。再后面把书又读了几章,才决定再次重新开始继续看这个CS193P的课程,这次总算能跟上进度了。

 

具体值得记录的点有:

1.每个类都可以选TargetMembership,单元测试类应该只选CardGameTest,待测类应该同时选CardGame和CardGameTest。CardGame是我的应用名字。

 选对之后我就不用一直用默认提供的CardGameTests这个类了,我后面写了两个分开的单元测试类

2.PlayingCard类里,suit和rank做了合法值校验,比如rank不能大于13,suit不能取四种花色以外的值。

  这点在CS193P里,OC下用的做法是重载了这两个变量的setter,我的做法是用了swift的did set功能来校验。

3.PlayingCardTests是我写来测试PlayingCard的。原CS193P的老外是不写单元测试的。但我现在主职业是做测试的,所以我写了单元测试。

思路是一点一点校验PlayingCard类提供的所有东西,包括suit和rank的默认值或最大值,单个变量成功的设置、不成功的设置时的校验、

 4.PlayingCardDeckTests里我通过检查deck里所有元素来检查待测的init方法。

并且在其后做了2次抽牌,抽牌之前先记录当前卡组,做随机抽牌,抽牌之后先用正则表达式证明抽到的牌在抽牌之前在卡组中,再用正则表达式判断被抽出的牌在抽牌之后不再在卡组中。

5.DeckPrintHelper只是用来打印当前卡组中的所有牌和打印随机抽出的牌,为了减少重复代码用。Regex是我从网上找来的swift正则表达式封装好的工具类

代码:

 

首先是ViewController,里面只有一个IBOutlet和一个IBAction

 1 //
 2 //  ViewController.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-6-6.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 import UIKit
10 
11 class ViewController: UIViewController {
12                             
13  
14     @IBOutlet var flipCount : UILabel
15 
16     var flipCountNum: Int = 0
17     override func viewDidLoad() {
18         super.viewDidLoad()
19         // Do any additional setup after loading the view, typically from a nib.
20     }
21 
22     override func didReceiveMemoryWarning() {
23         super.didReceiveMemoryWarning()
24         
25         // Dispose of any resources that can be recreated.
26     }
27     
28     @IBAction func touchButton(sender : UIButton) {
29     //check the card title to know which side is upside
30     //then flip it by change the background image and title
31         if (sender.currentTitle.isEmpty){
32             sender.setTitle("A♣?", forState: UIControlState.Normal)
33             sender.setBackgroundImage(UIImage(named:"CardFront"),forState:  UIControlState.Normal)
34         } else {
35             sender.setTitle("", forState: UIControlState.Normal)
36             sender.setBackgroundImage(UIImage(named:"CardBack"),forState:  UIControlState.Normal)
37         }
38     //increse the flip count number
39         flipCountNum++
40     //update the flip count on screen
41         setFlipCount()
42     }
43     
44     func setFlipCount(){
45         // update the flip count by reset the text of the label
46         flipCount.text = "Flips:" + String(flipCountNum)
47 
48     }
49     
50 
51 }

 

然后是PlayingCard类,他是Card类的子类

 1 //
 2 //  PlayingCard.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-18.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 import UIKit
10 
11 class PlayingCard: Card {
12    //in did set, do a check and make it can‘t set to invalid value
13     var suit: String = "?" {
14         didSet {
15             //#####could improve or not: is there a simpler way to check if an element is in an array?
16             for it in PlayingCard.valid_suits{
17                 if it == suit{
18                 return
19                 }
20             }
21             suit = oldValue
22         }
23     }
24    //in did set, do a check and make it can‘t set to invalid value
25     var rank: Int = 0 {
26         didSet {
27             if rank > PlayingCard.max_rank{
28                 rank = oldValue
29             }
30 
31         }
32     }
33     
34     //all valid ranks in this game,"?" means unset
35     class var rank_strings:String[] {
36     return ["?","A","2","3","4","5","6","7","8","9","10","J","Q","K"]
37     }
38     
39     //define the max rank
40     class var max_rank:Int{
41     return rank_strings.count - 1
42     }
43     
44     //all valid suits
45     class var valid_suits:String[]{
46     return ["♥?","♦?","♠?","♣?"]
47     }
48     
49     init() {}
50 
51     //just pirnt the rank and suit, and rank 11 will be rank "J",and so n
52     func contents() -> String{
53         return PlayingCard.rank_strings[self.rank]+self.suit
54     }
55     
56     
57 }

接着是PlayingCardDeck类,他是Deck类的子类

 

 1 //
 2 //  PlayingCardDeck.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-20.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 import UIKit
10 
11 class PlayingCardDeck: Deck {
12     //just init the deck with 52 cards
13     init(){
14     super.init()
15     for suit in PlayingCard.valid_suits{
16         for (var rank = 1; rank <= PlayingCard.max_rank; rank++){
17             var card: PlayingCard = PlayingCard()
18             card.rank = rank
19             card.suit = suit
20             cards.append(card)
21             }
22         }
23     
24     }
25     
26 }

为了测试这两个类,写了两个单元测试:

PlayingCardTests

bubuko.com,布布扣
 1 //
 2 //  PlayingCardTests.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-18.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 import XCTest
10 
11 class PlayingCardTests: XCTestCase {
12 
13     override func setUp() {
14         super.setUp()
15         // Put setup code here. This method is called before the invocation of each test method in the class.
16     }
17     
18     override func tearDown() {
19         // Put teardown code here. This method is called after the invocation of each test method in the class.
20         super.tearDown()
21     }
22 
23     func testExample() {
24         // This is an example of a functional test case.
25         var p_card: PlayingCard = PlayingCard()
26         
27         println(PlayingCard.valid_suits)
28         println(PlayingCard.rank_strings)
29         println(PlayingCard.max_rank)
30         
31         
32         XCTAssert(PlayingCard.valid_suits == ["♥?","♦?","♠?","♣?"], "Pass")
33         XCTAssert(PlayingCard.rank_strings == ["?","A","2","3","4","5","6","7","8","9","10","J","Q","K"], "Pass")
34         XCTAssert(PlayingCard.max_rank == 13, "Pass")
35         
36         XCTAssert(p_card.contents == "??","Pass")
37         println(p_card.contents)
38        
39         p_card.suit = "♥?"
40         p_card.rank = 11
41         println("this card:\(p_card.contents)")
42         XCTAssert(p_card.contents == "J♥?","Pass")
43     
44         p_card.suit = "" // try to set an invalid value, it will be ignored  because I do the check in didSet of the suit
45         println(p_card.contents)
46         XCTAssert(p_card.contents == "J♥?","Pass")
47        
48        
49         p_card.suit = "♣?"
50         println(p_card.contents)
51         XCTAssert(p_card.contents == "J♣?","Pass")
52         
53         p_card.rank = 33
54         println(p_card.contents)
55         XCTAssert(p_card.contents == "J♣?","Pass")
56        
57         p_card.rank = 13
58         println(p_card.contents)
59         XCTAssert(p_card.contents == "K♣?","Pass")
60 
61     }
62 
63     func testPerformanceExample() {
64         // This is an example of a performance test case.
65         self.measureBlock() {
66             // Put the code you want to measure the time of here.
67         }
68     }
69 
70 }
View Code

PlayingCardDeckTests

bubuko.com,布布扣
 1 //
 2 //  PlayingCardDeckTests.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-20.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 import XCTest
10 
11 class PlayingCardDeckTests: XCTestCase {
12 
13     override func setUp() {
14         super.setUp()
15         // Put setup code here. This method is called before the invocation of each test method in the class.
16     }
17     
18     override func tearDown() {
19         // Put teardown code here. This method is called after the invocation of each test method in the class.
20         super.tearDown()
21     }
22 
23     func testExample() {
24         // This is an example of a functional test case.
25       
26         //to test the init method, I create a new deck
27         var card_deck: PlayingCardDeck = PlayingCardDeck()
28        
29        // the expected result
30         var expected_card_string: NSString = "A♥?,2♥?,3♥?,4♥?,5♥?,6♥?,7♥?,8♥?,9♥?,10♥?,J♥?,Q♥?,K♥?,A♦?,2♦?,3♦?,4♦?,5♦?,6♦?,7♦?,8♦?,9♦?,10♦?,J♦?,Q♦?,K♦?,A♠?,2♠?,3♠?,4♠?,5♠?,6♠?,7♠?,8♠?,9♠?,10♠?,J♠?,Q♠?,K♠?,A♣?,2♣?,3♣?,4♣?,5♣?,6♣?,7♣?,8♣?,9♣?,10♣?,J♣?,Q♣?,K♣?,"
31         
32         //print and check the deck, if it has all 52 cards
33         XCTAssert( DeckPrintHelper.printDeck(card_deck) == expected_card_string,"Pass" )
34         
35         //check the card number in the deck
36         XCTAssert(card_deck.cards.count == 52, "Pass")
37         
38         //draw a card and check again
39         var draw_this_card = DeckPrintHelper.drawRandomCard(card_deck)
40        // Regex("K♥?").is_found_in(DeckPrintHelper.printDeck(card_deck))
41        // Regex(",").is_found_in(DeckPrintHelper.printDeck(card_deck))
42         XCTAssert( Regex(draw_this_card.contents).is_found_in(expected_card_string),"Pass" )
43         // use regex to check if still contain this card
44        var after_draw_once = DeckPrintHelper.printDeck(card_deck)
45         XCTAssert( Regex(draw_this_card.contents).is_found_in(after_draw_once) == false,"Pass" )
46         XCTAssert(card_deck.cards.count == 51, "Pass")
47     
48         //do it again
49         draw_this_card = DeckPrintHelper.drawRandomCard(card_deck)
50     XCTAssert( Regex(draw_this_card.contents).is_found_in(after_draw_once),"Pass" )
51         XCTAssert( Regex(draw_this_card.contents).is_found_in(DeckPrintHelper.printDeck(card_deck)) == false,"Pass" )
52         XCTAssert(card_deck.cards.count == 50, "Pass")
53 
54 
55     }
56     
57     
58     
59     func testPerformanceExample() {
60         // This is an example of a performance test case.
61         self.measureBlock() {
62             // Put the code you want to measure the time of here.
63         }
64     }
65 
66 }
View Code

其中有写打印所有card的方法写在了工具类里

DeckPrintHelper

bubuko.com,布布扣
 1 //
 2 //  DeckPrintHelper.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-20.
 6 //  Copyright (c) 2014 Ting. All rights reserved.
 7 //
 8 
 9 //a help class which contains some test logic for reuse
10 import UIKit
11 class DeckPrintHelper: NSObject {
12    
13     // to print and return the deck string in my format
14     class func printDeck(deck: Deck) -> String{
15         var card_string: String = ""
16         println("\n_______________________________________")
17         println("Now these cards in deck")
18         for card in deck.cards{
19            card_string += ("\(card.contents),")
20         }
21         println(card_string)
22         println("_______________________________________")
23    
24     return card_string
25     }
26     
27     // to draw a random card while printing some comments
28     class func drawRandomCard(deck: Deck) -> Card{
29         var random_card = deck.drawRandomCard()
30         println("Now draw this random card:")
31         println(random_card.contents)
32         return random_card
33     }
34 }
View Code

还有一个正则表达式的工具类

Regex

bubuko.com,布布扣
 1 //
 2 //  Regec.swift
 3 //  CardGame
 4 //
 5 //  Created by colin.zt on 14-10-20.
 6 //  Copyright (c) 2014年 Ting. All rights reserved.
 7 //
 8 
 9 import Foundation
10 
11 class Regex: NSObject {
12     let internalExpression: NSRegularExpression
13     let pattern: String
14     
15     init(_ pattern: String) {
16         self.pattern = pattern
17         var error: NSError?
18         self.internalExpression = NSRegularExpression(pattern: pattern, options: .CaseInsensitive, error: &error)
19     }
20     
21     func is_found_in(input: String) -> Bool {
22         let matches = self.internalExpression.matchesInString(input, options: nil, range:NSMakeRange(0, countElements(input)))
23         var count = matches.count
24         return matches.count > 0
25     }
26 }
27 
28 //Usage Example: Regex("\\w{4}").is_found_in("abdddcd")
View Code

 

用swift重写stanford CS193P的纸牌游戏 (2)- PlayingCard,PlayingDeck和ViewCotronller

标签:des   style   blog   http   color   io   os   ar   for   

原文地址:http://www.cnblogs.com/sdet/p/4037172.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!