数の神話:デジタル創世記

遠い昔 はるかかなたの銀河系で…
宇宙が虚無に包まれていた時代、0から9までの10個の数字だけがあった。

知恵の神アルカズはまず「0」で無を定義し、「1」で存在を定義した。
「2」を加えることで関係が生まれ、「3」では構造が生まれた。
こうして、アルカズは数字を組み合わせて、新たな意味と世界を生み出していった。

やがて、アルカズは数字の列「314159」を用いて時間を作り、
「299792458」で光を生み出した。
「137」で秩序の法則を編み出し、
「42」で存在の問いへのヒントを与えた。

それぞれの数字には力があり、並べ方次第で世界の性質が変わる。
アルカズが最も恐れた数は、「●」だった。
それは制御できず、世界を崩壊させる可能性があるからだ。

アルカズはこの「危険な数」を宇宙の端、時空の裏側に封印した。
だが、ある日――数字を操るKazuateが現れ、その封印に近づいてしまう。

その進化の道筋は、7つのレベル――プログラミングの知恵を体現するステージとなる。

「私たちはKazuate、誇りをもって戦いましょう」

7つそれぞれのレベルのパッケージを作成して準備してください。


レベル1:始まりの物語

学習目標:与えられた仕様書の内容を正しく読み取り、それに基づいてクラスを適切に設計・実装できる力を身につける。フィールドやメソッド、アクセス修飾子などの構成要素を仕様に従って正確に反映させることで、実践的なクラス設計のスキルを習得することを目的とする。

クラス図

クラス名:Kazuate1

概要
0~9 の正解数をランダムに生成し、ユーザーの予想を判定して結果メッセージを保持するコアロジッククラス。

フィールド

可視性属性名説明
privateintanswerランダムに生成された正解値(0~9)
privateStringmessage判定結果を格納する文字列

メソッド

修飾子戻り値シグネチャ説明
public-Kazuate1()コンストラクタ。Random.nextInt(10)answer を初期化
publicvoid checkTheAnswer(int guess)引数 guessanswer を比較し、message に「あたり!/もっと大きいよ。/もっと小さいよ。」を設定
publicint getAnswer()answer を返却
publicvoid setAnswer(int answer)answer を設定
publicString getMessage()message を返却
publicvoid setMessage(String message)message を設定
@Override
public
void String toString()デバッグ用に "[answer=…, message=…]" 形式の文字列を返却

クラス名:KazuateTest1

概要
標準入力から 0~9 の整数を一度だけ読み込み、Kazuate1 で判定を行い、結果を表示するシンプルなテストドライバクラス。

メソッド

修飾子戻り値シグネチャ説明
public static void main(String[] args)- 「0-9の整数で数を当ててください!」を表示
- Scanner で一度だけ整数入力
- Kazuate1 を生成して checkTheAnswer 実行
- 判定結果 (getMessage()) とデバッグ表示 (toString()) を出力

出力結果の例

0-9の整数で数を当ててください!
5
判定結果: もっと大きいよ。
デバッグ表示: [answer=6, message=もっと大きいよ。]

レベル2:複数インスタンスの共鳴

学習目標:クラスはオブジェクト指向における「設計図」の役割を果たし、実際に動作するのはその設計図から生成された「インスタンス(オブジェクト)」です。インスタンスは、それぞれが独立したフィールド(状態)を持ち、そのデータを用いてメソッド(振る舞い)を実行します。

本学習では、複数のインスタンスを生成し、それぞれが自身のフィールドを使って処理を行う様子を観察することで、クラスとインスタンスの関係、およびインスタンスが自律的に振る舞うという概念を実感することを目的とします。

クラス名: KazuateTest2

役割: このクラスは、数当てゲームを通して複数のインスタンスが独立して動作する様子を観察するためのプログラムです。

2人のプレイヤーごとに1つの Kazuate1 インスタンスを作成し、それぞれが異なる正解のもとで最大3回まで数を予想します。各インスタンスは自分専用の状態(正解やメッセージ)を保持しており、プレイヤー同士が互いに干渉することなくゲームを進められる点が特徴です。

