迷路
迷路生成アルゴリズムを実装した。 (壁伸ばし法)
1が壁で0が通路
1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1
Flood-fillアルゴリズムで通路(0)を2で塗りつぶす。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 2 1 1 2 2 2 1 2 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1
通路(0)がなくなっていれば、通路は連結している(壁に塞がれた通路は無い)と診断できる。
同様に壁(1)を3で塗りつぶす。
3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 3 2 3 3 3 3 2 3 3 3 2 3 3 2 2 2 3 2 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 2 2 2 3 2 3 3 3 3 3 3 3 3 3 3
壁(1)がなくなっていれば、壁は連結している(通路に回廊は無い)と診断できる
Rogue Likeななにか
ダンジョンの自動生成を作っているけどなかなかぐっとくる感じにならない
------------------------- ------- |.......................| |.....| |.......................+#######|.....| |.......................| #+.....| |.......................| |.....| |.......................| |.....| ---+-+------------------- --+---- # # # ####### ############################## # ## ---+----- --------++----- |.......| #####+.............| |.......| # |.............| |.......| # |.............| |.......| # |.............| |.......| # |.............| |.......| # ------------+-- |.......| # # |.......| # # |.......| # ######### |.......| # # ------------- |.......| # # |...........| |.......| # # ###+...........| |.......| # # # |...........| |.......+#### # # |...........| |.......| # # |...........| --------- -------+----- # -+----------- |...........+#### # |...........| # |...........| ## |...........| ----+---- |...........| |.......| ------------- |.......| |.......| |.......| |.......| ---------
Swift LANGUAGE GUIDE を読んで書いたブログエントリの一覧
- The Basics - 錯綜
- Basic Operators - 錯綜
- Strings and Characters - 錯綜
- Collection Types - 錯綜
- Control Flow - 錯綜
- Functions - 錯綜
- Closures - 錯綜
- Enumerations - 錯綜
- Classes and Structures - 錯綜
- Properties - 錯綜
- Methods - 錯綜
- Subscripts - 錯綜
- Inheritance - 錯綜
- Initialization - 錯綜
- Deinitialization - 錯綜
- Optional Chaining - 錯綜
- Error Handling - 錯綜
- Type Casting - 錯綜
- Nested Types - 錯綜
- Extensions - 錯綜
- Protocols - 錯綜
- Generics - 錯綜
- Automatic Reference Counting - 錯綜
- Memory Safety - 錯綜
- Access Control - 錯綜
- Advanced Operators - 錯綜
Advanced Operators
昨日に引き続き https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html を読む。
- Swiftの算術演算子はオーバーフローしない
Int16.max + 1
はエラー- オーバーフローする演算子
- オーバーフロー 加算
&+
- オーバーフロー 減算
&-
- オーバーフロー 乗算
&*
- オーバーフロー 加算
- 二項
static func + (left: T, right: T) -> T {…}
- 単項前置
static prefix func - (v: T) -> T {…}
- 複合代入
static func += (left: inout T, right: T) {…}
- デフォルトの代入演算子はオーバーロードできない
- 3項演算子はオーバーロードできない
- 等価
static func == (left: T, right: T) -> Bool {…}
プロトコルEquatable
をconform ==
を実装したら、ふつう!=
は実装する必要はないEquatable
プロトコルをconformすると宣言したら Swift が==
を合成してくれる場合- Equatable型の格納プロパティだけ持ってる構造体
- Equatable型の関連型だけ持つ列挙型
- 関連型を持たない列挙型
- カスタム演算子
operator
宣言は ファイルスコープでなければならない prefix operator ☹
static prefix func ☹ (v: T) -> T {…}
infix operator ☺: AdditionPrecedence
static func ☺ (left: T, right: T) -> T {…}
- 演算子の優先順位は Swift Standard Libraryのほうで決まっているみたい
さてLANGUAGE GUIDEがひととおり終わったので なんかiOSアプリを作ってみたい。ゲームとか。 LANGUAGE REFERENCEを読むのは重箱の隅ほど美味しそうだけど深みにハマっていくのもアレなので。
Access Control
昨日に引き続き https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html を読む。
- アクセスレベルは5段階
enum AccessLevel { case `open` case `public` case `internal` case `fileprivate` case `private` }
- レベルの高低は、
open
が最高(最も制限が少ない)、private
は最低(最も制限が多い) open
とpublic
の違いはmoduleを越えてsubclass化とoverrideできるかどうか- エンティティは より低い(より制限的な)他のエンティティが出てくるようなやつは 定義できない
public
な変数は、internal
やfileprivate
,privte
な型で定義できない- 関数は、パラメータや返り値の型より高いアクセスレベルにできない
- デフォルトのアクセスレベルは
internal
- 多くの場合、コードに明示的なアクセスレベルを指定する必要はありません。
- 単純な単一ターゲットアプリを書く場合は、
internal
で充分要件を満たしている - フレームワーク開発では APIを
open
かpublic
にする - 単体テスト可能なのは
open
かpublic
だけどinternal
なのをテストしたいなら@testable
アトリビュートを付ける - 型のアクセスレベルは、メンバーの暗黙のアクセスレベルになる
- privateかfileprivateにすると、メンバーの暗黙のアクセスレベルはprivateかfileprivateになる
- internalかpublicにすると、メンバーの暗黙のアクセスレベルはinternalになる
- タプルのアクセスレベルは、中身から最も低いアクセスレベルのやつになる
- 関数の暗黙のアクセスレベルは、パラメータと返り値型のなかから最も低いやつになる
- 列挙型の個々の
case
は、列挙型のレベルと同じになる。個々のcase
に異なるレベルはつけられない - 列挙型のrawValueと 関連付けられた値は、列挙型と同じか高いアクセスレベルでなければならない
- ネストされた型の暗黙のレベル
private
型にネストされた型は、private
fileprivate
型にネストされた型は、private
public
かinternal
型にネストされた型は、internal
- サブクラスは、スーパークラスより高いレベルにできない
- オーバーライドは、スーパークラスでのアクセスレベルより高くできる
- 定数変数プロパティは、その値の型のレベルより高くできない
- subscriptはインデックス型・返り値型より高くできない
- プロパティ等のgetterとsetterの暗黙のアクセスレベルは、そのプロパティ等と同じになる
- setterにgetterより低いアクセスレベルを与える
public private(set) var x = 0
- イニシャライザは 型の レベルより低くできる
required
イニシャライザは型のレベルと同じでなければならない- デフォルトのイニシャライザの暗黙のレベルは、型のレベルと同じ(
public
以外)public
型のデフォルトイニシャライザの暗黙のレベルはinternal
- 構造体のmemberwiseイニシャライザは、
- メンバーのレベルのうち一番低いやつが
private
ならprivate
- メンバーのレベルのうち一番低いやつが
fileprivate
ならfileprivate
- それ以外は
internal
- メンバーのレベルのうち一番低いやつが
- プロトコルの各要素のアクセスレベルは、プロトコルのレベルと同じで、違えられない
- プロトコル継承は、元のプロトコルのレベルまで持てる。高くはできない。
- プロトコルのconformは、型のレベルよりも低く出来る
- 型がプロトコルをconformするという文脈は、型のレベルとプロトコルのレベルの最小値
- extension で定義したメンバーの暗黙のレベルは、元の型のものと同じ(最大internal)
- extensionにデフォルトのレベルを指定
private extension {…}
- extensionでプロトコルをconformする場合は extensionのレベルは指定できない。替わりにプロトコルのレベルがデフォルトのレベルになる
- 元の型と同じソースファイルに書いたextensionから、元の型のprivateにアクセスできる
ふつうinternalだよね〜と言われたので、とりあえず全て無指定で生きて行こうと思うの。
Memory Safety
昨日に引き続き https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html を読む。
- シングルスレッドでも競合は起きる
- 次のすべての条件を満たす2つのアクセスがある場合、競合が発生する
- 少なくとも1つは書き込み
- メモリ内の同じ場所にアクセスする
- 期間が重複する
- メモリアクセス期間には「瞬時」か「長期」がある
- ふつうは瞬間的。いくつかの場合「長期アクセス」がある。長期アクセスは他のアクセスとオーバーラップできる
inout
パラメータの書き込みアクセスは、他の非inout
パラメータの評価が全て終わった後、 関数呼び出しの期間続く- 競合するとランタイムエラー
- ひとつの解決方法は、値をコピーすること
- 2つの
inout
パラメータをとる関数に、同一の変数を渡すとコンパイルエラー - 構造体の
mutating
メソッド は メソッド呼び出しの期間self
への 書き込みアクセスを持つ x.mutatingMethod(&x)
→コンパイルエラー- 構造体・列挙型・タプルの値の一部を変更すると値全体が変更される場合に競合するおそれがある
- 次の条件が適用される場合、コンパイラは、構造体プロパティへの重複アクセスが安全であることを証明できる
ちょっと意図しないところで出そうで怖いけど、 コンパイルエラーでもランタイムエラーでも「modification requires exclusive access」と言われるので、 言われたらまあ気づけるかな、と思う。