Go 言語で「基礎プログラミング演習 I 〜100 本ノック上級編」を解いてみる-No.83「じゃんけん 5 回勝負」

はじめに

「基礎プログラミング演習 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. 83 じゃんけん 5 回勝負

次の仕様のじゃんけんプログラムを作成せよ。
・人間は、グー、チョキ、パーをそれぞれ 0、1、2 の数字で入力する。
・コンピュータは乱数を使って出す手を選ぶ。乱数の使い方は演習資料の高度なテクニック集を見よ。
・5 回勝負として、人間とコンピュータの勝った回数を数え、勝敗がつくたびに 1 回ずつ表示する。あいこは決着がつくまで再勝負。途中でどちらかが 3 勝しても、5 回最後まで勝負を続ける。
・指定された範囲以外の値を入力したら負けにする

# 【実行例。下線部は入力値の例。メッセージはこの通りでなくてよい。】
$ ./knock83
あなたの手を選んでください(グー0、チョキ1、パー2): 0
コンピュータはチョキ
あなたの勝ち
あなた1勝、わたし0勝
あなたの手を選んでください(グー0、チョキ1、パー2): 2
コンピュータはパー
あいこ
あなたの手を選んでください(グー0、チョキ1、パー2): 2
コンピュータはチョキ
わたしの勝ち
あなた1勝、わたし1勝
あなたの手を選んでください(グー0、チョキ1、パー2): 3
そんな手はありません。あなたの負け
あなた1勝、わたし2勝
(中略)
あなた3勝、わたし2勝
あなたの総合勝利です。参りました。

回答

knock83.go

package main

import (
    "fmt"
    "math/rand"
    "strconv"
    "time"
)

func main() {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))

    choices := map[int]string{
        0: "グー",
        1: "チョキ",
        2: "パー",
    }

    wins := 0
    for i := 0; i < 5; i++ {
        isSettled := false
        for !isSettled {
            var choice int

            fmt.Print("あなたの手を選んでください(グー0、チョキ1、パー2): ")
            fmt.Scan(&choice)
            if choices[choice] == "" {
                fmt.Println("そんな手はありません。あなたの負け")
                break
            }

            computerChoice := r.Intn(3)
            fmt.Println("コンピュータは" + choices[computerChoice])

            switch computerChoice - choice {
            case 1, -2:
                fmt.Println("あなたの勝ち")
                wins++
                isSettled = true
            case 0:
                fmt.Println("あいこ")
            default:
                fmt.Println("コンピュータの勝ち")
                isSettled = true
            }
        }
        fmt.Println("あなた" + strconv.Itoa(wins) + "勝、コンピュータ" + strconv.Itoa(i+1-wins) + "勝")
    }

    if wins*2 > 5 {
        fmt.Println("あなたの総合勝利です。参りました。")
    }
}

実行

$ go run knock83.go

ひとこと

ロジックが汚い。マジックナンバー残ったまま。

Posted by genzouw