Kotlin練習問題3-☆1:MutableMapを使ってナインゲームを作ろう

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

Kotlinの初心者向け問題3-☆1:MutableMapを使ってナインゲームを作ろう

この問題を解くために必要な知識:

【レベル1~2の知識】
コメントの書き方、変数と定数、基本データ型、算術演算と論理演算、入力と出力、import文、配列、分岐処理(if、if~else、when)、繰り返し処理(for、while、do~while)、Null安全、スマートキャスト、関数の定義と呼び出し、関数の戻り値、関数のオーバーロード、ラベルとジャンプ、例外処理、クラスの定義と使用、インスタンス、コンストラクタ、プロパティ、クラスの継承、クラスの拡張

【レベル3の知識】
コレクションの基礎、リストコレクション(MutableList、ArrayList)セットコレクション(HashSet、MutableSet、TreeSet)、マップコレクション(HashMap、MutableMap、TreeMap)

<<前の問題 問題集Top 次の問題>>

Kotlin練習問題3-☆1:MutableMapを使ってナインゲームを作ろう





ナインゲームを作成しましょう。

ナインゲームはプレイヤーとコンピュータが対戦するシンプルなゲームです。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • プレイヤーとコンピュータは1から9までの9枚の牌を持っています。
  • プレイヤーとコンピュータはそれぞれのターンで牌を一枚選びます。
  • 牌の数字を比較し、大きい数字を出した方にその数字と同じ数の得点が入ります。
  • 一度出した牌は再び使用することはできません。全ての牌が使われるまでゲームは続きます。
  • 最終的に得点が多い方が勝者となります。
  • プレイヤーの牌はユーザーが入力し、コンピュータの牌はランダムに選ばれます。
  • ゲームの進行に合わせて、各ターンの状況と結果を表示してください。

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

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

ナインゲームを開始します!
プレイヤーの持ち牌 ⇒「1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9」
コンピュータの持ち牌⇒「1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9」

【第1回戦】
プレイヤーの得点 : 0点
コンピュータの得点: 0点
持ち牌の中から出す牌を選択してください > 9
コンピュータの打牌:5
プレイヤーの打牌:9 > 5:コンピュータの打牌
プレイヤーは9点獲得

プレイヤーの持ち牌 ⇒「1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,-」
コンピュータの持ち牌⇒「1 ,2 ,3 ,4 ,- ,6 ,7 ,8 ,9」
...

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

この問題を解くヒント

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

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

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

1.Randomクラスのインポート
2.main関数の定義
 2-1. ゲーム開始のメッセージを表示
 2-2. プレイヤーとコンピュータの持ち牌を初期化するマップの作成
  2-2-1. playerTilesの作成
  2-2-2. computerTilesの作成
  2-2-3. 1から9までの数字をキーとして持ち、値をtrueに設定
 2-3. プレイヤーとコンピュータのスコアを初期化
 2-4. 9回戦を行うためのループ
  2-4-1. 現在のラウンド数と得点を表示
  2-4-2. プレイヤーの持ち牌を表示
  2-4-3. コンピュータの持ち牌を表示
  2-4-4. プレイヤーの打牌を入力
   2-4-4-1. 持ち牌の中から出す牌を選択
   2-4-4-2. 入力された牌が既に使われているかをチェックし、再入力を促す
  2-4-5. コンピュータの打牌をランダムに選択
  2-4-6. プレイヤーとコンピュータの打牌を比較し、勝敗を決定
   2-4-6-1. プレイヤーが勝った場合の処理
   2-4-6-2. コンピュータが勝った場合の処理
   2-4-6-3. 引き分けの場合の処理
 2-5. ゲーム終了後の最終結果を表示
  2-5-1. 最終得点の表示
  2-5-2. 勝敗の決定

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

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

import kotlin.random.Random

