計算ゲームアプリ　Google play storeで公開しました

Google　play storeで公開しました。
https://play.google.com/store/apps/details?id=com.nyaa.braintrainer


Androidスマホを使っている方は遊んでみてもらえると嬉しいです。


また、コードレビューしていただき、ソースコードを少し修正しました。
メモも追加したり、学習用のメモを消したりしました。


もとのソースコード
https://qiita.com/KToushi/items/6e1a369111e904a6a22f




//playaAgainボタンを押したときの挙動を定義
public void playAgain(View view) {
    score = 0;
    numberOfQusetions = 0;
    timerTextview.setText("15s");
    scoreTextView.setText("0/0");

・
・
・

new CountDownTimer(15100, 1000) {

        //CountDownTimerクラスのメソッドを上書き
        @Override
        //カウントダウンしている間の挙動
        public void onTick(long millisUntilFinished) {

            //残り何秒か表示
            timerTextview.setText(String.valueOf(millisUntilFinished / 1000) + "s");

        }

・
・
・
public void newQuetion() {

    //インスタンス生成　　
    //クラス名　変数　=　new クラス名();
    Random rand = new Random();

    //整数の変数a,bを定義　　0～20の21通りの整数をランダムに代入
    int a = rand.nextInt(21);
    int b = rand.nextInt(21);

    sumTextView.setText(Integer.toString(a)+ " + " + Integer.toString(b));

    //0～3の4通りの整数をランダムに代入　Tagも0～3の4通り
    locationOfCorrectAnswer = rand.nextInt(4);
    //answersリストの中身（４つの答え）を消去　
    answers.clear();

  for(int i=0; i<4; i++) {
        if(i==locationOfCorrectAnswer) {
            answers.add(a+b);
        } else {
            //0～40の41通りの整数をランダムに代入（a,bにはそれぞれ0～20の整数が入るため　最小0+0　最大20+20）
            int wrongAnswer = rand.nextInt(41);

            //wrongAnswerが正解と一緒の場合、再び0から40の41通りの整数をランダムに代入
            while(wrongAnswer == a+b) {
                wrongAnswer = rand.nextInt(41);


15,15100,1000,4,21,41のような数値を直接メソッド内に書いてしまっていると、後から修正したいときに該当箇所を探すのが大変ということで、
始めに定数としてまとめて宣言することにしました↓


 //ゲーム開始時のカウントダウンタイマーの残り時間を表す定数
    final int remainingTime = 16;
    //カウントダウンタイマーのカウントダウンの間隔を表す定数
    final int countDownInterval = 1000;


    //選択肢の数
    final int numberOfTags = 4;
    //(問題に使うランダムな数が)何通りあるか
    final int numberOfWays = 20;




ソースコード全体↓


package com.nyaa.braintrainer;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;


import static android.media.MediaPlayer.create;

public class MainActivity extends AppCompatActivity {

    //ゲームを開始するボタン
    Button goButton;
    //残り時間、問題、得点/問題数、4つの選択肢（ボタン）
    ConstraintLayout gameLayout;

    Button playAgainButton;

    TextView resultTextView;
    TextView commentTextView;
    TextView timerTextview;
    int score = 0;
    int numberOfQusetions = 0;

    //猫画像
    ImageView imageNirami;
    ImageView imageKakure;
    ImageView imageYousumi;

    //ゲーム開始時のカウントダウンタイマーの残り時間を表す定数
    final int remainingTime = 16;
    //カウントダウンタイマーのカウントダウンの間隔を表す定数
    final int countDownInterval = 1000;


    ArrayList<Integer> answers = new ArrayList<Integer>();

    //正解の位置（ボタン）のtag
    int locationOfCorrectAnswer;
    //選択肢の数
    final int numberOfTags = 4;
    //(問題に使うランダムな数が)何通りあるか
    final int numberOfWays = 20;

    TextView scoreTextView;
    TextView sumTextView;
    Button button0, button1, button2, button3;





    //Goボタンを押したときの挙動（ゲームをスタートさせる）を定義
    public void start(View view) {

        //goボタンが消える
        goButton.setVisibility(View.INVISIBLE);

        //残り時間、問題、得点/問題数、4つの選択肢（ボタン）を出現させる
        gameLayout.setVisibility(View.VISIBLE);

        //playAgainButtonを押した時と同じ挙動をする
        playAgain(findViewById(R.id.timerTextView));

    }


    //playaAgainボタンを押したときの挙動を定義
    public void playAgain(View view) {
        score = 0;
        numberOfQusetions = 0;

        //残り何秒か表示
        timerTextview.setText(remainingTime + "s");

        //何問中何問正解しているか表示
        scoreTextView.setText("0/0");

        //新しい問題と選択肢を表示
        newQuetion();

        //resultTextViewを見えるようにする
        resultTextView.setVisibility(View.VISIBLE);

        //commentTextViewを見えなくする
        commentTextView.setVisibility(View.INVISIBLE);

        //playAgainButtonを見えなくする
        playAgainButton.setVisibility(View.INVISIBLE);

        //猫の画像見えなくする
        imageNirami.setVisibility(View.INVISIBLE);
        imageYousumi.setVisibility(View.INVISIBLE);
        imageKakure.setVisibility(View.INVISIBLE);

        resultTextView.setText("");

        //４つのボタン（選択肢）出現
        buttonShow();




        //カウントダウンタイマーをスタートさせる
        new CountDownTimer(remainingTime * 1000, countDownInterval) {

            //CountDownTimerクラスのメソッドを上書き
            @Override
            //カウントダウンしている間の挙動
            public void onTick(long millisUntilFinished) {

                //残り何秒か表示
                timerTextview.setText(String.valueOf(millisUntilFinished / 1000) + "s");

            }

            @Override
            //カウントダウンが0になった時の挙動
            public void onFinish() {
                MediaPlayer mediaPlayer;

                //４つのボタン（選択肢）を見えなくする
                buttonHide();

                resultTextView.setVisibility(View.INVISIBLE);
                commentTextView.setVisibility(View.VISIBLE);

                //得点によって表示される画像とテキスト、効果音を変える
                if(score > 9) {
                    commentTextView.setText("ほ、ほめてあげるわ//");

                    //隠れ猫表示
                    imageKakure.setVisibility(View.VISIBLE);

                    //効果音キラキラが鳴る
                    mediaPlayer = create(getApplicationContext(), R.raw.shine1);
                    mediaPlayer.start();



                } else if(score > 5) {
                    commentTextView.setText("ふん、まあまあね");

                    //様子見猫表示
                    imageYousumi.setVisibility(View.VISIBLE);

                    //効果音シャキーン！が鳴る
                    mediaPlayer = create(getApplicationContext(), R.raw.shakin1);
                    mediaPlayer.start();

                } else {
                    commentTextView.setText("あんたやる気あるの？");

                    //にらみ猫表示
                    imageNirami.setVisibility(View.VISIBLE);

                    //効果音チーンが鳴る
                    mediaPlayer = create(getApplicationContext(), R.raw.tin1);
                    mediaPlayer.start();

                }

                //playAgainButton出現
                playAgainButton.setVisibility(View.VISIBLE);

            }

        }.start();

    }

    //4種類のボタンを押したときの挙動（メソッド）を定義
    public void chooseAnswer(View view) {

        //正解のタグと押したタグが同じとき（４つのボタンに０～３の4種類のタグを設定している）
        if (Integer.toString(locationOfCorrectAnswer).equals(view.getTag().toString())) {
            resultTextView.setText("正解にゃ");

            //得点が1増える
            score++;

        } else {
            resultTextView.setText("間違いにゃ");

        }

        //現在の問題数が1増える
        numberOfQusetions++;

        //何問中何問正解しているか表示
        scoreTextView.setText(Integer.toString(score) + "/" + Integer.toString(numberOfQusetions));

        //新しい問題と選択肢を表示
        newQuetion();
    }


    //新しい問題を出現させるメソッドを定義
    public void newQuetion() {

        Random rand = new Random();

        //整数の変数a,bを定義　　0～numberOfWaysの(numberOfWays + 1)通りの整数をランダムに代入
        int a = rand.nextInt(numberOfWays);
        int b = rand.nextInt(numberOfWays);

        //a + bを表示
        sumTextView.setText(Integer.toString(a)+ " + " + Integer.toString(b));

        //0～3の4通りの整数をランダムに代入　Tagも0～3の4通り
        locationOfCorrectAnswer = rand.nextInt(numberOfTags);
        //answersリストの中身（４つの答え）を消去　
        answers.clear();

        for(int i=0; i<4; i++) {
            if(i == locationOfCorrectAnswer) {

               //anserwsリストに正解(a + b)を追加
                answers.add(a+b);
            } else {
                //0～numberOfWays * 2 の numberOfWays * 2 -1 通りの整数をランダムに代入
                int wrongAnswer = rand.nextInt(numberOfWays * 2 -1);

                //wrongAnswerが正解と一緒の間、0～numberOfWays * 2 の numberOfWays * 2 -1 通りの整数をランダムに代入
                while(wrongAnswer == a+b) {
                    wrongAnswer = rand.nextInt(numberOfWays * 2 -1);

                }

                //answersリストに間違った答えを追加
                answers.add(wrongAnswer);
            }

        }

        button0.setText(Integer.toString(answers.get(0)));
        button1.setText(Integer.toString(answers.get(1)));
        button2.setText(Integer.toString(answers.get(2)));
        button3.setText(Integer.toString(answers.get(3)));
    }

    //4つのボタン（選択肢）を見えるようにするメソッドを定義
    public void buttonShow() {
        button0.setVisibility(View.VISIBLE);
        button1.setVisibility(View.VISIBLE);
        button2.setVisibility(View.VISIBLE);
        button3.setVisibility(View.VISIBLE);
    }

    //4つのボタン（選択肢）を見えなくするメソッドを定義
    public void buttonHide(){
        button0.setVisibility(View.INVISIBLE);
        button1.setVisibility(View.INVISIBLE);
        button2.setVisibility(View.INVISIBLE);
        button3.setVisibility(View.INVISIBLE);
    }




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //それぞれlayoutのViewと紐づけ
        goButton = findViewById(R.id.goButton);
        sumTextView = findViewById(R.id.sumTextView);
        button0 = findViewById(R.id.button0);
        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);
        button3 = findViewById(R.id.button3);
        resultTextView = findViewById(R.id.resultTextView);
        commentTextView = findViewById(R.id.commentTextView);
        scoreTextView = findViewById(R.id.scoreTextView);
        timerTextview = findViewById(R.id.timerTextView);
        playAgainButton = findViewById(R.id.playAgainButton);
        gameLayout = findViewById(R.id.gameLayout);
        imageNirami = findViewById(R.id.nirami);
        imageKakure = findViewById(R.id.kakure);
        imageYousumi = findViewById(R.id.yousumi);

        goButton.setVisibility(View.VISIBLE);

    }
}


レイアウト↓

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/goButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@android:color/holo_green_dark"
        android:onClick="start"
        android:padding="40dp"
        android:text="GO!"
        android:textSize="60sp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/kakure"
        android:layout_width="474dp"
        android:layout_height="900dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/konekokakure" />

    <ImageView
        android:id="@+id/yousumi"
        android:layout_width="409dp"
        android:layout_height="738dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/nekoyousumi" />

    <ImageView
        android:id="@+id/nirami"
        android:layout_width="375dp"
        android:layout_height="245dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/nekonirami" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/gameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible">


        <TextView
            android:id="@+id/timerTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:background="@android:color/holo_orange_dark"
            android:text="30s"
            android:textSize="30sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/scoreTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:background="@android:color/holo_blue_dark"
            android:padding="10dp"
            android:text="0/0"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/sumTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:padding="15dp"
            android:text="31 + 7"
            android:textSize="40dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TableLayout
            android:id="@+id/TableLayout"
            android:layout_width="330dp"
            android:layout_height="350dp"
            android:layout_marginTop="60dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TableRow
                android:id="@+id/TableRow1"
                android:layout_width="match_parent"
                android:layout_height="258dp">

                <Button
                    android:id="@+id/button0"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:layout_row="0"
                    android:layout_column="0"
                    android:layout_columnWeight="1"
                    android:layout_gravity="fill"
                    android:layout_weight="1"
                    android:background="@android:color/holo_red_light"
                    android:onClick="chooseAnswer"
                    android:tag="0"
                    android:text="14"
                    android:textSize="80sp" />

                <Button
                    android:id="@+id/button1"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:layout_row="0"
                    android:layout_column="1"
                    android:layout_columnWeight="1"
                    android:layout_gravity="fill"
                    android:layout_weight="1"
                    android:background="@android:color/holo_purple"
                    android:onClick="chooseAnswer"
                    android:tag="1"
                    android:text="14"
                    android:textSize="80sp" />

            </TableRow>

            <TableRow
                android:id="@+id/TableRow2"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <Button
                    android:id="@+id/button2"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:layout_row="1"
                    android:layout_column="0"
                    android:layout_columnWeight="1"
                    android:layout_gravity="fill"
                    android:layout_weight="1"
                    android:background="@android:color/holo_blue_dark"
                    android:onClick="chooseAnswer"
                    android:tag="2"
                    android:text="14"
                    android:textSize="80sp" />

                <Button
                    android:id="@+id/button3"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:layout_row="1"
                    android:layout_column="1"
                    android:layout_columnWeight="1"
                    android:layout_gravity="fill"
                    android:layout_weight="1"
                    android:background="@android:color/holo_green_dark"
                    android:onClick="chooseAnswer"
                    android:tag="3"
                    android:text="14"
                    android:textSize="80sp" />
            </TableRow>


        </TableLayout>

        <TextView
            android:id="@+id/resultTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="45dp"
            android:text="Correct!"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />

        <TextView
            android:id="@+id/commentTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="45dp"
            android:text="TextView"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />

        <Button
            android:id="@+id/playAgainButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="10dp"
            android:onClick="playAgain"
            android:text="play again"
            android:visibility="invisible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/resultTextView" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>