Kazuate1は変更なし。

フィールドなし

メソッド説明

修飾子シグネチャ内容
public staticvoidmain(String[] args)Scanner を用意して標準入力を受け付ける。
Kazuate1 を2つインスタンス化(player1, player2)し、個別の正解値を生成。
プレイヤー1のターン:
最大3回まで予想を受け付けるループを開始。
入力された予想を player1.checkTheAnswer() に渡して判定を実行。
判定メッセージを getMessage() で取得し、表示。
「あたり!」だった場合はループを中断。
プレイヤー2のターン:
プレイヤー1と同様の処理を行う。
Scanner をクローズして終了。

出力結果の例

=== プレイヤー1の番です ===
予想を入力してください(0〜9): 5
もっと小さいよ。
予想を入力してください(0〜9): 5
もっと小さいよ。
予想を入力してください(0〜9): 3
もっと小さいよ。

=== プレイヤー2の番です ===
予想を入力してください(0〜9): 4
もっと大きいよ。
予想を入力してください(0〜9): 5
もっと大きいよ。
予想を入力してください(0〜9): 6
もっと大きいよ。

[デバッグ用] プレイヤー1の答え: 0
[デバッグ用] プレイヤー2の答え: 7


レベル3:メソッド分割の叡智

学習目標:プログラムにおける基本的な処理の流れ「入力 → 判定 → 表示」を意識し、その各段階を適切にメソッドとして分割することで、処理の見通しを良くし、保守性や再利用性の高いコードを実現する。

本学習では、メソッド分割を通して役割の明確化を図り、プログラムの構造を論理的に捉える力を身につけることを目的とする。

クラス図

クラス名KazuateTest2

概要
ユーザーからの入力を取得し、Kazuate1 インスタンスで一度だけ数当て判定を行って結果を表示するテストドライバクラス。

メソッド一覧

修飾子戻り値シグネチャ説明
public static void main(String[] args)アプリケーションのエントリポイント。
1) readUserInput() で予想値を取得
2) createGame(int)Kazuate1 を生成・判定
3) displayResult(Kazuate1) で結果を表示
public static int readUserInput()Scanner を用いて 0–9 の整数を標準入力から読み込む。
入力待ち後に Scanner をクローズし、取得値を返却
public static Kazuate1 createGame(int guess)Kazuate1 の新規インスタンスを生成し、引数 guesscheckTheAnswer に渡して判定を実行。
完成したオブジェクトを返却
public static void displayResult(Kazuate1 k)引数に渡された Kazuate1 オブジェクトから getMessage()toString() を呼び出し、判定結果とデバッグ情報を標準出力に表示

出力結果の例

0〜9の整数を入力してください: 5
判定結果: もっと大きいよ。
デバッグ表示: [answer=9, message=もっと大きいよ。]


レベル4:例外を乗り越える盾

学習目標:ユーザーからの入力に対して、想定外の値やエラーが発生する可能性を考慮し、例外処理を用いてプログラムが正常に動作し続けるように制御できる力を身につける。try-catch文などを活用して、エラー発生時の適切な対応やメッセージの表示を行うことで、信頼性の高いプログラムの作成を目指す。

クラス名KazuateTest4

概要
ユーザーからの入力を安全に読み取り、Kazuate1 インスタンスで数当てゲームを実行し、結果を標準出力に表示するテスト用ドライバクラス。


主な役割・機能

  1. ユーザー入力の取得と検証
    • 標準入力から 0~9 の整数を読み込む
    • 非整数入力をキャッチしてプログラムを終了
  2. ゲームインスタンスの生成と判定
    • Kazuate1 のコンストラクタでランダムに正解数を生成
    • ユーザーの予想値を checkTheAnswer(int) メソッドで評価
  3. 結果の表示
    • 判定メッセージ(getMessage())とデバッグ用文字列(toString())を表示

メソッド一覧

