tags: Apps, 開發(fā)隨筆
已完成章節(jié)索引
用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算法改進
在上一片分片完成之后艺糜,計算每一組棋的棋就是水到渠成的事了髓涯。
我們還是從最基本的概念入手。一個棋子在棋盤上,與它直線緊鄰的空點是這個棋子的“氣”管嬉。
如下圖执隧,一個不在邊框上的棋肆糕,其周圍有4個相鄰的空點态鳖,即ABCD四個位置。
將這個情形寫成測試用例用swift描述就是:
func testLibertyOne(){
let kifu = "(;;B[qq])"
let game = parser.parse(kifu)
game.currentMove = 0
let groups = game.assignGroups()
assert(groups.count == 1)
assert(groups[0].calculateLiberty(game.occupiedLocations()) == 4)
}
如果再下一手黑棋和它相連耿芹,成下面的樣子:
則2顆棋子連起來了崭篡,它們一共有ABCDEF 6口氣。將情形二描述成測試用例:
func testLibertyTwo(){
let kifu = "(;;B[qq];B[qr])"
let game = parser.parse(kifu)
game.currentMove = 1
let groups = game.assignGroups()
assert(groups.count == 1)
assert(groups[0].calculateLiberty(game.occupiedLocations()) == 6)
}
如下圖所示吧秕,這2顆有6口氣的棋琉闪,如果它們的6個氣位都被白棋圍住的話,則氣為0砸彬,成了死子颠毙。
將這中情形描述為測試用例:
func testLibertyThree(){
let kifu = "(;;B[qq];B[qr];W[qp];W[rq];W[rr];W[qs];W[pr];W[pq])"
let game = parser.parse(kifu)
game.currentMove = 7
let groups = game.assignGroups()
//assert(groups.count == 2)
assert(groups[2].calculateLiberty(game.occupiedLocations()) == 0)
}
有了測試用例后,實現(xiàn)起來挺簡單拿霉,每一顆棋吟秩,其氣數(shù)就看它周圍的空點是否被其他棋子所占:
// Move類中
func calculateLiberty(occupied:[Location])->Int{
var liberty = 4
if (location.x == 0 || location.x == 19 || location.y == 0 || location.y == 19){
liberty = 3
if (location.x == 0 && location.y == 0
|| location.x == 19 && location.y == 0
|| location.x == 0 && location.y == 19
|| location.x == 19 && location.y == 19
){
liberty = 2
}
}
for l in occupied {
if self.location.isEqual(l) {
continue
}
if self.location.isConnectedTo(l) {
liberty -= 1
}
}
return liberty
}
而每一片棋的氣則是這片棋中所有棋子氣數(shù)之和:
//在MoveGroup類中
func calculateLiberty(occupied:[Location])->Int{
var liberty = 0
for m in allMoves {
liberty += m.calculateLiberty(occupied)
}
return liberty
這個方法我們還可以用swift的函數(shù)式編程特性咱扣,寫得更像黑魔法一點 :)
//在MoveGroup類中
func calculateLiberty(occupied:[Location])->Int{
return allMoves.reduce(0, combine:{$0 + $1.calculateLiberty(occupied)} )
}
簡單的弄一下三個測試用例居然都過了绽淘。
非常好!
現(xiàn)在push最新的代碼到github:https://github.com/marknote/GoTao
剩下的就是一些細節(jié)了闹伪』γ基本可以收工了。