Go 言語で「基礎プログラミング演習 I 〜100 本ノック上級編」を解いてみる-No.85「石取りゲーム」

はじめに

「基礎プログラミング演習 I 〜100 本ノック上級編」を解いてみます。

取り扱う問題は以下のサイトを引用させていただきました。

検証環境

$ uname -moi
x86_64 unknown GNU/Linux

$ head -n 2 /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"

$ go version | head -n 1
go version go1.16.3 linux/amd64

問題

No. 85 石取りゲーム

最初に石の個数を入力し(10 個以上とする)、二人のプレイヤーが交互に 1〜3 個ずつ石を取り、最後の 1 個を取った方が負けとなるゲームがある。このゲームプログラムを作成せよ。具体的には実行例を参照のこと。

# 【実行例、下線部は入力例】
$ ./knock85
石の数を入力してください(10以上): 15
石の数: 15
プレイヤー1の番です
何個取る(1〜3個)? 3
石の数: 12
プレイヤー2の番です
何個取る(1〜3個)? 2
石の数: 10
プレイヤー1の番です
何個取る(1〜3個)? 4
プレイヤー1の番です
何個取る(1〜3個)? 3
石の数: 7
プレイヤー2の番です
何個取る(1〜3個)? 3
石の数: 4
プレイヤー1の番です
何個取る(1〜3個)? 2
石の数: 2
プレイヤー2の番です
何個取る(1〜3個)? 1
石の数: 1
プレイヤー2の勝ち
$ ./knock85
石の数を入力してください(10以上): 10
石の数: 10
プレイヤー1の番です
何個取る(1〜3個)? 3
石の数: 7
プレイヤー2の番です
何個取る(1〜3個)? 2
石の数: 5
プレイヤー1の番です
何個取る(1〜3個)? 3
石の数: 2
プレイヤー2の番です
何個取る(1〜3個)? 3
石の数: -1
プレイヤー2の反則負け

回答

knock85.go

package main

import (
    "fmt"
)

func main() {
    stones := 0
    for stones < 10 {
        fmt.Print("石の数を入力してください。(10以上) : ")
        fmt.Scan(&stones)
    }

    fmt.Printf("石の数: %d\n", stones)

playing:
    for true {
        for i := 0; i < 2; i++ {
            takedStones := 0
            for !(1 <= takedStones && takedStones <= 3) {
                fmt.Printf("プレイヤー%dの番です\n", (i + 1))
                fmt.Print("何個取る(1〜3個) ? ")
                fmt.Scan(&takedStones)
            }

            stones -= takedStones
            fmt.Printf("石の数: %d\n", stones)
            switch stones {
            case -2:
                fallthrough
            case -1:
                fmt.Printf("プレイヤー%dの反則負け\n", (i + 1))
                break playing
            case 0:
                fmt.Printf("プレイヤー%dの負け\n", (i + 1))
                break playing
            case 1:
                fmt.Printf("プレイヤー%dの勝ち\n", (i + 1))
                break playing
            }
        }
    }
}

実行

$ go run knock85.go

ひとこと

プレイヤーが間違って全部とってしまったケースの出力例が無いため、仕様を想像し実装しました。

Posted by genzouw