修飾子戻り値シグネチャ説明
public staticvoid main(String[] args)アプリケーション入口。
1)readUserInput() で予想値取得
2)createGame(int) でゲーム実行
3)displayResult(Kazuate1) で結果表示
public staticint readUserInput()Scanner を用いて 0~9 の整数を入力。
不正入力時はメッセージ出力後 System.exit(1)
public staticKazuate1 createGame(int guess)Kazuate1 インスタンスを生成し、guesscheckTheAnswer を実行。
public staticvoid displayResult(Kazuate1 k)k.getMessage()k.toString() を標準出力に表示。

例外処理

  • InputMismatchException
    • 非整数入力を検知し、エラーメッセージを出力して終了
  • 範囲外チェック
    • guess < 0 || guess > 9 の場合、警告メッセージを出力して終了

出力結果の例

0〜9の整数を入力してください: a
エラー: 整数を入力してください。
0〜9の整数を入力してください: 11
エラー: 入力は0から9の範囲でお願いします。
0〜9の整数を入力してください: 5
判定結果: あたり!
デバッグ表示: [answer=5, message=あたり!]

レベル5:例外をthrowせよ

学習目標:例外が発生した場合に、その場で処理を行うのではなく、throw を用いて例外を呼び出し元のメソッドに伝えるクラスを作成できるようになる。これにより、例外処理の責任を適切に分離し、柔軟で保守性の高いプログラム設計を習得することを目的とする。

KazuateTest5 は入力と表示の役割に専念し、Kazuate2 が範囲チェックと判定ロジックを担う責務分離をする。


クラス名:Kazuate2

概要
0~9 の正解数をランダム生成し、ユーザーの予想を判定して結果メッセージを保持する。入力範囲外の場合は例外処理により専用メッセージを返す。

フィールド

可視性名前内容
privateintanswerランダムに生成された正解(0~9)
privateStringmessage判定結果を格納する文字列

メソッド

修飾子戻り値シグネチャ説明
public-Kazuate2()コンストラクタ。Random.nextInt(10)answer を初期化
publicvoid checkTheAnswer(int guess)throws IllegalArgumentException- guess が 0~9 範囲外なら引数に"入力は0から9の範囲でお願いします。" を渡したIllegalArgumentExceptionを送出して即リターン
- 範囲内なら正誤を判定し、message を「あたり!」/「もっと大きいよ。」/「もっと小さいよ。」で設定
publicint getAnswer()answer を返却
publicvoid setAnswer(int answer)answer を設定
publicString getMessage()message を返却
publicvoid setMessage(String message)message を設定
@Override
public
String toString()デバッグ用表示。"[answer=…, message=…]" 形式で返却

クラス名:KazuateTest5

主な役割・機能

概要
ユーザーからの入力を取得し、Kazuate2 インスタンスで数当てゲームを実行、結果を標準出力に表示するドライバクラス。

  1. ユーザー入力の取得(0~9 の整数)
  2. 範囲外入力時のメッセージ出力ではなく、Kazuate2 側での判定へ委譲
  3. ゲーム実行後、メッセージとデバッグ情報を表示

メソッド一覧

修飾子戻り値シグネチャ説明
public staticvoid main(String[] args)起動後のフローを制御。
1)readUserInput() で予想値取得
2)createGame(int) でゲーム実行
3)displayResult(Kazuate2) で結果表示
public staticint readUserInput()Scanner で整数を入力。
非整数入力時はメッセージ出力後 System.exit(1)
public staticKazuate2 createGame(int guess)Kazuate2 インスタンスを生成し、guesscheckTheAnswer で評価。例外が発生した場合は例外を補足してメッセージ出力後 System.exit(1)
public staticvoid displayResult(Kazuate2 k)k.getMessage()k.toString() を出力。

例外処理

  • InputMismatchException
    • 非整数入力を検知し、エラーメッセージ出力後に強制終了
  • 範囲チェックは行わず、Kazuate2.checkTheAnswer に委譲

出力結果の例

整数値以外が入力されたケース

0〜9の整数を入力してください: a
エラー: 整数を入力してください。

0〜9の整数を入力してください: 2.0
エラー: 整数を入力してください

