【Kotlin】確認問題5-☆1:モンスター捕獲ゲームを作ろう

記事内に商品プロモーションを含む場合があります

この記事の練習問題で使用する知識:
基礎文法、制御構造(レッスン1~2)関数の定義と呼出し関数の戻り値ジェネリクスnの基礎クラスの定義と使用プライマリコンストラクタクラスメンバとインスタンスメンバクラスの継承

Kotlinのゲームコード一覧はこちら

<<前のページ Kotlin記事一覧 次のページ>>

確認問題モンスター捕獲ゲームを作ろう

複数のモンスターを捕まえるゲームを作成しましょう。

このゲームではモンスターがサイコロを振り、その結果を見てプレイヤーはサイコロを振るかどうかを決めることができます。

プレイヤーのサイコロの目がモンスターのサイコロの目より大きければ捕獲成功。小さければ失敗でゲーム終了です。

この問題の要件

以下の要件に従ってプログラムを作成してください。

  1. 抽象クラス Character を定義
    • name という名前のプロパティを持ちます(String 型)。
    • サイコロを振る rollDice という関数を持ちます。この関数は 1 から 6 までのランダムな整数を返します。
  2. Character クラスを継承する Monster クラスを定義
    • コンストラクタでモンスターの名前を受け取ります。
  3. Character クラスを継承する Player クラスを定義
    • コンストラクタでプレイヤーの名前を受け取ります。
  4. main 関数でゲームを実行
    • Player オブジェクトを作成し、名前は「勇者」とします。
    • Monster オブジェクトを 3 つ作成し、それぞれ「ゴブリン」、「スライム」、「ドラゴン」という名前をつけます。
    • これらのモンスターを ArrayList に格納します。
    • プレイヤーが各モンスターを捕まえようとするループを実行します。ループの中で、プレイヤーはサイコロを振るかどうかを決めることができます。
    • プレイヤーのサイコロの目がモンスターのサイコロの目より大きければ捕まえることができます。失敗するとゲームオーバーとなり、ループが終了します。

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

ゴブリンを捕まえようとしています...
ゴブリンのサイコロ: 4
サイコロを振りますか? (yes/no): yes
プレイヤーのサイコロ: 6
ゴブリンを捕まえました!
スライムを捕まえようとしています...
スライムのサイコロ: 5
サイコロを振りますか? (yes/no): yes
プレイヤーのサイコロ: 3
スライムを捕まえられませんでした...
ゲームオーバー!

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:kotlin.random.Randomモジュールのインポート
2:抽象クラスCharacterの定義
  □ プライマリコンストラクタでnameプロパティを初期化
  □ rollDice関数の定義
  □ □ Random.nextIntを用いて1から6までのランダムな整数を返す
3:Monsterクラスの定義
  □ Characterクラスを継承
4:Playerクラスの定義
  □ Characterクラスを継承
5:main関数の定義
  □ Playerオブジェクトplayerの生成
  □ Monsterオブジェクトmonster1、monster2、monster3の生成
  □ ArrayListにモンスターを格納
  □ forループでmonstersリストを反復処理
  □ □ モンスターの名前を出力
  □ □ モンスターのrollDice関数を呼び出して結果をmonsterRollに格納
  □ □ monsterRollを出力
  □ □ 「サイコロを振りますか?」と出力
  □ □ ユーザー入力を受け取り、response変数に格納
  □ □ if文でresponseが”yes”と一致するか判定(大文字小文字を無視)
  □ □ □ プレイヤーのrollDice関数を呼び出して結果をplayerRollに格納
  □ □ □ playerRollを出力
  □ □ □ if文でplayerRollがmonsterRollより大きいか判定
  □ □ □ □ 成功メッセージを出力
  □ □ □ □ ゲーム続行
  □ □ □ else文
  □ □ □ □ 失敗メッセージを出力
  □ □ □ □ ゲームオーバーメッセージを出力
  □ □ □ □ breakでループ終了
  □ □ else文
  □ □ □ モンスター捕獲を諦めた旨を出力

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

import kotlin.random.Random

// 抽象クラス Character を定義
abstract class Character(val name: String) {
    // サイコロを振る関数
    fun rollDice(): Int {
        /* 【穴埋め問題1】
           ここにサイコロを振るためのランダムな数を生成するコードを書いてください。
        */
    }
}

// Character クラスを継承する Monster クラスを定義
class Monster(name: String) : Character(name)

// Character クラスを継承する Player クラスを定義
class Player(name: String) : Character(name)

fun main() {
    // プレイヤーを作成
    val player = Player("勇者")

    // モンスターを作成
    val monster1 = Monster("ゴブリン")
    val monster2 = Monster("スライム")
    val monster3 = Monster("ドラゴン")

    // モンスターを格納するArrayListを作成
    val monsters = arrayListOf(monster1, monster2, monster3)

    // プレイヤーがモンスターを捕まえようとするループ
    for (monster in monsters) {
        println("${monster.name}を捕まえようとしています...")
        val monsterRoll = monster.rollDice()
        println("${monster.name}のサイコロ: $monsterRoll")

        print("サイコロを振りますか? (yes/no): ")
        val response = readLine()?.trim() ?: ""

        if (response.equals("yes", ignoreCase = true)) {
            /* 【穴埋め問題2】
               ここにプレイヤーがサイコロを振るためのコードを書いてください。
            */
        } else {
            println("${monster.name}を捕まえるのを諦めました。")
        }
    }
}

