質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Java

    14097questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android Studio

    3785questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

QUIZアプリでランダムに問題を出す方法

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,687

kimura

score 52

下記のコードで問題を15問作りました。
そのうち15問中10問だけクイズを出したいときはどのように書き換えれば宜しいでしょうか?
また、出題の順番もランダムで出したいと思っております。
大変分かりにくくて申し訳ありませんが回答いただけますと助かりますので宜しくお願い致します。

・java


import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;


public class MyQuiz extends ActionBarActivity {

    public final static String EXTRA_MYSCORE = "com.example.taguchi.myquizapp.MYSCORE";
    private ArrayList<String[]> quizSet = new ArrayList<String[]>();

    private TextView scoreText;
    private TextView qText;
    private Button a0Button;
    private Button a1Button;
    private Button a2Button;
    private Button nextButton;

    private int currentQuiz = 0;
    private int score = 0;

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

        loadQuizSet();

        getViews();

        setQuiz();
    }

    private void showScore() {
        scoreText.setText("Score: " + score + " / " + quizSet.size());
    }

    private void setQuiz() {
        qText.setText(quizSet.get(currentQuiz)[0]);

        ArrayList<String> answers = new ArrayList<String>();
        for (int i = 1; i <= 3; i++) {
            answers.add(quizSet.get(currentQuiz)[i]);
        }
        Collections.shuffle(answers);

        a0Button.setText(answers.get(0));
        a1Button.setText(answers.get(1));
        a2Button.setText(answers.get(2));

        a0Button.setEnabled(true);
        a1Button.setEnabled(true);
        a2Button.setEnabled(true);
        nextButton.setEnabled(false);

        showScore();
    }

    public void checkAnswer(View view) {
        // answer?
        Button clickedButton = (Button) view;
        String clickedAnswer = clickedButton.getText().toString();

        // judge
        if (clickedAnswer.equals(quizSet.get(currentQuiz)[1])) {
            clickedButton.setText("◯ " + clickedAnswer);
            score++;
        } else {
            clickedButton.setText("× " + clickedAnswer);
        }
        showScore();

        // button
        a0Button.setEnabled(false);
        a1Button.setEnabled(false);
        a2Button.setEnabled(false);
        nextButton.setEnabled(true);

        // next quiz
        currentQuiz++;

        if (currentQuiz == quizSet.size()) {
            nextButton.setText("Check result");
        }
    }

    public void goNext(View view) {
        if (currentQuiz == quizSet.size()) {
            // show result
            Intent intent = new Intent(this, MyResult.class);
            intent.putExtra(EXTRA_MYSCORE, score + " / " + quizSet.size());
            startActivity(intent);
        } else {
            setQuiz();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        nextButton.setText("Next");
        currentQuiz = 0;
        score = 0;
        setQuiz();
    }

    private void getViews() {
        scoreText = (TextView) findViewById(R.id.scoreText);
        qText = (TextView) findViewById(R.id.qText);
        a0Button = (Button) findViewById(R.id.a0Button);
        a1Button = (Button) findViewById(R.id.a1Button);
        a2Button = (Button) findViewById(R.id.a2Button);
        nextButton = (Button) findViewById(R.id.nextButton);
    }

    private void loadQuizSet() {
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        try {
            inputStream = getAssets().open("quiz.txt");
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            while ((s = bufferedReader.readLine()) != null) {
                quizSet.add(s.split("\t"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) inputStream.close();
                if (bufferedReader != null) bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


・txt


what is A?    A0    A1    A2
what is B?    B0    B1    B2
what is C?    C0    C1    C2
what is D?    D0    D1    D2
what is E?    E0    E1    E2
what is F?    F0    F1    F2
what is G?    G0    G1    G2
what is H?    H0    H1    H2
what is I?    I0    I1    I2
what is J?    J0    J1    J2
what is K?    K0    K1    K2
what is L?    L0    L1    L2
what is M?    M0    M1    M2
what is N?    N0    N1    N2
what is O?    O0    O1    O2


・xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainQuiz">

    <TextView
        android:id="@+id/scoreText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right" />

    <TextView
        android:id="@+id/qText"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:gravity="center"
        android:textSize="32sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/a0Button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:onClick="checkAnswer" />

    <Button
        android:id="@+id/a1Button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:onClick="checkAnswer" />

    <Button
        android:id="@+id/a2Button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:onClick="checkAnswer" />

    <Button
        android:id="@+id/a3Button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:onClick="checkAnswer" />

    <Button
        android:id="@+id/nextButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="goNext"
        android:layout_gravity="right"
        android:layout_marginTop="8dp"
        android:text="@string/next_button" />

</LinearLayout>

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

  • 基本方針
  1.  問題の入っているquizSetを,最初の出題前にシャッフルする.途中でやっているanswerのシャッフルと同じ方法で構わない.
  2.  nextButtonを押したタイミングでcurrentQuizが10なら終了する.
  • 現状の問題点
各ButtonにOnClickLisnerをセットしていないため,現段階ではどのButtonを押しても何も起こらない

ある程度コードを書いてみます.
//クリックリスナーを実装
public class MyQuiz extends ActionBarActivity implements View.OnClickListener{ 

    public final static String EXTRA_MYSCORE = "com.example.taguchi.myquizapp.MYSCORE"; 
    private ArrayList<String[]> quizSet = new ArrayList<String[]>(); 

    private TextView scoreText; 
    private TextView qText; 
    private Button a0Button, a1Button, a2Button; 
    private List<Button> buttons;  //Buttonごとの操作をまとめてするためリスト化
    private Button nextButton; 

    private int currentQuiz = 0; 
    private int score = 0; 

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

        loadQuizSet(); 

        Collections.shuffle(quizSet);  //問題セットはこのタイミングで1度だけシャッフルする

        getViews(); 

        setQuiz(); 
    } 

    private void showScore() { 
        scoreText.setText("Score: " + score + " / " + quizSet.size()); 
    } 

    private void setQuiz() { 
        qText.setText(quizSet.get(currentQuiz)[0]); 

        ArrayList<String> answers = new ArrayList<String>(); 
        for (int i = 1; i <= 3; i++) { 
            answers.add(quizSet.get(currentQuiz)[i]); 
        } 
        Collections.shuffle(answers); 

        //解答Buttonに個別にしていた設定をListとforを使ってまとめて記述
        for(int i = 0; i < answers.size(); i++){
            Button button = buttons.get(i);
            button.setText(answers.get(i)); 
            button.setEnabled(true);
        }

        nextButton.setEnabled(false); 

        showScore(); 
    } 

    //ボタンクリック時の動作を実装
    @Override
    public void onClick(View view){
        //クリックされたのが解答ボタンのどれかだった場合は解答の判定
        if(buttons.contains(view))
            checkAnswer(view);

        //nextButtonがクリックされたら次の問題への処理
        else if(view == nextButton)
            goNext(view);
    }

    public void checkAnswer(View view) { 

        //判定に関してはそのままでいい

        // ここの操作もforで書き換え
        for(Button button : buttons){
            button.setEnabled(false);
        }
        nextButton.setEnabled(true); 

        // next quiz 
        currentQuiz++; 

        if (currentQuiz == quizSet.size()) { 
            nextButton.setText("Check result"); 
        } 
    } 

    public void goNext(View view) { 
        //「10問目まで」ならここを10に書き換えればよい
        if (currentQuiz == 10) { 
            // show result 
            Intent intent = new Intent(this, MyResult.class); 
            intent.putExtra(EXTRA_MYSCORE, score + " / " + quizSet.size()); 
            startActivity(intent); 
        } else { 
            setQuiz(); 
        } 
    } 

    @Override 
    public void onResume() { 
        //変更不要なので省略
    } 

    private void getViews() { 

        //各View,Buttonを取得する記述(もとと同じでいいので省略)

        buttons = Arrays.asList(a0Button, a1Button, a2Buttons);  //Buttonをリスト化
        //各Buttonにクリックリスナを設定
        for(Button button : buttons){
            button.setOnClickListener(this);
        }
        nextButton.setOnClickListener(this);
    } 

    private void loadQuizSet() { 
        //ここは変更しなくていいので省略
    } 
} 

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/11 23:02

    すいません。修正前のを出してしまいました。
    回答ありがとうございます。
    1.はanswerと同じ方法でやったのですが、15問中同じ問題が何度か出てしまって消してしまいました。
    2・のタイミングは分からなくて書けませんでした。

    キャンセル

  • 2015/10/12 00:33

    何度もありがとうございます。
    スッキリするソースで分かりやすかったです。
    おかげさまで2は出来ました。
    1もシャッフルされて問題が出るようになりましたが、10問終了後再度playすると前回と同じ問題が順番に出ます。
    何度も失礼ですが再度クイズをした場合にもランダムにすることは出来るのでしょうか?
    何卒宜しくお願い致します。

    キャンセル

  • 2015/10/12 00:36 編集

    要するに10問終わってIntentで遷移した先の画面から戻ってきた時,ということでしょうか?
    だとすれば問題シャッフルのメソッドをonResumeのsetQuizの前に移動させるとできると思います.

    キャンセル

  • 2015/10/12 00:42

    出来ました。
    最後までありがとうございます。
    しつこくてすいませんでした。

    キャンセル

0

java.util.Collectionsクラスのshuffle(List)メソッドを利用してはいかがでしょうか?

このメソッドでquizSetをシャッフルしたリストを作成し、最初の10個の要素を取り出せば、重複なくランダムに出題できると思います。

https://docs.oracle.com/javase/jp/6/api/java/util/Collections.html#shuffle(java.util.List))

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/11 23:52

    ご回答ありがとうございます。
    ↓↓こういうことですか?
      重複してしまいました(涙)  

    private void setQuiz() {
    java.util.Collections.shuffle(quizSet);

    キャンセル

  • 2015/10/12 00:17

    よく見たら回答のシャッフルに、すでに使っていましたね。

    setQuiz メソッド内部ではなく、
    loadQuizSet メソッド内部の、while文の直後に Collections.shuffle(quizSet) を追加してください。

    これで quizSet の各要素がシャッフルされるので、出題するときは先頭から順番に要素を取り出すだけで、ランダムに出題できることになります。

    キャンセル

  • 2015/10/12 00:34

    何度も回答してくださってありがとうございます。
    おかげさまでシャッフルされて問題が出るようになりましたが、10問終了後再度playすると前回と同じ問題が順番に出ます。
    何度も失礼ですが再度クイズをした場合にもランダムにすることは出来るのでしょうか?
    何卒宜しくお願い致します。

    キャンセル

  • 2015/10/12 00:43

    おかげさまで完璧に出来ました。
    お世話になったのにベストアンサーにせず申し訳ありません。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    14097questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android Studio

    3785questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。