第26回目:Swiftでオセロを作る(Part3)2014-08-25筆者:村田こんにちは。夏休み明けの1週間でしたがリハビリ完了しましたか?これからまた頑張っていきたいと思います。お盆も過ぎたのでどんどん涼しくなってくるはずですね。秋は空気が澄んでいて過ごしやすく、スポーツ、読書、食べる(!)、プログラミング(?)、色々いい季節です。個人的には体育館に行ったりするなど、少し体を動かしたいなと思うのですがどうなることか。前回はオセロの盤面を表示し、タッチした場所に黒石を置けるところまで作成しました。続きに行きたいところですが、その前にXcodeのbeta5へ対応することにします。beta4だけで進めようかとも思いましたが、せっかくbeta5をダウンロードしたので追いかけようかと。いうわけで前回までのコードをbeta5で早速コンパイルしてみます。今回の話のネタにはなりますが:P以下のようにOthelloViewのイニシャライザにrequiredという識別子を付与しなければなりませんでした。{super.init(coder:aDecoder)・・・}リリースノートや新しいマニュアルでrequiredについて調べてみると、以下のサンプルのようにサブクラスでイニシャライザの実装を強制する機能のようでした。サブクラスでinitの実装が必須...}}ただし、サブクラスで1つ以上の何らかのイニシャライザを定義する場合にのみ強制されます。何もイニシャライザを定義しない場合はrequiredイニシャライザをサブクラスでオーバライドする必要はありません。requiredイニシャライザとは何なのでしょう。JavaやC++など他の言語において、抽象クラスの空っぽのメソッドをサブクラス側で実装するように強制する機能は有名です。UIViewは抽象クラスではありませんし、上記のSuperClassのinitは抽象メソッドではありません。Objective-Cを知っている方はもうお分かりかもしれませんが、requiredは指定イニシャライザのことのようです。ObjCではお作法やノウハウとして、スーパークラスの指定イニシャライザをサブクラス側でオーバーライドするようにしていましたが、Swiftではコンパイラによってこのルールが強制されることになったようです。指定イニシャライザって何なのさってことです。Objective-Cの話になってしまいますが、Swiftのrequiredの理解にも繋がりそうですので紹介したいと思います。以下にObjCで定義したクラスを使って考えましょう。_b);}@end何だか適当なクラス名ですが、ClassABはNSObjectを継承したクラスです。NSObjectはObjCでのルートクラスで、JavaでいうObjectのようなものです。ClassABは_aと_bというメンバ変数を持っています。initWithA:andBというイニシャライザの実装を見てみましょう。init]でスーパークラス(NSObject)のイニシャライザを呼び出してから、自分のメンバを全て初期化しています。initializer)」と言います。一つのinitWithAというイニシャライザは指定イニシャライザを利用して初期化処理しています。これを副次的イニシャライザと言ったりします。ポイントは「指定イニシャライザは必ず呼ばれる」ということです。初期化するのに副次的イニシャライザを呼び出したとしても、指定イニシャライザにたどり着きます。いうか、そうなるようにイニシャライザを設計しましょう。以下のmain関数から実際に使ってみます。0;}@autoreleasepoolは詳しく説明しませんがObjCでメモリを自動解放する記述です。showメソッドの結果は想像できるでしょうか。200」と表示されます。指定イニシャライザについては一旦ここまでにします。ここからちょっと遠回りな脱線です。main関数のオブジェクト生成式をもう一度見てみます。alloc]のallocはNSObjectのクラスメソッドで、ここで必要なサイズのメモリを確保しClassABオブジェクトを生成しています。このとき_aと_bなどメンバ変数のメモリは全て0に初期化されます。ここまではいいですか?その後、生成されたオブジェクトに対してinitWithA:andBというメソッドを呼び出して初期化しています。ところで、この初期化メソッドを呼ぶことは必須ではありません。ふむむ、つまりinit〜といったメソッドは「イニシャライザ」なんて呼ばれていますが、showメソッドと同じ普通のメソッドなのです。init]のように続けて呼び出すことがほとんどですが必須ではありません。(なお、イニシャライザを他のメソッドと”全く同じ”と言ってしまうことは、ARCシステムを考えると語弊がありますが今回は触れません)まだ脱線の続きです。えっと唐突ですが、ObjCにはコンストラクタがありません。allocを呼び出した後、明示的にイニシャライザを呼ぶことで代用していますが、これはC++のコンストラクタとは異なります。C++のコンストラクタではメモリ確保とメンバの初期化は不可分ですが、コンストラクタのないObjCでは明示的に初期化メソッドを呼んでいます。C++ではコンストラクタを仮想化できず(※)、コンストラクタ呼び出しは静的にディスパッチされます。それに対しObjCのイニシャライザはオブジェクトに対するメソッド呼び出しなので、継承ツリーを辿り動的にディスパッチします。同じC言語からオブジェクト指向を取り入れ進化した2つの言語。一方は型(クラス)に重きを置き、一方はオブジェクトに重きを置いているように感じます。このあたりの話、Simulaに影響を受けたC++と、Smalltalkに影響を受けたObjCという影響元の言語の違いなんでしょうか。SimulaもSmalltalkも勉強したことが無いので、いつか調べてみたいです。Method)でエミュレートします少し軌道を戻しましょう。先程のClassABのオブジェクト初期化ではinitWithA:andBメソッドを使いましたが、メソッドなら何でもいいです。NSObjectのinitメソッドを呼び出してもいいです。0;}この場合、NSObject内のメンバは正しく初期化されますが、ClassABの_aと_bは0のままです。0のままでオブジェクトとして成り立つなら特に問題はありません。_aと_bは最初に必ず-1に初期化しなければ不整合になるという場合は困りますね。C++ではコンストラクタがあるので問題になりませんが、ObjCでは上記のようなスーパークラスのイニシャライザ呼び出しが可能なので、不整合なオブジェクトが生成される可能性があるのです。したらいいのでしょう。解決策は「スーパークラスの指定イニシャライザをオーバーライドすること」です。NSObjectの指定イニシャライザはinitですのでClassABでオーバーライドしてみましょう。andB:-1];}@end内部でinitWithA:andBメソッドを呼び出してそれぞれ-1に初期化するようにします。init];と呼び出したとしても、NSObjectのinitではなくオーバーライドしたClassABのinitが呼ばれるため、正しく初期化することができます。大分冗長に説明していますがそろそろまとめましょう。ObjC/Swiftでは必ずしも自クラスのイニシャライザが呼ばれるとは限りません。スーパークラスのイニシャライザが呼ばれるかもしれないのです。そこでスーパークラスの最も偉い?指定イニシャライザをオーバーライドし、その中でオブジェクトの不整合が発生しないように初期化する必要があるのです。ObjCではプログラマが気をつけるだけでしたが、Swiftでは指定イニシャライザをrequiredにすることでサブクラスでのオーバーライドを強制できるようにしているのですね。メンバ変数が無い場合など、そもそも自前の初期化が必要ないクラス、つまり「イニシャライザを一つも定義していないクラス」であれば、スーパークラスのrequiredを実装していなくても怒られません。現在のSwiftコンパイルエラーからは指定イニシャライザが何かまでは分かりません。その都度、スーパークラスやプロトコルのリファレンスを調べる必要があります。個人的にはコンパイラやfix-it機能で実装すべきrequiredイニシャライザを教えてくれたらな〜と思うのですが。SwiftというかObjective-Cの話ばかりで結局オセロのコードは進みませんでしたが、今回はここまでにしたいと思います。第25回目:Swiftでオセロを作る(Part2)2014-08-15筆者:村田こんにちは。お盆休みいかがお過ごしでしょうか。私は暑さ凌ぎも兼ねて地元福生市の図書館に通っています。図書館はエアコンが強すぎず静かで、背丈を超える本棚に囲まれるているとちょっと贅沢な気分になれるので大好きです。この図書館は周囲に緑があるのも嬉しいです。皆さんのお住まいの地域にはどんな図書館がありますか?どの図書館にも趣、特色があって楽しいです。川崎市武蔵小杉の駅ビルに昨年オープンした図書館に行ってきました。奇麗で蔵書も多くシャレオツでした。以前武蔵小杉に住んでいたのですが、当時オープンしていたら絶対通っていたな〜と羨ましく思いました。そんなわけで、夏休みにお時間がある方は図書館に足を運んでみたらいかがでしょうか。リラックスして贅沢な気分になれるかもしれません:-)さて、オセロの続きですね。ところで早くもXcode6のbeta5がリリースされてしまいました。リリースノートを眺めてみるとSwift言語自体にも機能追加があるようでした。Optional型の使い勝手向上は分かりましたが、その他の機能はよく分かりませんでした。これまでのbetaリリースは割と頻繁にXcodeがクラッシュしていたので、なるべく新しいリリース版を使うべきですが、とりあえず今回はbeta4で進めたいと思います。最初の目標はオセロの盤面を画面に表示させることでした。オセロの盤面は8x8マスなので2次元配列で表現するのが自然に扱えそうです。Swiftの配列について少し実験しましょう。ちなみにSwiftの実験にはXcode6のPlaygroundという環境を使うと楽です。「リアルタイムのREPL」という感じで、コンパイルやRunさせなくても、コードを書いた瞬間に式の評価結果が画面に表示されるという代物です。頻繁なクラッシュがなければね〜ボソッ(-_-)Swiftの配列はオブジェクトです。配列型はArray<T>と表現します。大括弧を使って[T]とも書けます。TはIntやStringなど配列の中身の型です。[1,2,3]Int型の配列array1を定義してみました。varは変数宣言の識別子です。var変数は書き換え可能(mutable)です。以下のように異なる配列オブジェクトを参照するように書き換えることができます。[4,5,6]中身も書き換えることもできます。9次は[]を使って文字列の配列を定義してみます。こっちの[]を使った型宣言の書き方のほうが分かりやすいですね。"three"]letは定数宣言の識別子です。書き換え不可(immutable)です。参照値を書き換えたり、中身の変更もできません。error上記例ではコロンの後ろにArray<Int>や[String]と型注釈を書いてコンパイラに変数の型を教えています。Swiftでは初期値を与えれば初期値の型から型推論できるので型注釈を省略できます。"three"]配列はオブジェクトなのでいくつかの便利なメソッドやプロパティを備えています。配列の要素数を返すプロパティがあります。3あとは関数型プログラミングのリスト操作でおなじみのトリオ、map,reduce,filter関数もあります。これらは関数を引数に渡す高階関数ってやつです。Swiftではクロージャを引数に渡すことになります。map関数は配列の各要素に対して、もらったクロージャを作用させて新しい配列を作ります。元の配列から新しい配列を作るだけで元の配列は何も変わりません。8]Swiftのクロージャは中括弧{}で括ります。inの前がクロージャの型です。Intなので、IntをもらってIntを返すクロージャです。もらった引数nを倍返ししています。ここからが面白いところです。Swiftの配列はオブジェクトですが、コピー動作時にプリミティブ値のように振る舞います。array2は変わらない!!ほ〜。JavaやC#のように配列をオブジェクトの参照として扱う言語とは異なります。これらの言語ではcopyやcloneなどのメソッドを呼び出して、明示的に新しい配列オブジェクトを生成する必要がありますが、Swiftでは不要です。配列をオブジェクトとして意識させるのではなく、「値」として扱わせるという観点は関数型プログラミングのアプローチと言えるでしょう。配列を常にプリミティブとして扱っていては不要なコピーコストが生じる可能性があります。コンパイル時にフロー解析をするのか、あるいは配列の中身の書き換えや要素数の変更時までコピーを遅延させているのか分かりませんが、いずれにせよプログラマが意識しないところでコピーコストの最小化が行われていると考えられます。Swiftでは文字列やディクショナリもプリミティブ値のように振る舞います。str2は変わらないディクショナリの例。[“age”:35]さて話をオセロの盤面に戻します。2次元配列の中身の型はどうしましょう。各マスの取りうる状態としては黒石、白石、空きとなります。これらをオブジェクト(Enum)として表すこともできますが、今回は単純なInt値で表したいと思います。直値はやめて定数の名前ぐらいは用意しておきます。Swiftはグローバルスコープやクラススコープに定義を書けるので、本記事で特に断りがなければグローバルスコープに定義を書いているものとします。クラススコープに記述する場合は、メンバ変数、メソッドなどと言うようにします。2盤面はメンバ変数として以下のように定義しました。Intの2次元配列です。Array<Array<Int>>と書いてもいいです。board:[[Int]]}ついでに盤面の初期状態を定数として定義しておきましょう。中央4マスにはあらかじめ石がおいてあります。以下の定義をよ〜く見ると10x10マスになっています。盤面の周囲を番兵値(0)でぐるりと囲んでいます。役に立つか分かりませんが、今後のアルゴリズムにおいて配列の範囲チェックを省略することが狙いです。[[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,2,1,0,0,0,0],[0,0,0,0,1,2,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],];Viewの初期化時に上記の盤面初期値をboardメンバにコピーしましょう。前回OthelloViewをStoryboardに登録して簡単な動作確認をしましたが、Storyboardに登録したViewは初期化時に以下のイニシャライザが呼ばれます。{}}このinitの中で盤面の初期化をします。それとNSCoderのinitは親クラスのイニシャライザを呼ぶ必要があります。initboardsuper.init(coder:aDecoder)}盤面1マスの辺の長さ(size)と1列1行目の画面上の座標(top,left)を画面の大きさから計算します。2...}}次は盤面の描画です。オーバーライドしたdrawRectの中でグラフィックスコンテキストを使うとViewに絵を描くことができます。黒丸を書くコードでちょっと練習してみましょう。100))}CG〜で始まる関数群はCoreGraphicsライブラリの関数です。基本的な手順は、(1)contextを取得して、(2)contextに線の太さや色を指定して、(3)描画関数を呼ぶ、これだけです。色オブジェクトは毎回描画時に生成するとコストがかかりますので、View初期化時に生成しておきます。白、黒、盤面の緑です。緑はちょっと明るい色にしました。CoreGraphicsAPIに渡す色はCGColorオブジェクトですので、UIColorからCGColorに変換しておきます。alpha:1.0).CGColor...}ちょっと寄り道してSwiftのfor文の使い方を確認しましょう。C言語風の書き方で0〜9をコンソールに表示できます。iは書き変わるのでvarにします。{println(i)}次のfor-in文は、他の言語ではfor-eachとか拡張for文と呼ばれているものです。inの後はイテレーションできる配列やRangeオブジェクトを書くことができます。{println(i)}SwiftのRangeの書き方は、0..<10で10を含まない範囲(0〜9)、0...10で10を含む範囲(0〜10)となります。それでは以下に描画関数を一気に載せました。rect)}}}}マスの位置計算がちょっと分かりにくいかもしれません。2重のfor文は番兵を除くため1〜8で変化させます。board[y][x]のx,yの順番に気をつけて下さい。xのループの方がyより早く回り、左から右へ、次に上から下へマスの塗りつぶしが進むイメージです。CGFloat()の部分はIntからCGFloatへの型キャストです。ここまででオセロの初期状態がiPhoneシミュレータに表示されるはずです。(文字数制限にひっかかったので次の記事に続きます・・・)第25回目の続き2014-08-15次に画面にタッチした場所に石を置けるようにします。画面タッチのイベントハンドラはtouchesBeganメソッドですので、これをオーバライドしましょう。{}touches引数の中にタッチした位置情報が入っています。touchesを解析して盤面のマス位置情報(x列,y行)に変換して返すメソッドを作りたいと思います。メソッド名はgetPosにしたいと思います。タッチした画面位置が盤面から外れた場所であればnilを返したいと思います。ここでSwiftのOptional型を登場させましょう。成功時にはオブジェクトを返し、失敗時にはnilを返すという関数はよくあるパターンです。関数呼び出し側では成功したかnilチェックをするわけですね。Swiftでは「値またはnil」という表現をOptional型としてカプセル化できます。Optional型は型名の末尾にクエスチョンマークを付けます。Int?という型は「何らかの数値かまたはnil」ということを表す型です。以下の例でnumOfApplesはIntオプショナル型のvar変数です。3という数値やnilを代入できます。nilIntとInt?は型として異なるものです。IntからInt?への型変換は暗黙的に行われますが、逆にInt?からIntへは明示的な変換が必要です。Intの値を引数にとる関数にInt?型の値をそのまま渡すことはできません。Int?型の値はnilかもしれませんのでInt型に単純に変換できないのは当然ですね。そこでInt?型の値をInt型に変換する(Int値を取り出す)必要がある場合は、Optional変数名の後にエクスクラメーションマークを付けることで取り出すことができます。Int?からIntへ変換。生のInt値の取り出しとも言える。3もしOptional変数にnilが入っていたら、エクスクラメーションで型変換をしようとしたときに例外が発生します。nilをInt値には変換できないということです。例外発生C言語をご存知の方なら、ポインタ操作に近いと感じるかもしれません。メモリアドレスとは関係ないので、あくまで操作のお作法が似ているという点においてですが。以下はC言語のポインタ操作の例です。numOfApples!上記C言語の最後の文はアスタリスクを使ったポインタの間接参照ってやつです。このときnumOfApplesというポインタ変数がNULLであればメモリアクセス例外が発生するわけです。Swiftのエクスクラメーションと似てますね。そんなわけで、オプショナル値から安全に型変換を行いたければ、事前にnilではないことをチェックする必要があります。\(apples)")}このような「事前にnilチェックしてからInt値への変換」というコードはあちこちに出てくるので、Swiftにはもう少しスッキリ書く記法が用意されています。\(apples)")}letの部分はvar変数でも構いません。numOfApplesがnilの場合は型変換を行わずif文の中にも入りません。numOfApplesに値が入っている場合は、型変換してInt値をapples変数に取り出し、if文の中が評価されます。applesの型は型推論でIntであることが分かります。ように型注釈を付けてもいいです。nilチェックと型変換をifの条件部にてスッキリまとめたスマートな記法ですね。余談ですがbeta5のOptional型について少し触れておきます。beta4までは「Optional値の型変換式」は左辺値(l-value)にできませんでしたが、beta5からは左辺値にすることができます。プログラミング言語における左辺値という用語は「代入式の左辺として扱えるもの」という値のことですね。C言語のconst変数は左辺値ではありません。変数のアドレスも左辺値ではありません。こんな風には書けません一度ポインタ変数にアドレスを入れ、ポインタの間接参照式にすれば左辺値にすることができます。3;Swiftも例で説明しましょう。3と書けるようになりました。この例では今ひとつ嬉しさが伝わりませんね。分かりやすい例が以下です。3numOfApples!++上記のように書けるのはエクスクラメーション式を左辺値にすることができるからです。3と書いていたわけです。この辺にしておきます。今後のbetaリリースでまた変わるかもしれませんし:Pさて本題に戻りましょう。Optional型をgetPosメソッドの戻り値に使うことで、タッチした場所が盤面上ではないことを自然に表現できるようになります。メソッドのインタフェースは以下のようになります。{}引数のtouchesはtouchesBeganメソッドのtouchesをそのまま渡してもらう変数です。戻り値は盤面のマス目の位置(列,行)のタプルをOptionalで返すようにします。引数touchesから画面上の位置(point)を取り出すところまで書いてみましょう。touch.locationInView(self)}touches.anyObject()の戻り値はAnyObject型です。asはダウンキャスト演算です。ダウンキャストとは型の互換性がない場合の強制キャストのことですね。UITouchにキャストしてlocationInViewメソッドで画面上の位置pointを取り出します。getPosの続きを一気に載せてしまいましょう。nil}2重for文で各マス目のrect領域を計算し、タッチ位置pointがrect領域に含まれるかチェックしています。このメソッドをtouchesBeganメソッドから呼び出して黒石を置いてみましょう。BLACK_STONE}setNeedsDisplay()}if文の条件式でgetPosの戻り値から安全にタプル値を取り出しています。盤面上をうまくタッチしていればif文の中に入るのでboardに黒石を置いてsetNeedsDisplayで再描画を指示します。すると非同期でdrawRectメソッドが呼ばれ、黒石を置いたところに黒丸が描画されます。盤面の描画とタッチして黒石を置けるところまで作ることができました。適当に黒石を置いてみたところを参考画像に載せます。Swiftの配列やOptional型は、それぞれbetaリリース中にゴタゴタと変更があった言語機能です。:OthelloViewをタッチして黒石を置いたところ2014-08-15OthelloViewの画面キャプチャ第24回目:Swiftでオセロを作る(Part1)2014-08-07筆者:村田こんにちは。今回からアップルの新言語Swiftを使って何か作りたいと思います。何かと言ってますがタイトル通りオセロです。オセロについては説明不要ですね。現在のSwiftについてですが、6月頭のWWDC2014で発表されてからまだ2ヶ月程しか経っていませんが評価バージョンはbeta4まで改訂されています。今秋に正式リリースされる予定だそうです。Overflowで大抵解決策が見つかるという、なんともありがたい状況です。そこで、とりあえず触りながらネット検索すれば、何やら作れるんじゃないかな〜ということでオセロを作ってみたいと思います。Swift言語はOSXアプリやiOSアプリを作ることができますが、今回のターゲットはiOS(iPhone)にしました。注意点として、SwiftでプログラミングするためにはXcode6が必要であり、ダウンロードするためにOSX/iOSの開発者ライセンスが必要になります。beta4バージョンを前提に作っていく予定です。他のバージョンでは動かないかもしれません。実際にbeta2の頃に書いたコードをbeta3に持っていったらコンパイルエラーやランタイムエラーが出ました。アクセス制限修飾子の追加があったり、Cocoaとの一部I/Fが変わったり、配列の仕様が変わったりもしました。今秋リリースとのことですが結構大きく改訂されてますね^^;ではアプリ作成を初めていきたいと思います。Xcode6のダウンロードはappleデベロッパーサイトから行うことができます。ダウンロードしたイメージファイルをダブルクリックすればインストールを開始できます。betaバージョンとは互いに独立しているので複数のXcodeをインストールしても問題ありません。(容量を食いますが)Xcode6を起動してプロジェクトを作成して下さい。Applicationを選択します。使用する言語にSwiftとObjective-Cが選べるのでSwiftを選びましょう。Xcodeの詳細なGUI操作については省略します:P自動生成されたファイルはAppDelegate.swiftとViewController.swiftとMain.storyboardです。Objective-Cではヘッダファイル(.h)と実装ファイル(.m)が分かれていましたが、Swiftではヘッダ・実装を分ける必要はなく、.swiftファイルにクラスやら関数やらを書いていけば良いです。AppDelegateはアプリのライフサイクルのデリゲートで、ViewControllerはビューのライフサイクルのデリゲートです。これらの役割はXcode5と変わっていません。ところでObjCではテンプレートにmain.mという実装ファイルがあり、以下のようにmain関数が書かれていました。class]));}}Swiftの今回のiOSテンプレートを見ると、mainエントリの書かれたファイルはありません。AppDelegate.swiftをよく見ると以下のようにクラスに@UIApplicationMainという属性がついています。これが従来main.mの中で行っていた紋切り型コードの代わりであり、AppDelegateのクラス登録を行っているのでしょう。{...}クラス登録は属性で行っているのは何となく分かりました。それでもエントリポイントとしてのmainはどうなってるのでしょう?GUIアプリでは明示的なmainが無くてもまあいいですが、単純なコンソールアプリではmainがあった方が分かりやすいはず、と思ってOSXのコンソールアプリのテンプレートを見てみました。おお、あるあるmain.swiftが。World!")・・・これだけか。Swiftではトップレベルに実行コンテキストが書けるようです。スクリプト言語のように上から順に実行されます。このようにトップレベルに式を書けるのはmain.swiftというファイルのみです。自分で追加したswiftファイルのトップレベルには式を書けません。ビルド設定のどこかに「main.swiftから実行する」って書いてあるのかな〜と探してみましたが見つかりませんでした。単純にテキスト検索しただけでは見つからないところにリンクしているかもしれません。iOSのテンプレートに話を戻しましょう。Main.storyboardもよく見るとXcode5の頃から変わっています。Xcode5で導入されていたAutoLayout機能が必須になった感じです。iOSも様々な画面サイズのデバイスに簡単に対応できるようにするため、レイアウトを絶対配置ではなく相対配置で書くことが重要になった、ということではないかと思います。iPhone6も噂?では4.7インチ、5.5インチと画面サイズがiPhone5とは異なるようです。iOSアプリもAndroidアプリのように多様な画面サイズへの対応が必要になってきました。テンプレートを眺めるのはこの辺にして、今のところ考えているオセロアプリのポイントは以下のとおりです。・一人二役での対戦は寂しいので、一応コンピュータ対戦にする(思考アルゴリズムは無く、単純なランダム)・副作用無しで書けそうな部分は、上書きできないlet変数を使って関数型プログラミングを意識してみる最初の目標はオセロ盤面を表示させることです。2DゲームなのでSpriteKitやUIImageViewを使うことも考えられますが、衝突などのアクションやアニメーションは必要ないので、UIViewの派生クラス1個という簡単な構成で進めていきます。OthelloView.swiftを新規作成し以下のようにUIKitをimportしてUIViewの派生クラスを作成します。{}そしてstoryboardから最初に起動するViewをOthelloViewに切り替えます。記事の最後にスクショを載せてみましたが、Xcode5と手順は同じです。それとViewの描画関数内でprintデバッグを出して簡単な動作確認を行いましょう。Swift!と表示されればOKです。短いですが上記のSwiftコードをちょっと眺めてみます。最初の印象はどうでしょう。何らかのオブジェクト指向言語を知っていれば普通に読めちゃうと思います。Objective-Cの記法は特徴があって個人的には好きなんですが、やはりSwiftの方が理解しやすそうです。クラスや継承の書き方も普通です。最近の言語らしくオーバーライドは明示的にoverrideと記述する必要があり、「知らぬ間にオーバライド問題」を防ぎます。メソッドや関数の頭にはfuncという識別子が必要です。Swiftの宣言の特徴は先頭に識別子を書くことです。クラスはclass、変数はvar、定数はletという識別子から始まります。逆に型注釈は名前の後になります。上記例においてrectという引数名の後にCGRect型と書いていますね。他に上記例から、式や宣言の後にセミコロンを書かなくても良いことがわかります。1.宣言の最初に識別子を書く、2.型注釈は名前の後、3.セミコロンは省略可、これらはGo言語に似ている特徴と言えます。えーっと後はコメントの書き方も普通なのですぐに覚えられますね。/*〜*/で複数行をコメントアウトできます。オセロを書く気配がありませんが、のんびりいきましょう:-)しばらくお付き合い頂ければと思います。