fun main() {
    // ゲームの開始メッセージを表示
    println("ナインゲームを開始します!")

    // プレイヤーとコンピュータの持ち牌を初期化するためのマップを作成
    /*【穴埋め問題1】
    @@@このコメントを消して、プレイヤーとコンピュータの持ち牌を初期化するためのマップを作成するコードを書いてください。@@@
    */
    
    // 各マップに1から9までの数字をキーとして持ち、値をtrueに設定
    for (i in 1..9) {
        playerTiles[i] = true
        computerTiles[i] = true
    }

    // プレイヤーとコンピュータのスコアを初期化
    var playerScore = 0
    var computerScore = 0

    // 9回戦を行うためのループ
    for (round in 1..9) {
        println("\n【第${round}回戦】")
        println("プレイヤーの得点 : ${playerScore}点")
        println("コンピュータの得点: ${computerScore}点")

        // プレイヤーの持ち牌を表示
        print("プレイヤーの持ち牌 ⇒「")
        /*【穴埋め問題2】
        @@@このコメントを消して、プレイヤーの持ち牌を表示するコードを書いてください。@@@
        */
        println("」")
        
        // コンピュータの持ち牌を表示
        print("コンピュータの持ち牌⇒「")
        computerTiles.forEach { (key, value) -> if (value) print("$key ,") else print("- ,") }
        println("」")

        // プレイヤーの打牌を入力
        var playerTile: Int
        while (true) {
            print("持ち牌の中から出す牌を選択してください > ")

            /*【穴埋め問題3】
            @@@このコメントを消して、プレイヤーの打牌を入力し、整数に変換してplayerTileに代入するコードを書いてください。@@@
            if文でその牌が既に使われていないか確認するコードを書いてください。
            */

        }

        // コンピュータの打牌をランダムに選択

        /*【穴埋め問題4】
        @@@このコメントを消して、コンピュータの打牌をランダムに選び、使用済みに設定するコードを書いてください。@@@
        */

        // 結果の表示
        println("プレイヤーの打牌:$playerTile > $computerTile:コンピュータの打牌")
        if (playerTile > computerTile) {
            // プレイヤーが勝った場合の処理
            println("プレイヤーは${playerTile}点獲得")
            playerScore += playerTile
        } else if (computerTile > playerTile) {
            // コンピュータが勝った場合の処理
            println("コンピュータは${computerTile}点獲得")
            computerScore += computerTile
        } else {
            // 引き分けの場合の処理
            println("引き分けです")
        }
    }

    // ゲーム終了後の最終結果を表示
    println("\nゲーム終了!")
    println("最終得点:")
    println("プレイヤーの得点 : ${playerScore}点")
    println("コンピュータの得点: ${computerScore}点")
    
    // 最終結果の判定
    if (playerScore > computerScore) {
        println("プレイヤーの勝利です!")
    } else if (computerScore > playerScore) {
        println("コンピュータの勝利です!")
    } else {
        println("引き分けです!")
    }
}

 

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

解答例

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

正解コードの例

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

********************

import kotlin.random.Random

fun main() {
    // ゲームの開始メッセージを表示
    println("ナインゲームを開始します!")

    // プレイヤーとコンピュータの持ち牌を初期化するためのマップを作成
    val playerTiles = mutableMapOf<Int, Boolean>()
    val computerTiles = mutableMapOf<Int, Boolean>()
    
    // 各マップに1から9までの数字をキーとして持ち、値をtrueに設定
    for (i in 1..9) {
        playerTiles[i] = true
        computerTiles[i] = true
    }

    // プレイヤーとコンピュータのスコアを初期化
    var playerScore = 0
    var computerScore = 0

    // 9回戦を行うためのループ
    for (round in 1..9) {
        println("\n【第${round}回戦】")
        println("プレイヤーの得点 : ${playerScore}点")
        println("コンピュータの得点: ${computerScore}点")

        // プレイヤーの持ち牌を表示
        print("プレイヤーの持ち牌 ⇒「")
        playerTiles.forEach { (key, value) -> if (value) print("$key ,") else print("- ,") }
        println("」")
        
        // コンピュータの持ち牌を表示
        print("コンピュータの持ち牌⇒「")
        computerTiles.forEach { (key, value) -> if (value) print("$key ,") else print("- ,") }
        println("」")

        // プレイヤーの打牌を入力
        var playerTile: Int
        while (true) {
            print("持ち牌の中から出す牌を選択してください > ")
            playerTile = readLine()!!.toInt() // 入力を整数に変換
            if (playerTiles[playerTile] == true) {
                playerTiles[playerTile] = false // 使用済みに設定
                break
            } else {
                println("その牌は既に使われています。別の牌を選んでください。")
            }
        }

        // コンピュータの打牌をランダムに選択
        val computerTile = computerTiles.filter { it.value }.keys.random()
        computerTiles[computerTile] = false

        // 結果の表示
        println("プレイヤーの打牌:$playerTile > $computerTile:コンピュータの打牌")
        if (playerTile > computerTile) {
            // プレイヤーが勝った場合の処理
            println("プレイヤーは${playerTile}点獲得")
            playerScore += playerTile
        } else if (computerTile > playerTile) {
            // コンピュータが勝った場合の処理
            println("コンピュータは${computerTile}点獲得")
            computerScore += computerTile
        } else {
            // 引き分けの場合の処理
            println("引き分けです")
        }
    }

    // ゲーム終了後の最終結果を表示
    println("\nゲーム終了!")
    println("最終得点:")
    println("プレイヤーの得点 : ${playerScore}点")
    println("コンピュータの得点: ${computerScore}点")
    
    // 最終結果の判定
    if (playerScore > computerScore) {
        println("プレイヤーの勝利です!")
    } else if (computerScore > playerScore) {
        println("コンピュータの勝利です!")
    } else {
        println("引き分けです!")
    }
}