この問題の穴埋めコードは以上です。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

モンスター捕獲ゲームの正解コードと解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

import kotlin.random.Random

// 抽象クラス Character を定義
abstract class Character(val name: String) {
    // サイコロを振る関数
    fun rollDice(): Int {
        return Random.nextInt(6) + 1  // 1から6までのランダムな数を返す
    }
}

// Character クラスを継承する Monster クラスを定義
class Monster(name: String) : Character(name)

// Character クラスを継承する Player クラスを定義
class Player(name: String) : Character(name)

fun main() {
    // プレイヤーを作成
    val player = Player("勇者")

    // モンスターを作成
    val monster1 = Monster("ゴブリン")
    val monster2 = Monster("スライム")
    val monster3 = Monster("ドラゴン")

    // モンスターを格納するArrayListを作成
    val monsters = arrayListOf(monster1, monster2, monster3)

    // プレイヤーがモンスターを捕まえようとするループ
    for (monster in monsters) {
        println("${monster.name}を捕まえようとしています...")
        val monsterRoll = monster.rollDice()
        println("${monster.name}のサイコロ: $monsterRoll")

        print("サイコロを振りますか? (yes/no): ")
        val response = readLine()?.trim() ?: ""

        if (response.equals("yes", ignoreCase = true)) {
            val playerRoll = player.rollDice()
            println("プレイヤーのサイコロ: $playerRoll")

            if (playerRoll > monsterRoll) {
                println("${monster.name}を捕まえました!")
            } else {
                println("${monster.name}を捕まえられませんでした...")
                println("ゲームオーバー!")
                break
            }
        } else {
            println("${monster.name}を捕まえるのを諦めました。")
        }
    }
}

正解コードの解説

今回はプレイヤーがモンスターを捕まえるゲームを作成しました。

このコードをブロックごとに分解し、初心者向けに解説します。

抽象クラス Character の定義

abstract class Character(val name: String) {
    fun rollDice(): Int {
        return Random.nextInt(6) + 1
    }
}
  • abstract class Character: これは抽象クラスで、具体的なインスタンスを作成できません。他のクラスが継承して使うことを目的としています。
  • val name: String: キャラクターの名前を表すプロパティです。
  • fun rollDice(): Int: サイコロを振る関数です。Random.nextInt(6) によって、1~6 のランダムな値を生成します。

Monster クラスと Player クラスの定義

class Monster(name: String) : Character(name)
class Player(name: String) : Character(name)
  • class Monster: Character クラスを継承しています。モンスター専用の追加機能はありません。
  • class Player: プレイヤーのクラスも Character を継承し、基本的に同じ構造です。

main関数とゲームのセットアップ

fun main() {
    val player = Player("勇者")
    val monster1 = Monster("ゴブリン")
    val monster2 = Monster("スライム")
    val monster3 = Monster("ドラゴン")

    val monsters = arrayListOf(monster1, monster2, monster3)
  • fun main(): Kotlinプログラムのエントリーポイントです。
  • val player = Player(“勇者”): プレイヤーのインスタンスを作成します。
  • val monsters = arrayListOf(…): モンスターをリストに格納し、順番に操作できるようにします。

モンスターとの対戦ループ

for (monster in monsters) {
    println("${monster.name}を捕まえようとしています...")
    val monsterRoll = monster.rollDice()
    println("${monster.name}のサイコロ: $monsterRoll")
  • for (monster in monsters): リスト内のモンスターを1体ずつ順番に処理します。
  • monster.rollDice(): モンスターがサイコロを振ります。

プレイヤーの選択と対戦結果の処理

    print("サイコロを振りますか? (yes/no): ")
    val response = readLine()?.trim() ?: ""

    if (response.equals("yes", ignoreCase = true)) {
        val playerRoll = player.rollDice()
        println("プレイヤーのサイコロ: $playerRoll")

        if (playerRoll > monsterRoll) {
            println("${monster.name}を捕まえました!")
        } else {
            println("${monster.name}を捕まえられませんでした...")
            println("ゲームオーバー!")
            break
        }
    } else {
        println("${monster.name}を捕まえるのを諦めました。")
    }
}
  • readLine(): コンソールからユーザーの入力を取得します。
  • response.equals(“yes”, ignoreCase = true): ユーザーが「yes」を入力したかを確認します。
  • player.rollDice(): プレイヤーがサイコロを振ります。
  • if (playerRoll > monsterRoll): プレイヤーのサイコロの値がモンスターより大きい場合、捕まえることに成功します。それ以外はゲームオーバーになります。

まとめ

このコードではKotlinの基本的なクラス構造やリスト操作、サイコロを使ったゲームロジックを学べます。

特に継承とループの使い方、そしてユーザー入力の処理が中心となっています。

これを応用して、さらに複雑なゲームやアプリを作成できるスキルを磨いていきましょう!

Kotlinのゲームコード一覧はこちら

<<前のページ Kotlin記事一覧 次のページ>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Kotlinテキスト&問題集へ戻る
    トップページへ戻る