-1
0〜9の整数を入力してください: 

0〜9の整数を入力してください: 5
判定結果: もっと大きいよ。
デバッグ表示: [answer=8, message=もっと大きいよ。]

レベル6:知識を蓄えるアレイリスト

学習目標:可変長のデータ構造である ArrayList を活用し、要素の追加・取得・削除などの基本操作を理解して使いこなせるようになる。また、ArrayList の特性を理解し、配列との違いや使い分けができる力を身につける。


クラス名:Kazuate3

概要
0~9 の正解数をランダム生成し、ユーザーの予想を判定・履歴管理するロジックを提供するクラス。
不正入力(範囲外)の場合は IllegalArgumentException を投げることで呼び出し元に再入力を促す。

フィールド

可視性名前内容
privateintanswerランダムに生成された正解値(0~9)
privateStringmessage判定結果メッセージ(あたり!/もっと大きいよ。/もっと小さいよ。)
privateArrayList<Integer>guessHistory正常入力されたすべての予想値を順に記録するリスト

メソッド

修飾子戻り値シグネチャ説明
public-Kazuate3()コンストラクタ。Random.nextInt(10) により answer を初期化し、guessHistory を空の ArrayList で生成
publicvoid checkTheAnswer(int guess) throws IllegalArgumentException- guess が 0~9 の範囲外なら例外を投げる
- 正常な入力は guessHistory に追加し、正誤を判定して message を設定
publicint getAnswer()正解値を返却
publicvoid setAnswer(int answer)正解値を手動設定
publicString getMessage()判定結果メッセージを返却
publicvoid setMessage(String message)メッセージを手動設定
publicArrayList<Integer> getGuessHistory()これまでの予想履歴を返却
@Override
public
String toString()「デバッグ用 [answer=…, message=…]」形式の文字列を返却

クラス名:KazuateTest6

概要
Kazuate3 を使ってユーザーとの対話ループを回し、正解が当たるまで繰り返し予想を促すテストドライバ。例外と入力ミスマッチを捕捉しつつ、最終的に正解と入力履歴を表示する。

メソッド一覧

修飾子戻り値シグネチャ説明
public staticvoid main(String[] args)- Kazuate3 インスタンス生成
- Scanner で予想値を読み取りつつループ
- checkTheAnswer 呼び出し
- 例外時はメッセージ表示後再ループ
- 「あたり!」でループ脱却
- 終了後に displayResult 呼び出し
public staticint readUserInput(Scanner sc)- sc.nextInt() で整数を読み込む
- InputMismatchException 時はエラーメッセージを表示しバッファクリア
- -1返却で不正入力扱い
public staticvoid displayResult(Kazuate3 k)- ゲーム終了時に正解 (k.getAnswer()) と全予想履歴 (k.getGuessHistory()) を出力

出力結果の例

0〜9の整数を入力してください: 1
もっと大きいよ。
0〜9の整数を入力してください: 5
もっと小さいよ。
0〜9の整数を入力してください: 3
もっと小さいよ。
0〜9の整数を入力してください: 2
あたり!
正解: 2
予想履歴: [1, 5, 3, 2]


レベル7:継承と多態性の極致

学習目標:共通のメソッド checkTheAnswer(int) を用いた呼び出しであっても、各サブクラスが独自にオーバーライドした判定ロジックを実行する「多態性(ポリモーフィズム)」の仕組みを体験的に理解する。これにより、同じインタフェースやメソッド名であっても、実行時にはオブジェクトの型に応じた適切な処理が行われることを学び、オブジェクト指向の柔軟な設計思想を身につける。


クラス図

クラス一覧

1. DistanceKazuate extends Kazuate1

概要
正解との「距離」が 5 以上あれば "全然違う" と一刀両断し、それ以外は親クラスのロジックを流用する。

修飾子戻り値シグネチャ説明
@Override
public
void checkTheAnswer(int guess)正解との「距離」が 5 以上あればmessage="全然違う" を設定し即リターン
それ以外は親クラスのロジックを流用する

2. HistoryKazuate extends Kazuate1