********************

コードの解説

ナインゲームのKotlinコードの各部分を初心者向けに説明します。コードがどのように動作するのかを理解し、Kotlinプログラミングの基礎を学びましょう。

ランダム関数のインポート

import kotlin.random.Random

最初に、Kotlin標準ライブラリからRandomクラスをインポートします。これを使ってランダムな数値を生成します。

メイン関数の開始

fun main() {
    println("ナインゲームを開始します!")

main関数はプログラムのエントリーポイントです。ここでは、最初にゲームの開始メッセージを表示します。

持ち牌の初期化

    val playerTiles = mutableMapOf<Int, Boolean>()
    val computerTiles = mutableMapOf<Int, Boolean>()
    for (i in 1..9) {
        playerTiles[i] = true
        computerTiles[i] = true
    }

プレイヤーとコンピュータの持ち牌を初期化します。それぞれの牌をキーとして、使用可能かどうかを示すBoolean値を持つマップを作成します。

スコアの初期化

    var playerScore = 0
    var computerScore = 0

プレイヤーとコンピュータの得点を0に設定します。

ゲームの各ラウンドを処理

    for (round in 1..9) {
        println("\n【第${round}回戦】")
        println("プレイヤーの得点 : ${playerScore}点")
        println("コンピュータの得点: ${computerScore}点")

ゲームは9ラウンド行われ、各ラウンドの開始時に現在のラウンド数と得点を表示します。

プレイヤーとコンピュータの持ち牌を表示

        print("プレイヤーの持ち牌 ⇒「")
        playerTiles.forEach { (key, value) -> if (value) print("$key ,") else print("- ,") }
        println("」")
        print("コンピュータの持ち牌⇒「")
        computerTiles.forEach { (key, value) -> if (value) print("$key ,") else print("- ,") }
        println("」")

プレイヤーとコンピュータの持ち牌をそれぞれ表示します。使用済みの牌は-で示されます。

プレイヤーの打牌を入力

        var playerTile: Int
        while (true) {
            print("持ち牌の中から出す牌を選択してください > ")
            playerTile = readLine()!!.toInt()
            if (playerTiles[playerTile] == true) {
                playerTiles[playerTile] = false
                break
            } else {
                println("その牌は既に使われています。別の牌を選んでください。")
            }
        }

プレイヤーは使用可能な牌の中から1つ選びます。既に使われた牌を選ぶと再入力を求められます。

コンピュータの打牌を決定

        val computerTile = computerTiles.filter { it.value }.keys.random()
        computerTiles[computerTile] = false

コンピュータは使用可能な牌の中からランダムに1つ選びます。

ラウンド結果を表示しスコアを更新

        println("プレイヤーの打牌:$playerTile > $computerTile:コンピュータの打牌")
        if (playerTile > computerTile) {
            println("プレイヤーは${playerTile}点獲得")
            playerScore += playerTile
        } else if (computerTile > playerTile) {
            println("コンピュータは${computerTile}点獲得")
            computerScore += computerTile
        } else {
            println("引き分けです")
        }
    }

プレイヤーとコンピュータの打牌を比較し、勝者に得点を加算します。同点の場合は引き分けと表示されます。

ゲーム終了後の結果を表示

    println("\nゲーム終了!")
    println("最終得点:")
    println("プレイヤーの得点 : ${playerScore}点")
    println("コンピュータの得点: ${computerScore}点")
    if (playerScore > computerScore) {
        println("プレイヤーの勝利です!")
    } else if (computerScore > playerScore) {
        println("コンピュータの勝利です!")
    } else {
        println("引き分けです!")
    }
}

全ラウンド終了後に最終得点を表示し、最終的な勝敗を決定します。

<<前の問題 問題集Top 次の問題>>

この問題への質問・コメント

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

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






    Kotlin練習問題集へ戻る
    トップページへ戻る