クラス実装
クラスを実装し、次のように✕、〇を交互に打てるようにする。
Square
各マス目に対応するクラスSquareを作成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.example.myapplication import android.widget.ImageButton import kotlinx.android.synthetic.main.activity_main.* class Square(var state:Int=0,var imagebutton: ImageButton) { val img = arrayOf( R.drawable.ic_baseline_check_box_outline_blank_24, R.drawable.ic_baseline_close_24, R.drawable.ic_baseline_panorama_fish_eye_24 ) init{ click(state) } fun click(state:Int){ this.state = state imagebutton.setImageResource(img[state]) } } |
プロパティは3つだ。マス目の状態(0:空白、1:×、2:〇)を表すstate、ImageButton情報のimageutton、空白、×、〇画像を配列化したimgだ。画像の配列化はstateをインデックスにすることにより画像を決定できるからだ。
6 7 8 9 10 |
class Square(var state:Int=0,var imagebutton: ImageButton) { val img = arrayOf( R.drawable.ic_baseline_check_box_outline_blank_24, R.drawable.ic_baseline_close_24, R.drawable.ic_baseline_panorama_fish_eye_24 ) |
コンストラクタで関数clickを呼び出している。clickはstate情報により画像を設定する関数だ。stateには0が設定されているので、ここでマス目を空白にしているのだ。
11 12 13 14 15 16 17 18 |
init{ click(state) } fun click(state:Int){ this.state = state imagebutton.setImageResource(img[state]) } |
Squares
クラスSquareを管理し各種処理を行うSquaresを作成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.example.myapplication import android.util.Log import android.widget.ImageButton import kotlinx.android.synthetic.main.activity_main.* class Squares(imagebutton: Array<Array<ImageButton>>) { var square = arrayOf( arrayOf(Square(0,imagebutton[0][0]), Square(0,imagebutton[0][1]), Square(0,imagebutton[0][2])), arrayOf(Square(0,imagebutton[1][0]), Square(0,imagebutton[1][1]), Square(0,imagebutton[1][2])), arrayOf(Square(0,imagebutton[2][0]), Square(0,imagebutton[2][1]), Square(0,imagebutton[2][2])) ) fun isKUHAKU(x:Int,y:Int):Boolean{ return if(square[x][y].state == 0) true else false } fun click(x:Int,y:Int,next:Boolean) { var ne= if(next) 1 else 2 square[x][y].click(ne) } } |
MainActivityからImgeButtonの情報を3×3の配列で受け取る予定だ。
7 |
class Squares(imagebutton: Array<Array<ImageButton>>) { |
クラスSquareを3×3のマス目分作成する必要がある。それが8行目から12行目だ。Squareを作成しながら3×3の配列に格納している。同時にSquareへマス目状態0(空白)、ImageButton情報を受け渡している。
8 9 10 11 12 |
var square = arrayOf( arrayOf(Square(0,imagebutton[0][0]), Square(0,imagebutton[0][1]), Square(0,imagebutton[0][2])), arrayOf(Square(0,imagebutton[1][0]), Square(0,imagebutton[1][1]), Square(0,imagebutton[1][2])), arrayOf(Square(0,imagebutton[2][0]), Square(0,imagebutton[2][1]), Square(0,imagebutton[2][2])) ) |
マス目に手が打たれているか、このチェック関数が13行-15行目のisKUHAKUだ。
13 14 15 |
fun isKUHAKU(x:Int,y:Int):Boolean{ return if(square[x][y].state == 0) true else false } |
チェックするマス目の座標を引数とし、Squareクラスのマス目状態を判断している。0(空白)なら真(true)、それ以外は偽(false)を返している。
このif文よーく見ると違和感があるだろう。これはKotlinの三項演算子みたいな書き方だ。真、偽により値を返す動きをする。
マス目がクリックされた際の処理が16行-19行目の関数clickだ。
16 17 18 19 |
fun click(x:Int,y:Int,next:Boolean) { var ne= if(next) 1 else 2 square[x][y].click(ne) } |
クリックされた座標(x,y)と手番(next)を引数で受け取っている。手番はtrueの時に×手番、falseの時に〇手番としている。
17行目で手番によりマス目状態を確定している。つまり手番がtrue(✕手番)の時には1、false(〇手番)の時に2とし変数neに格納している。
18行目でSquareクラスのcheck関数を呼び出し、ボタン状態、画像の変更を行っている。これで画面に〇や✕が表示される。
MainActivity
MainActivityを次の通り変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.example.myapplication import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View import android.widget.ImageButton import kotlinx.android.synthetic.main.ticktacktoo.* class MainActivity : AppCompatActivity(), View.OnClickListener { lateinit var squares:Squares var next:Boolean = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.ticktacktoo) var imagebutton = arrayOf( arrayOf(imageButton1,imageButton2,imageButton3), arrayOf(imageButton4,imageButton5,imageButton6), arrayOf(imageButton7,imageButton8,imageButton9) ) for(idx1 in imagebutton.indices){ for(idx2 in imagebutton[idx1].indices){ imagebutton[idx1][idx2].setOnClickListener(this) var array = arrayOf(idx1,idx2) imagebutton[idx1][idx2].setTag(array) } } squares = Squares(imagebutton) } override fun onClick(p0: View?) { var button = p0 as ImageButton var array = button.getTag() as Array<Int> textView3.text = "" if(squares.isKUHAKU(array[0],array[1])){ squares.click(array[0], array[1], next) next = !next }else { textView3.text = "既に打たれています。" } } } |
プロパティを2つ用意する。1つ目はSquaresクラス用の変数だ。この変数は定義時に初期値が決定されず、nullを許容したくないため「lateinit」を付けている。2つ目が手番情報のnextだ。
11 12 |
lateinit var squares:Squares var next:Boolean = true |
関数onClickに処理を追加している。36行目はメッセージエリアを空白にしている。前のメッセージが残らないようにだ。
36 |
textView3.text = "" |
37行目からのif文で手が打てるかクラスSquaresのisKUHAKU関数を使い確認を行っている。
37 |
if(squares.isKUHAKU(array[0],array[1])){ |
手が入力できないなら40行目からのelse文でメッセージを設定している。
40 41 42 |
}else { textView3.text = "既に打たれています。" } |
手が入力できる場合は38行目でクラスSquaresのclick関数を使いマス目情報、画像の変更を行っている。最後に39行目で手番を否定(!)し手番へ格納している。これは例をあげるとtrue(✕)なら否定しfalse(〇)へ、それをnextへ設定する。つまり手番を交代していることになる。
38 39 |
squares.click(array[0], array[1], next) next = !next |
その他のコードは「KotlinでAndroidアプリ#19」、「KotlinでAndroidアプリ#20」を確認してください。
雰囲気は出てきたがまだまだ実装しなければいけない。次回は終了判定など作成してみたい。