用Swift写围棋App-06解析器初版

作者: MarkNote | 来源:发表于2015-12-28 22:56 被阅读919次

tags: App, 开发随笔

已完成章节索引

用Swift写围棋App-00序
用Swift写围棋App-01准备工作
用Swift写围棋App-02建立工程
用Swift写围棋App-03StoryBoard
用Swift写围棋App-04棋盘
用Swift写围棋App-05初识棋谱
用Swift写围棋App-06解析器初版
用Swift写围棋App-07解析器改进
用Swift写围棋App-08绘制每一手棋
用Swift写围棋App-09分片算法
用Swift写围棋App-10气的算法
用Swift写围棋App-11算法改进

了解了棋谱的格式后,我们终于可以撸代码了!
我们来尝试一下TDD,也就是Test Driven Development,测试驱动开发。
先定义相关的Model,开始的时候不用尽善尽美,满足最初的测试就好了。后面再不断改进好了。
先定义一个类Location,它表示每一步棋放在那个位置:

class Location: NSObject {
    var x:Int
    var y:Int
    init(x:Int,y:Int) {
            self.x = x
            self.y = y
    }
}

然后定义Move,它表示一步棋:

class Move: NSObject {
    
    var location: Location
    var type:StoneType
    
    init(type:StoneType,loc:Location) {
        self.location = loc
        self.type = type
    }

}

这里StoneType用来区别黑棋和白棋,是一个枚举类型:

enum StoneType: Character {
    case Black = "B"
    case Withe = "W"
}

定义一个SGFParser类,它就是我们的解析器了。先写一个假方法:

public class SGFParser {
    
    func parse(kifu:String)->GameInfo{
        return GameInfo()
    }
    
}

然后写测试用例:

import XCTest
@testable import GoTao

class GoTaoTests: XCTestCase {
    let parser = SGFParser()
    func testKifuCount() {
        let kifu = ";B[qd];W[dc];B[pq];"
        let result = parser.parse(kifu)
        assert(3==result.allMoves.count)
        
        
    }
 }

按command +U,运行测试。编译通过,但是测试失败:

assertion failed: : file GoTaoTests.swift, line 26

这正是我们预期的!因为我的解析器还没写呢!
改进一下解析器为如下版本:

import Foundation

public class SGFParser {
    
    func parse(kifu:String)->GameInfo{
        let game = GameInfo()
        let moves = kifu.characters.split { $0 == ";" }
            .map(String.init)
            .filter{($0.hasPrefix("B[")||$0.hasPrefix("W["))&&$0.characters.count==5}
            .map{Move(step: $0 as String)}
        print(moves)
        game.allMoves = moves
        return game
    }
    
}

这里我期望可以直接从B[ab]这样的字符串直接构建Move实例,所以需要改进一下Move这个类,如下:

import Foundation

class Move: NSObject {
    
    var location: Location
    var type:StoneType
    
    init(type:StoneType,loc:Location) {
        self.location = loc
        self.type = type
    }
    init(step:String){
        let color =  StoneType(rawValue:step[step.startIndex])
        let x = step.asciiValueAt(pos: 2) - "a".asciiValue
        let y = step.asciiValueAt(pos: 3) - "a".asciiValue
        
        self.type = color!
        self.location = Location(x: x,y: y)        
    }

}

再按command + U,奇迹出现了:

Screen Shot 2015-12-28 at 10.51.13 PM.png
居然通过了测试!
虽然这只是最简单的一个版本,它却麻雀虽小,五脏俱全,已经具备了一个优秀应用的架子。
很好!
再次Commit和 Push代码到github https://github.com/marknote/GoTao
下面就需要多写几个测试用例,来改进解析器了。

相关文章

网友评论

  • 柴茝:支持! 有想法! 加油!
  • 1ab444348f0b:这技术文都能发简书?
    MarkNote:@布良鸟 客气啦,多谢鞭策!不过话说其实我感觉简书上程序员挺多的
    1ab444348f0b:@MarkNote 额,我想你误会了,我不是说写的不行
    我以为简书上只发偏文学类的文章,只能说我少见多怪,新来的别介意。。
    MarkNote:@布良鸟 惭愧,目前是简陋了些 还在改善中 我想把整个过程漏出来给有需要的人参考。不过据说牛逼的Google 创始人最初的时候还在论坛上向人请教遇到的Java 编程问题呢。简书里面牛逼的文章有,但是似乎也不拒绝浅显的文字吧。

本文标题:用Swift写围棋App-06解析器初版

本文链接:https://www.haomeiwen.com/subject/istihttx.html