概要
すべての予想値を内部リストに記録し、通常の判定ロジックも併用できるサブクラス。

可視性名前説明
privateList<Integer>history予想値を順に格納する不変リスト
修飾子戻り値シグネチャ説明
@Override
public
void checkTheAnswer(int guess)- history.add(guess) で記録後、super.checkTheAnswer(guess) 呼び出し
publicList<Integer> getHistory()現在までの予想履歴を返却

3. KazuateLuckySeven extends Kazuate1

概要
「ラッキーセブン」(予想も正解も 7)のとき特別メッセージを返し、それ以外は通常のヒントを出すサブクラス。

修飾子戻り値シグネチャ説明
@Override
public
void checkTheAnswer(int guess)- guess == 7 && answer == 7message="ラッキーセブン!大当たりです!"
- それ以外 → 通常ヒント (あたり!/もっと大きいよ。/もっと小さいよ。)

4. KazuateWithLives extends Kazuate1

概要
残りライフ制を導入し、ライフが尽きるとゲームオーバー、正解判定時は通常通り「あたり!」。ヒントには残りライフ数を付加。

可視性名前初期値説明
privateintlives5残り試行回数
修飾子戻り値シグネチャ説明
@Override
public
void checkTheAnswer(int guess)- lives <= 0"ゲームオーバー!もう試せません。"
- 正解 → "あたり!"
- 不正解 → lives--→ ライフ0なら "残りライフ0…ゲームオーバー!"、それ以外は "もっと大きいよ。残りライフ:n" など
publicint getLives()現在の残ライフ数を返却

5. ReverseHintKazuate extends Kazuate1

概要
常に嘘のヒントを言うサブクラス(通常「小さすぎ」なら「もっと大きいよ。」だが逆に、「小さすぎ」なら「もっと小さいよ。」と返す)。

修飾子戻り値シグネチャ説明
@Override
public
void checkTheAnswer(int guess)- answer == guess"あたり!"
- answer > guess"もっと小さいよ。"
- answer < guess"もっと大きいよ。"

6. KazuatePolymorphismTest

概要
5種類の Kazuate1 サブクラスをひとつのリストに詰め込み、同一の checkTheAnswer 呼び出しで各クラスの振る舞いが切り替わることを確認するテストドライバ。

修飾子戻り値シグネチャ説明
public staticvoid main(String[] args)- 各サブクラスのインスタンスを List<Kazuate1> に追加
- 正解を固定 (7)
- 一連の予想をループで評価・表示
- HistoryKazuate は履歴表示
- KazuateWithLives は残りライフを表示

出力結果の例

=== DistanceKazuate ===
Guess 2 → 全然違う
Guess 5 → もっと大きいよ。
Guess 8 → もっと小さいよ。
Guess 7 → あたり!

=== HistoryKazuate ===
Guess 2 → もっと大きいよ。
Guess 5 → もっと大きいよ。
Guess 8 → もっと小さいよ。
Guess 7 → あたり!
History: [2, 5, 8, 7]

=== KazuateLuckySeven ===
Guess 2 → もっと大きいよ
Guess 5 → もっと大きいよ
Guess 8 → もっと小さいよ
Guess 7 → ラッキーセブン!大当たりです!

=== KazuateWithLives ===
Guess 2 → もっと大きいよ。残りライフ:4
Guess 5 → もっと大きいよ。残りライフ:3
Guess 8 → もっと小さいよ。残りライフ:2
Guess 7 → あたり!
Life: 2

=== ReverseHintKazuate ===
Guess 2 → もっと小さいよ
Guess 5 → もっと小さいよ
Guess 8 → もっと大きいよ
Guess 7 → あたり

伝説はつづく

こうして Kazuate は、複数インスタンスから始まり、メソッド分割、例外処理、アレイリストを経て、継承と多態性を極めた存在となった。

あなたは今、この物語の語り手であり、同時に設計者でもある――次はどのような試練が与えられるだろうか?

銀河の未来は、あなたの手の中にある。

以上。

JavaSEの問題集トップページに戻る