Java Basic 中級編 ~③メインメソッドを修正しないで拡張する~

イントロダクション

前回は、メインメソッドを修正しない形での実装を行いました。

この段階では、まだ役割分担を行っただけでこれがどんな効果があるのか?というところがわからないと思います。

なので、今回は、「〇×あてゲーム」を拡張することを考えていきたいと思います。
作成したプログラムコードはGithubにアップしてあります。

メインメソッドを修正しないで拡張する

今までに「役割分担」を行ったので、この役割分担を活用していきます。
Lv2Mainクラスはメインメソッドを動かすクラスなので、これ以外のクラスを実装していきます。

  • Lv2Main
  • MarubatsuConsole
  • MarubatsuUtils

Lv2Mainを見る

まずは、メインメソッドを見てみます。Lv2Main

/**
 * Javaの基本レベル2:小さなレベルのプログラムを拡張する。
 * 今回は、〇か×か当てるゲーム。
 */
public class Lv2Main {
    /** 終了フラグ */
    private static boolean isFinish;

    public static void main(String[] arg) {
        isFinish = false;
        // 標準入力を受け取るクラスをインスタンス化
        Scanner scan = MarubatsuUtils.getScanner();

        while (true) {
            // ゲーム開始文言
            MarubatsuConsole.printGameStart();
            // 標準入力を受け取る
            int input = scan.nextInt();
            // isFinishがtrueならば処理終了。
            if (isFinish) {
                MarubatsuConsole.printTerminated();
                break;
            }
            // 0か1の値を返却する
            int res = MarubatsuUtils.nextInt(2);

            // 0: 〇 1: ×で当たったかどうかの判定
            boolean isAtari = MarubatsuUtils.judgeAtariOrNot(res, input);
            MarubatsuConsole.printAtatiorNot(isAtari, input);

            // 続けるのかどうか判定する
            if (MarubatsuConsole.printNextPlayOrNot(scan)) {
                break;
            }
        }
    }
}

コメントを並べただけですが、以下の順序で処理を行っています。

  1. 標準入力を受け取るクラスをインスタンス化
  2. ゲーム開始文言
  3. 標準入力を受け取る
  4. isFinishがtrueならば処理終了。
  5. 0か1の値を返却する
  6. 0: 〇 1: ×で当たったかどうかの判定
  7. 続けるのかどうか判定する

上の番号で行くと2~7がループ処理の中にあります。
なので、7の「続けるか判定する」部分でNo(続けない)を選択するまで無限ループします。

インスタンス化

Boolean

標準入力

フィールド変数の扱い

拡張ポイントを見つける

そして、役割分担を行ったところ、つまりは、下のクラスを使用している部分が拡張ポイントになります。
Githubにアップしてあります。

具体的には、以下のコメント部分です。

  • ゲーム開始文言
  • isFinishがtrueならば処理終了。の終了表示部分
  • 0か1の値を返却する
  • 0: 〇 1: ×で当たったかどうかの判定
  • 続けるのかどうか判定する

もしも、他の部分を拡張したいと思たのならば、メインメソッドを少し修正する必要があります。
何かの処理をほかのクラスに任せてある状態(MarubatsuConsole, MarubatsuUtilsを使用している状態)ならば
メインメソッドを修正する必要がありません。
しかし、直接メインメソッドを修正する必要がある場合はやはり、修正する必要があります。

このような実装方法を理解すると、下のようなプログラムが作れます。

※ビルドするのに3分くらい時間がかかっています。
このプログラムは、メインの処理部分も、別クラスにしているので、まったく別のプログラムを起動するように修正することもできます。
しかし、現状では、テキストRPGを作成するところに注力しているので役割分担を行いそれぞれの役割を拡張して実装しています。
具体的には、テキストファイルを読み、それをもとにデータ(ステータスやアイテム)を生成してそれをゲームの中で使用する形での実装を行っております。
ちょっと残骸が残っていますが。。。

拡張するとき

先に示したように、別のクラスを呼び出している(使用している)部分を拡張、つまり処理を追加することができるので、次の部分を拡張することができます。

  • ゲーム開始文言
  • isFinishがtrueならば処理終了。の終了表示部分
  • 0か1の値を返却する
  • 0: 〇 1: ×で当たったかどうかの判定
  • 続けるのかどうか判定する

