Skip to content
Playground

演習: ミニゲーム集

各問題のコードは、Main クラスの main メソッドの中に書く前提です。標準入力には Scanner、乱数には Math.random() または java.util.Random を使ってください。各問題は1〜3時間で完成する規模で、易しい順に並んでいます。

3ラウンド行います。各ラウンドで、ユーザーが 1〜6 のいずれかを予想します。コンピュータがサイコロを振り、出た目と一致した回数を最後に表示します。

出力例:

サイコロを3回振ります。1〜6 のどれが出るかを毎回予想してください。
ラウンド 1 > 3
出た目: 5 → 外れ
ラウンド 2 > 2
出た目: 2 → 当たり!
ラウンド 3 > 6
出た目: 1 → 外れ
結果: 3回中 1回 的中
ステップ
  1. ユーザーの予想を入力で受け取り、サイコロの目を乱数で生成して、当たり/外れを表示する。
  2. これを3ラウンド繰り返し、最後に当たり回数を表示する。
ヒント

1〜6 の整数は (int)(Math.random() * 6) + 1 で生成できます。

ユーザーの予想は ScannernextInt() で受け取れます。for ループで 3 ラウンド回し、予想と出た目が一致した回数をカウンタ変数に貯めて、ループを抜けた後に表示します。

コンピュータが 1〜100 の中からランダムに整数を1つ選びます。ユーザーが 1〜100 の整数を入力するたびに、コンピュータは「もっと大きい」「もっと小さい」を返します。正解したら何回で当てたかを表示してください。

出力例:

1〜100 の数字を当ててください。
> 50
もっと大きい
> 75
もっと小さい
> 60
もっと小さい
> 55
正解! 4回で当てました。
ステップ
  1. 答えを固定値(例: 47)にしておき、ユーザー入力を1回受け取って「もっと大きい」「もっと小さい」「正解」を表示する。
  2. 答えを乱数で生成し、正解するまで繰り返して試行回数を表示する。
ヒント

答えは (int)(Math.random() * 100) + 1 で 1〜100 の整数を作り、ループに入る前に1度だけ決めておきます。

while ループの構造:

  • 試行回数を 0 で初期化
  • ループの中で入力を1つ受け取り、試行回数を +1
  • 答えと比較して「もっと大きい」「もっと小さい」「正解」を表示
  • 正解なら break でループを抜ける

正解時のメッセージで試行回数を表示します。

コンピュータが 1〜13 のカードを次々と引いていきます。ユーザーは、現在表示されている「場のカード」に対して、次に引かれるカードがそれより大きい(H)か小さい(L)かを予想します。

予想が当たれば、新しく引いたカードが次の場のカードになり、次のラウンドへ進みます。引いたカードが場のカードと同じ値だった場合は引き分けで、連続正解のカウントは変えずに、場のカードはそのままで再度予想します。

5回連続で正解すれば勝ち、1回でも外せば負けです。

出力例:

場のカード: 7
H or L? > H
引いたカード: 11 → 当たり (1/5)
場のカード: 11
H or L? > L
引いたカード: 4 → 当たり (2/5)
場のカード: 4
H or L? > H
引いたカード: 4 → 引き分け(再予想)
場のカード: 4
H or L? > H
引いたカード: 9 → 当たり (3/5)
...
5回連続で当てました!勝利。
ステップ
  1. 場のカードと引いたカードを乱数で生成し、ユーザーの予想(H/L)を入力で受け取って、正誤を表示する。
  2. 5連続正解か1回外しになるまで繰り返す。
  3. 引き分けのときは、連続正解数を増やさず、同じ場のカードでもう一度予想を受け付ける。
ヒント

カードは 1〜13 の整数で表現します。場のカードと引いたカードの2つの変数を持ち、ラウンドごとに引いたカードを新しい場のカードに上書きします(引き分けのときは上書きしません)。

入力は Scanner.next() で文字列として受け取り、"H" "L" との比較は大文字小文字を吸収するため equalsIgnoreCase を使います。

while ループの中で、連続正解数を管理する変数(例: streak)を進めます:

  • 当たり → streak++、次ラウンドへ
  • 引き分け → streak はそのまま、同じ場のカードでもう一度入力を受け付ける
  • 外れ → 負けて break
  • streak == 5 で勝利して break

コンピュータが、重複しない 3桁の数字(例: 547)をランダムに決めます。ユーザーは3桁の数字を入力して当てに行き、コンピュータは結果を以下の形で返します。

  • Hit: 数字も位置も合っている桁の数
  • Blow: 数字は合っているが位置が違う桁の数

例: 答えが 547、ユーザー入力が 527 の場合

  • 5(1桁目): 答えの1桁目と一致 → Hit
  • 2(2桁目): 答えに含まれない → なし
  • 7(3桁目): 答えの3桁目と一致 → Hit
  • 結果: 2 Hit, 0 Blow

3 Hit になればクリア。何回で当てたかを最後に表示します。

