日々是好日~every day is a good day~

日常の中の非日常の備忘録

【Android Studio】Number Puzzle 2回目

今日は『シャッフルして不可能配列でなければ表示』です

ここで不可能配列とはですが

ランダムに数字を入れ替えると結構な確率で解くことのできないパズルになってしまいます

解けないパズルはゲームとして意味がないので事前に解けるか解けないかをチェックして

解けるパズルだけを表示するようにします
manabitimes.jp

ここに詳しく解説されている方がいました

理屈はよく分かりませんが判定方法のロジックだけ分かればOK(笑)

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView

private var textData =ArrayList<Int>()  //画面上の数値データ

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text0: TextView = findViewById(R.id.text0)
        val text1: TextView = findViewById(R.id.text1)
        val text2: TextView = findViewById(R.id.text2)
        val text3: TextView = findViewById(R.id.text3)
        val text4: TextView = findViewById(R.id.text4)
        val text5: TextView = findViewById(R.id.text5)
        val text6: TextView = findViewById(R.id.text6)
        val text7: TextView = findViewById(R.id.text7)
        val text8: TextView = findViewById(R.id.text8)
        val text9: TextView = findViewById(R.id.text9)
        val text10: TextView = findViewById(R.id.text10)
        val text11: TextView = findViewById(R.id.text11)
        val text12: TextView = findViewById(R.id.text12)
        val text13: TextView = findViewById(R.id.text13)
        val text14: TextView = findViewById(R.id.text14)
        val text15: TextView = findViewById(R.id.text15)
        val text16: TextView = findViewById(R.id.text16)
        val text17: TextView = findViewById(R.id.text17)
        val text18: TextView = findViewById(R.id.text18)
        val text19: TextView = findViewById(R.id.text19)
        val text20: TextView = findViewById(R.id.text20)
        val text21: TextView = findViewById(R.id.text21)
        val text22: TextView = findViewById(R.id.text22)
        val text23: TextView = findViewById(R.id.text23)
        val text24: TextView = findViewById(R.id.text24)
        val textView = arrayOf(
            text0, text1,text2,text3,text4,text5,text6,text7,
            text8,text9,text10,text11,text12,text13,text14,text15,
            text16,text17,text18,text19,text20,text21,text22,text23,text24)
        val textmsg1: TextView = findViewById(R.id.textmsg1)
        textmsg1.setVisibility(View.INVISIBLE)   //クリアメッセージ非表示
        val dispData = arrayOf(
            " ","1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
            "11", "12", "13", "14", "15","16","17","18","19","20",
            "21","22","23","24")
        val list = listOf(
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
            16,17,18,19,20,21,22,23,24)
        var check=false   //不可能配列かどうか(true:可能 false:不可能)
        while(check==false){
            textData = list.shuffled() as ArrayList<Int>
            check = GoalCheck()
        }
        //シャッフルした数字を表示し0を空白にする
        for (i in 0..24) {
            textView[i].text = dispData[textData[i]]
            if(textData[i]==0){
                textView[i].setBackgroundColor(Color.WHITE)
            }
        }
    }
    fun onNumberTap(view: View){
        //数字をタップしたときの処理
    }
    //不可能配置のチェック
    fun GoalCheck():Boolean{
        var num =IntArray(25)
        var zmove=true
        var nmove=true
        //空白が25の場所に移動するまでの最短距離が偶数か奇数か(1)
        var cnt=0
        for(i in 0..24){
            num[i] = textData[i]
            if(textData[i]==0) {
                num[i]=25
                cnt = i
            }
        }
        val zx=(cnt%5)+1
        val zy=(cnt/5)+1
        if(((5-zx)+(5-zy))%2 == 0) zmove= true
        else zmove= false
        //正しい順に並べるまでの配置変換数が偶数か奇数か(2)
        cnt = 0
        var bak=0
        for(i in 0..24){
            if(num[i]==i+1) continue
            for(j in i..24){
                if(num[j]==i+1) {
                    bak = num[i]
                    num[i] = num[j]
                    num[j]=bak
                    cnt++
                    break
                }
            }
        }
        if(cnt%2==0) nmove=true
        else nmove=false
        //(1)と(2)が同じならtrue 違ったらfalse
        if(zmove == nmove) return true
        else return false
    }
}

0~24のTextViewを取得して配列に設定
シャッフルして可能か不可能か判定
不可能なら可能になるまでシャッフルを繰り返す
シャッフルしたテキストを表示(0は空白にする)

解けるパズルの表示ができました