1. Qiita
  2. 投稿
  3. Swift

Swiftの再帰的enumとパターンマッチでズンドコ

  • 17
    いいね
  • 0
    コメント

再帰的enumを使ってみたかったので今更ながらズンドコキヨシを書いてみました。
ズンドコキヨシまとめ

import Foundation

enum Zundoko: CustomStringConvertible {
    case Start
    indirect case Zun(Zundoko)
    indirect case Doko(Zundoko)
    indirect case Kiyoshi(Zundoko)
    var description: String {
        switch self {
        case Start: return "スタート!"
        case Zun(let zd): return "\(zd)\nズン"
        case Doko(let zd): return "\(zd)\nドコ"
        case Kiyoshi(let zd): return "\(zd)\nキ・ヨ・シ!"
        }
    }
    func zundoko() -> Zundoko {
        return (arc4random_uniform(2) > 0) ? Zun(self) : Doko(self)
    }
}

var zd: Zundoko = .Start
while true {
    if case .Doko(.Zun(.Zun(.Zun(.Zun)))) = zd {
        zd = .Kiyoshi(zd)
        break
    }
    zd = zd.zundoko()
}
print(zd)

if case .Doko(.Zun(.Zun(.Zun(.Zun)))) = zd
だけでズンドコ判定が済んでしまうのが非常にいい感じです。

while caseでパターンの否定が使えればもう少しスッキリしそうなのですが、
調べた限りでは書き方がわかりませんでした。。

短めバージョン

whileを無くして再帰にしました

import Foundation

enum Zundoko: CustomStringConvertible {
    case Start
    indirect case Zun(Zundoko), Doko(Zundoko), Kiyoshi(Zundoko)
    var description: String {
        switch self {
        case Start: return "スタート!"
        case Zun(let zd): return "\(zd)\nズン"
        case Doko(let zd): return "\(zd)\nドコ"
        case Kiyoshi(let zd): return "\(zd)\nキ・ヨ・シ!"
        }
    }
    func zundoko() -> Zundoko {
        if case .Doko(.Zun(.Zun(.Zun(.Zun)))) = self {
            return .Kiyoshi(self)
        }
        return (arc4random_uniform(2) > 0) ? Zun(self).zundoko() : Doko(self).zundoko()
    }
}
print(Zundoko.Start.zundoko())

再帰的enum、便利です!