타닥타닥 개발자의 일상

Kotlin 코틀린 random 넘버와 spinner 이용한 안드로이드 야구 게임 만들기 본문

코딩 기록/Kotlin

Kotlin 코틀린 random 넘버와 spinner 이용한 안드로이드 야구 게임 만들기

NomadHaven 2022. 2. 10. 00:11

 나는 야구를 전혀 몰라서 하기의 규칙이 실제 야구 규칙과 일치하는지 모른다.

 

 

 

야구 게임 규칙

1. 컴퓨터는 세가지 수를 랜덤으로 선정한다.
2. 유저는 세가지 수를 스피너로 선택한다.
3. 컴퓨터의 랜덤번호와 숫자만 맞고 위치면 틀리면 1볼이다.
4. 컴튜터의 랜덤번호와 숫자가 다르고 위치가 같으면 1스트라이크다.
5. 3 스트라이크가 되면(스트라이크가 세번 누적되면) 게임이 종료된다.

 


폴더 및 파일 구성

 

com.example.baseballfin 폴더에 Baseball.kt 생성

layout 폴더에 item_spinner.xml 생성

 


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    <TextView
            android:id="@+id/textView"
            android:layout_width="320dp"
            android:layout_height="79dp"
            android:text="welcome"
            android:textSize="30sp"
            android:gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.27" />
    <Spinner
            android:layout_width="137dp"
            android:layout_height="87dp"
            android:id="@+id/spinner3"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_bias="0.879"
            app:layout_constraintVertical_bias="0.41"/>
    <Spinner
            android:id="@+id/spinner1"
            android:layout_width="137dp"
            android:layout_height="87dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_bias="0.123"
            app:layout_constraintVertical_bias="0.41"/>
    <Spinner
            android:layout_width="137dp"
            android:layout_height="87dp"
            android:id="@+id/spinner2"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintVertical_bias="0.41"/>
    <Button
            android:id="@+id/button"
            android:text="Match"
            android:layout_width="162dp"
            android:layout_height="103dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintVertical_bias="0.586"/>
    <Button
            android:id="@+id/button2"
            android:text="Replay"
            android:layout_width="162dp"
            android:layout_height="103dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintVertical_bias="0.73"/>

</androidx.constraintlayout.widget.ConstraintLayout>

designe화면

 

 

item_spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tvItemSpinner"

        android:layout_width="match_parent"
        android:layout_height="45dp"

        android:paddingTop="10dp"
        android:paddingStart="30dp"
        android:textColor="@android:color/black"
        android:textSize="15sp"
        android:paddingLeft="30dp"/>

 

 

Baseball.kt
package com.example.baseballfin

class Baseball {

    var randNum: IntArray = IntArray(3)
    var clear: Boolean = false

    constructor() {
        clear = false

    }

    fun random() {

            //switch 0 0 0 0 0  0 0 0 0 0
            var switch = BooleanArray(10)
            for (i in switch.indices){
            switch[i] = false // 스위치가 꺼져있다. 값이 전부 0 으로 세팅
            }

            var w =0
            while(w<3){
            var r = (Math.random() * 10).toInt() //1~9
            if(switch[r]==false){
                switch[r] =true // 특정 숫자가 들어오면 true
                randNum[w] = r + 1 //1~10
            w++
                }
            }

            for(i in randNum.indices){
                println("randNum[$i] = ${randNum[i]}")
            }
        }

        //strike와 ball을 판정하는 finding 함수. 
        //user가 spinner로 선택한 값(userNum:Array<Int>)을 매개변수로 넣어준다.
        //최종 strike와 ball 값이 입력된 MyResult 클래스를 반환한다.
        fun finding(userNum:Array<Int>) : MyResult {
            var strike:Int=0
            var ball:Int=0

            //ball 자리는 다른데 숫자가 같다
            for(i in userNum.indices){
                for(j in userNum.indices){
                    if(userNum[i]==randNum[j] && i!=j){
                        ball++
                    }
                }
            }

            //strike 자리도 맞고 숫자도 맞다
            for(i in userNum.indices){
                if(userNum[i]==randNum[i]){
                    strike++
                }
            }

            return MyResult(strike,ball)
        }

    // 결과
    fun resultString(): String{
        return if(clear==true){
            "축하합니다. 게임 클리어."
        }else{
            "다시 도전하시겠습니까?"
        }
    }

	//게임 다시 시작할때
    fun reset(){
        clear = false
        random()
    }
}

class MyResult(val strike:Int, val ball:Int)