出力例:

重複しない3桁の数字を当ててください。
> 123
1 Hit, 1 Blow
> 145
0 Hit, 2 Blow
> 547
3 Hit! 7回で当てました。
ステップ
  1. 答えとユーザー入力を固定値として、Hit と Blow を計算してコンソールに表示する。
  2. ユーザー入力を受け取り、3 Hit になるまで繰り返す。試行回数も数え、勝ったときに表示する。答えは固定のまま。
  3. 固定値だった答えを乱数で生成する。この時点では重複が出てもよい。
  4. 重複しない3桁を生成するように変える。
ヒント

判定は、答えとユーザー入力をそれぞれ3要素の配列にして、各位置を比較します。

  • 同じ位置で同じ数字 → Hit
  • それ以外で、答えに含まれる数字 → Blow

入力 123 を桁ごとに分けるには、2つの方法があります。

  • String で受け取り charAt(i) で1文字ずつ取り出す。char を整数に直すには '5' - '0' のように '0' を引きます。
  • 整数で受け取り、100 の位 = n / 10010 の位 = (n / 10) % 101 の位 = n % 10 で取り出します。

答えの3桁を作る方法も2つあります。

発展課題
  • 手書き Fisher-Yates を Collections.shuffle に、Blow 判定の二重ループを List.contains に置き換える
  • 不正な入力("abc""12" など)を弾き、再入力を促す
  • 答えの生成や入力検証を独立したメソッドに切り出し、コード中のマジックナンバーを名前付き定数にする

4×4 の盤面に、1〜8 の数字を2枚ずつランダムに配置します(合計16マス)。ユーザーは2マスの位置を順に指定し、同じ数字なら開いたまま、違えば次のターンに進む際に再び伏せられます。全ペアを揃えるまでに何手かかったかを表示します(1手 = 2マス開く)。

出力例(簡略化):

盤面:
? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?
1枚目の位置(行 列) > 0 0
2枚目の位置(行 列) > 1 2
3 ? ? ?
? ? 3 ?
? ? ? ?
? ? ? ?
ペア!
1枚目の位置(行 列) > 0 1
2枚目の位置(行 列) > 2 2
3 5 ? ?
? ? 3 ?
? ? 7 ?
? ? ? ?
ペアではありません
[次のターンの開始時に、(0,1) と (2,2) は再び ? に戻る]
...
すべて揃いました! 13手で完了。
ヒント

盤面の管理には2つの2次元配列を使います。

  • int[][] board: 各マスの数字(1〜8)
  • boolean[][] revealed: 各マスが公開されているかどうか

盤面の作り方:

1ターンの流れ:

  • 盤面を表示(revealed[i][j]true なら数字、false なら ?
  • 1枚目の位置を入力で受け取り、revealedtrue にして再表示
  • 2枚目の位置を入力で受け取り、同様に表示
  • 数字が一致すればそのまま、違えば両マスの revealedfalse に戻す

すべてのマスが true になったら終了。手数のカウンタは2枚目を開いたタイミングで +1 します。

入力の妥当性チェック(範囲外、既に公開済み)も入れると堅牢になります。

カードの合計を 21 に近づけるカードゲームです。プレイヤーとディーラーが対戦します。

ルール:

  • カードは 1〜13 が引くたびにランダムに決まります(無限デッキとして扱い、同じ数字が複数回出ても構いません)
  • 111213(J・Q・K)は 10点 として扱う
  • 1(A)は 1点 または 11点 のうち、合計が 21 を超えないように有利な方を採用
  • プレイヤーは最初に2枚配られ、その後「ヒット(もう1枚引く)」か「スタンド(やめる)」を選ぶ。何度でも繰り返せる
  • 合計が 22 以上になったら バスト(その時点で負け確定)
  • プレイヤーがスタンドしたら、ディーラーが合計17以上になるまでヒットする
  • 双方の合計を比較し、バストしていない方が勝ち。両方バストならディーラー勝ち、同点ならプレイヤー負け(簡易ルール)

出力例:

あなたの手札: [10, 7] = 17
ヒット (h) or スタンド (s) > s
ディーラーの手札: [9, 5, 13] = 24 → バスト
あなたの勝ち!
ヒント

手札は ArrayList<Integer> で持つと、add でカード追加・size で枚数取得が楽です。

カード値の補正:

  • 11・12・13(J・Q・K)は得点計算時に 10 として扱う
  • 1(A)は、まず全部 11 として合計を計算し、22 を超えるなら A を1枚ずつ 1 に降ろしていく

合計を計算するメソッド(例: score(ArrayList<Integer> hand))を切り出すと、プレイヤーとディーラーの両方で使い回せます。

ゲームの流れ:

  • プレイヤーに2枚配る
  • プレイヤーの手番: while ループでヒット/スタンドを受け付ける。バストか s 入力で抜ける
  • ディーラーの手番: 合計が 17 以上になるまで while ループで引く
  • 最後に両方の合計を比較