LoginSignup
15
14

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-04-09

再帰的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、便利です!

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14