もう少しスマートに作りたかったが。。。何しろ動けばいいやということで、かなり無理矢理作った。またの機会に格好良く作ってみたい。
アプリ実行のビデオ:
スクリーンのデザイン:
Tablet sizeでキャプチャー。「Play again」ボタンは、勝敗が決まるまでは非表示。
ブロック・コード:
1. マル、バツの画像ファイル名をリスト形式で変数imageToShowに格納。
circle1Trans.png cross1Trans.png
2. 9つのボタンの初期化。有効にすると共にimageは「なし」に設定。
変数buttonListは以下の9つのボタンをリスト形式で格納
3. Buttonのgenericのイベントハンドラー(タップした時の動作を設定)を使用。
genericのイベントハンドラーは、対象となるcomponent全ての動作を一様に設定するもので、今回はButton。もちろん条件をつけて特定のButtonのみの動作を設定することもできる。
今回は、Buttonとして設定されているのは9つのみ。「Play again」ボタンがあるが、これはButtonではなくタップした時の動作を設定できる「clickable image」をボタンとして利用しているもの。
今回の基本的な動作は、ボタンがタップされると、変数tapIndexにより、初期設定の1の場合は「circle」を表示、2の場合は、「cross」を表示させる。先攻はcircleとあらかじめ決めているので、最初にボタンをタップすれば、そのボタンは、circleを表示することになる。次に相手がタップすれば、tapIndexは2と設定されているので、crossが表示される。
具体的にgenericのイベントハンドラーを見てみると。。。
先攻がいずれかのボタンをタップする=>初めてなので、tapIndexは1。同ボタンの画像はimageToShowのindex 1であるcircleとなる=>tapIndexを2に、タップされたボタンは無効に設定。=>後攻がいずれかのボタンをタップする=>tapIndexが2に設定されているので、imageToShowのindex 2であるcrossとなる=>tapIndexが1に設定されるとともに、タプされたボタンは無効に設定=>この繰り返しでタップするたびにcircle、crossが交互に表示されていく
また、変数positionListの当該indexの値が、circleの場合は5、crossの場合は10に設定されていく。
4. 関数decideWinnerは、以下の変数winningCombinationListの組み合わせを、circle(5)、またはcross(10)のいずれが達成するかを監視するのが役目。もし、circle(5)が達成したら、「Circle wins」を、cross(10)が達成したら、「Cross wins」を表示することになる。(変数winningCombinationList自体は使用していない。数字は上記positionListのリスト項目のindexの値)
*******************以下、勝つ場合の組み合わせの数だけ続くが、省略********************
変数winningCombinationListは、勝利する時の組み合わせをリストにしたもので、このリストを使えば簡単に勝敗を決定できるだろうと考えたが、目論み通りには行かなかった。結局、上記の通り、かなりめんどくさい方法で勝者を決めることになった。
5. 勝者が決まったら、以下の関数makeButtonsDisabledを実行し、全てのボタンを無効に設定し、「Play again」ボタンを表示。
6. 「Play again」ボタンをタップした時の動作を設定。各変数を初期値へ戻す。
positionListの各リスト項目に0を再設定(初期化)。
関数makeButtonsEnabledでButtonを初期化。各ボタンを有効にするとともに、ボタンの画像をブランクに設定。
やはり、もう少しスマートな方法がないのか検討する必要がありそうだ。
勝者なしの引き分けの場合を想定するのを忘れた。(訂正=>勝負がつかない場合)