具体的には、ゲーム開始文言を変更することができる。とか、当たったかどうかの履歴を付ける。とか
そこらへんは、実装者のアイディア次第でどこまでも広げることができます。

ゲームの開始文言を変更する

先ほど、拡張する例としてゲームの開始文言を変更するということを上げました。これを実際にやってみます。

やっている手順としては、以下の通りです。

  1. JUnitテストケースの作成
  2. 現状のプログラム実行確認
  3. プログラムの修正、実行確認(目視で確認)

最後の実行確認(目視で確認)に関しては、すべてプログラムで確認することができます。
そのためには、ちょっと面倒なことをする必要があるので、割愛しました。
具体的には標準出力の出力先を変更して(別のPrintStreamを使用)そのストリーム内の出力内容と期待値を比較するという形になります。

現状としては、単純に〇×あてゲームの初期表示文言を変更するだけなので、目視で確認しました。

0: 〇 1: ×で当たったかどうかの判定

この部分は上記の動画では、挙動がおかしくなっていました。なので、これを修正し想定通りの実行結果が得られるようにプログラムを修正します。

実行した結果は下のようになります。

******************************
*「〇×あてゲーム」 0: 〇 1: ×。 *
******************************
※0は「〇」を表し1は「×」を表します。
1
はずれ:×
続けますか? 0: 続ける  1: やめる
0
******************************
*「〇×あてゲーム」 0: 〇 1: ×。 *
******************************
※0は「〇」を表し1は「×」を表します。
1
はずれ:×
続けますか? 0: 続ける  1: やめる
1

その前に、問題点を明確にします。

今回の問題点は「あたりのときの値、つまりは、『〇』が当たりなのか?『×』が当たりなのか?」が明確でないというところです。
なので、これも修正します。

先ほどと同じようにまずは、修正ポイント(先ほどは拡張ポイントと記載しました。)を見つけます。
実行結果を見ると、「はずれ:×」のように当たりはどちらなのか?がわからない状態ですので、これを明確にします。

具体的には、「「〇」があたりです。「×」が当たりですなどの文言を表示するように修正」する形で対応しようと考えております。

当然、他に良いアイディアがあれば、それを実装するとよいと思います。

当たり判定処理の修正

今回作成した「当たり判定処理」は、MarubatsuUtils#judgeAtariOrNotで実装しているのでこれを修正します。

現状のプログラムは下のようになっています。

    /**
     * 生成した乱数と、入力値が等しいか判定する。
     *
     * @param res 生成した乱数
     * @param input 入力値
     * @return true: 等しい false: 違う
     */
    public static boolean judgeAtariOrNot(int res, int input) {
        // 0: 〇 1: ×で当たったかどうかの判定
        return res == input;
    }

このプログラムの問題点は、〇と×のどちらが当たりなのか表示されない点です。
なので、これを表示するようにプログラムを修正する必要があります。

テストケースを作成する

先ほど初期表示の文言を表示するテストケースを作成しました。
これに追加して、「〇と×のどちらが当たりなのか表示する」テストケースを実装します。

仕様から考える

今回の要件(どのように動いたらよいか?)は「〇と×のどちらが当たりなのか表示する」ということです。
これを確かめるプログラムを考えます。

確認項目をリストアップ

  1. あたりは「〇」「×」どちらか表示する
  2. 予想を入力したユーザーの入力は「〇」「×」どちらか表示する

簡単ですが、2項目になります。

これもテストケースを作成する

ちなみに、このクラスのテストケースは以前、他のテストケースを作成していたので、これに今回のテストケースを追加します。

JUnitのセットアップ方法

テストケースの作り方①

テストケースの作り方②

テスト実行

サンプル動画

やったことは、同じです。

  1. 現状のプログラム実行確認
  2. プログラムの修正
  3. プログラムの実行確認

ちょっと長めの動画になりましたが、行ったことをそのまま動画にしてあります。
ポイントとしては、テストケースのプログラムの実装、作成方法、考え方(この記事に記載)を実際に行った
動画にしてあります。
別な言い方をすると、自分がこの作業を行ったものを動画にしました。

でわでわ。。。

<<< 前回

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す