랜덤넘버를 만드는 함수 random()에 대한 설명은 이전글에 좀더 자세하게 적어놨다.

https://developerson.tistory.com/94

 

kotlin BooleanArray, Math.random 이용하여 중복되지 않는 랜덤 번호 골라주는 함수 만들기

예를들어 1부터 10까지의 수중 중복되지 않는 3개의 숫자를 고른다면 아래와 같은 함수를 만들어서 랜덤 번호를 뽑을 수 있다. fun random() { var randNum: IntArray = IntArray(3) //구하고자하는 랜덤번호 3가

developerson.tistory.com

 

 

MainActivity.kt
package com.example.baseballfin

import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.TextView

class MainActivity : AppCompatActivity() {
	//Baseball 클래스의 객체를 만들어준다.
    var baseball:Baseball? = null

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

		//만들어준 spinner3개를 불러온다
        setupSpinner(R.id.spinner1)
        setupSpinner(R.id.spinner2)
        setupSpinner(R.id.spinner3)
		
        //baseball 클래스의 생성자를 불러온다.
        baseball = Baseball()
       
       //baseball 클래스의 랜덤함수를 실행한다
       baseball!!.random()

		
        val button = findViewById<Button>(R.id.button)
        button.setOnClickListener{
            action()
        }


        val button2 = findViewById<Button>(R.id.button2)
        button2.setOnClickListener{
                replay()
        }


    }

    fun action(){
    	
        val spinner1 = findViewById<Spinner>(R.id.spinner1)
        val spinner2 = findViewById<Spinner>(R.id.spinner2)
        val spinner3 = findViewById<Spinner>(R.id.spinner3)
		
        //세가지 스피너에서 받은 값을 문자열에서 정수로 전환한다.
        val num1 = spinner1.selectedItem.toString().toInt()
        val num2 = spinner2.selectedItem.toString().toInt()
        val num3 = spinner3.selectedItem.toString().toInt()

		//세가지 스피너에서 받은 값의 정수를 배열 spinnerArr로 만든다
        var spinnerArr =  arrayOf<Int>(num1, num2, num3)

		//Baseball 클래스 finding 함수에서 스피너의 세가지 값으로 이루어진 배열을 넣어준다.
        //finding함수를 통해서 strike와 ball의 값을 파악한다.
        //파악된 strike와 ball의 값을 매개변수로 담은 MyResult 클래스의 객체를 변수로 선언한다.
        val result: MyResult? = baseball?.finding(spinnerArr)

        val textView = findViewById<TextView>(R.id.textView)

        if(result!=null){

            if(result.strike==3){
                baseball?.clear = true
                textView.text =baseball?.resultString()
                //스트라이크가 3번이면 게임을 종료한다.
            }
            else{

                textView.text = "${result.strike} 스트라이크 ${result.ball} 볼입니다."
            }
        }

    }

    fun replay(){

        val spinner1 = findViewById<Spinner>(R.id.spinner1)
        val spinner2 = findViewById<Spinner>(R.id.spinner2)
        val spinner3 = findViewById<Spinner>(R.id.spinner3)

        spinner1.setSelection(0,false);
        spinner2.setSelection(0,false);
        spinner3.setSelection(0,false);
		//그냥 spinner.setSelection(0)이라 설정하면 오류가 나므로 false로 설정해준다.
        //이유는 나도 모른다. (。_。)
        //0은 포지션을 나타나는 숫자이므로 setSelection을 통하여 스피너는 첫번째값 1로 세팅된다.

        baseball?.reset()
        //clear를 false로 바꾸고 random번호를 뽑는 함수를 다시 실행한다.

        var strike:Int=0
        var ball:Int=0
        //strike와 ball을 다 0으로 초기화한다.

        val result= MyResult(strike,ball) 
        //My Result  클래스에 초기화된 값을 넣는다.
        val textView = findViewById<TextView>(R.id.textView)
        textView.text = "${result?.strike} 스트라이크 ${result?.ball} 볼입니다."


    }


    //spinner
    fun setupSpinner(spinnerNum:Int){
        var countArr = arrayOf(1,2,3,4,5,6,7,8,9,10)

        val adapter = ArrayAdapter(this,R.layout.item_spinner,countArr)

        val spinner = findViewById<Spinner>(spinnerNum)
        spinner.adapter = adapter

    }
}

 

 

실행화면

스피너로 숫자 입력하고 Match 버튼 눌렀을때 화면

 

Replay 눌러서 스트라이크, 볼 값 초기화 시키고 스피너도 1로 초기화 시킨 화면

Comments