// ProblemGenerator -- 問題生成を担当するクラス public class ProblemGenerator { String[] problemMemory; // 問題を記憶する配列 int problemCounter; // 生成した問題数の記憶(カウンタ) int currentAnswer; // 現在の問題の答え int maxAnswerValue; // 答えの最大値 static int maxNo2Default = 10; // 第2項の最大値のデフォルト static int maxNo2; // 第2項の最大値(実際に使われる値) // コンストラクタ ProblemGenerator(int noProblems, int maxValue) { this(noProblems, maxValue, maxNo2Default); //別のコンストラクタを呼ぶ // コンストラクタの最初の文でのみこのようなことが可能 } // コンストラクタその2 ProblemGenerator(int noProblems, int maxValue, int maxNo2) { this.problemMemory = new String[noProblems]; // 問題記憶領域の準備 this.problemCounter = 0; // カウンタを0に this.maxAnswerValue = maxValue; // 答えの最大値 this.maxNo2 = maxNo2; } // 問題を生成するメソッド public String generate() { int no1, no2; // 第1項,第2項 String operator; // 演算子(+,-) String problem; // 問題文字列(例: 15-8) do { // 今までに生成されていない問題ができるまで繰り返し no1 = RandomInt.generate(maxAnswerValue); if (RandomInt.generate(2) == 1) { //足し算の場合 operator = " + "; // 答えがmaxAnswerValueを超えないように第2項を生成 int difference = maxAnswerValue - no1; no2 = difference < maxNo2 ? RandomInt.generate(difference) : RandomInt.generate(maxNo2); // ☆☆ 上の文は下の2行と同じこと // if (difference < maxNo2) no2 = RandomInt.generate(difference); // else no2 = RandomInt.generate(maxNo2); // この構文を「条件演算子」という。複雑な式を書くと // 読みにくくなるので,少しでも複雑になったら,if文で // 置き換えた方がよい。筆者はほとんど使わない。「まとめ」参照 currentAnswer = no1 + no2; } else { // 引き算の場合 operator = " - "; no2 = no1 > maxNo2 ? // ☆☆ この構文はすぐ上で説明済み RandomInt.generate(maxNo2) : RandomInt.generate(no1); currentAnswer = no1 - no2; } problem = no1 + operator + no2; // 文字列の連結 // System.out.println(problem); //デバッグ用に使った残骸 } // 同じ問題である限り繰り返し。 while (isSameProblem(problem)); problemMemory[problemCounter++] = problem; // ++が後ろについているので,1増える前の値で配列に記憶されて // からproblemCounterの値が1増える。 return(problem); // 問題を戻す } // すでに生成した問題かどうかチェック。 // すでに同じ問題があった → true  新しい問題 → false private boolean isSameProblem(String problem) { for (int i = 0; i < problemCounter; i++) { if (problemMemory[i].equals(problem)) return (true); // ☆☆ problemMemory[i] == problemではダメ // これでは,オブジェクト(文字列)のアドレスを比較している // ことになってしまう。 } return (false); } // 答え合わせをする public boolean checkAnswer(int answerFromUser) { // 記憶している答えと同じ → true,違う → false return (answerFromUser == currentAnswer); // 整数の比較なので「==」でOK。論理値が戻る } }