シェルスクリプト:ピッグ(Pig)ダイスゲーム

 シェルスクリプトは、システム管理だけでなく、テキストベースのゲーム作成にも活用できる強力なツールです。ここでは、シェルスクリプトを使って「ピッグ(Pig)ダイスゲーム」を作成し、その手順と詳細な解説を行います。このゲームは、サイコロを使った2人用のシンプルなゲームで、100点を先取したプレイヤーが勝利します。この演習を通じて、シェルスクリプトの基本的な構文、条件分岐、ループ、ランダム数の生成、ユーザー入力の処理などの知識を総合的に学ぶことができます。

ゲームの概要

ゲームの目的

  • サイコロを振ってポイントを獲得し、先に100点に到達することを目指します。

ゲームのルール

  1. ゲームの進行
    ・プレイヤーとコンピュータは交互にターンを行います。
    ・各ターンで、プレイヤーは何度でもサイコロを振ることができます。
    ・サイコロを振るたびに、その出目(1〜6)が一時的なポイントに加算されます。
    ・プレイヤーは好きなタイミングで「ホールド」を宣言して、そのターンの一時的なポイントを総得点に加算できます。
  2. リスクと報酬
    出目が1の場合:そのターンで獲得した一時的なポイントはすべて失われ、ターンが相手に移ります。
    出目が2〜6の場合:一時的なポイントに加算され、プレイヤーは続けてサイコロを振るか、ホールドするかを選択できます。
  3. 勝利条件
    ・先に総得点が100点以上になったプレイヤーが勝利します。

pig_game.shの作成から実行までの手順と解説

ステップ1:スクリプトファイルの作成

ターミナルで以下のコマンドを実行し、新しいスクリプトファイル pig_game.sh を作成します。

user01@ubuntu:~$ nano pig_game.sh

ステップ2:スクリプトの内容を記述

エディタが開いたら、以下のコードをコピーして貼り付けます。

#!/bin/bash

# プレイヤーとコンピュータの得点
player_score=0
computer_score=0

# ターゲットスコア
target_score=100

# ゲーム開始のメッセージ
echo "=== ピッグ(Pig)ダイスゲームへようこそ! ==="
echo "先に$target_score 点に到達した方が勝ちです。"

# プレイヤーのターン関数
player_turn() {
    turn_total=0
    while true; do
        read -p "サイコロを振りますか?(y/n): " choice
        choice=${choice,,}  # 小文字に変換
        if [ "$choice" == "y" ]; then
            roll=$((RANDOM % 6 + 1))
            echo "サイコロの出目:$roll"
            if [ "$roll" -eq 1 ]; then
                echo "出目が1です!このターンのポイントは0になります。"
                turn_total=0
                break
            else
                turn_total=$((turn_total + roll))
                echo "このターンのポイント:$turn_total"
                if [ $((player_score + turn_total)) -ge $target_score ]; then
                    player_score=$((player_score + turn_total))
                    return
                fi
            fi
        elif [ "$choice" == "n" ]; then
            player_score=$((player_score + turn_total))
            echo "現在のあなたの得点:$player_score"
            break
        else
            echo "無効な入力です。'y' か 'n' を入力してください。"
        fi
    done
}

# コンピュータのターン関数
computer_turn() {
    echo "コンピュータのターンです。"
    turn_total=0
    while true; do
        roll=$((RANDOM % 6 + 1))
        echo "コンピュータがサイコロを振りました:$roll"
        if [ "$roll" -eq 1 ]; then
            echo "コンピュータの出目が1です!このターンのポイントは0になります。"
            turn_total=0
            break
        else
            turn_total=$((turn_total + roll))
            # コンピュータの戦略:ターンポイントが20以上ならホールド
            if [ $turn_total -ge 20 ] || [ $((computer_score + turn_total)) -ge $target_score ]; then
                computer_score=$((computer_score + turn_total))
                echo "コンピュータはホールドしました。現在のコンピュータの得点:$computer_score"
                break
            fi
        fi
        sleep 1
    done
}

# ゲームループ
while true; do
    echo
    echo "--- あなたのターン ---"
    echo "あなたの得点:$player_score, コンピュータの得点:$computer_score"
    player_turn
    if [ "$player_score" -ge "$target_score" ]; then
        echo "おめでとうございます!あなたの勝ちです!"
        exit
    fi

    echo
    echo "--- コンピュータのターン ---"
    echo "あなたの得点:$player_score, コンピュータの得点:$computer_score"
    computer_turn
    if [ "$computer_score" -ge "$target_score" ]; then
        echo "残念!コンピュータの勝ちです。"
        exit
    fi
done

ステップ3:スクリプトの内容の解説

1.シェバン行

#!/bin/bash
  • スクリプトが Bash シェルで実行されることを指定します。

2.変数の初期化

# プレイヤーとコンピュータの得点
player_score=0
computer_score=0

# ターゲットスコア
target_score=100
  • 目的:プレイヤーとコンピュータの得点、および勝利条件となるターゲットスコアを初期化します。

3.ゲーム開始のメッセージ

echo "=== ピッグ(Pig)ダイスゲームへようこそ! ==="
echo "先に$target_score 点に到達した方が勝ちです。"
  • ゲームの開始を告げ、ルールの概要を説明します。

4.プレイヤーのターン関数 player_turn

player_turn() {
    turn_total=0
    while true; do
        read -p "サイコロを振りますか?(y/n): " choice
        choice=${choice,,}  # 小文字に変換
        if [ "$choice" == "y" ]; then
            roll=$((RANDOM % 6 + 1))
            echo "サイコロの出目:$roll"
            if [ "$roll" -eq 1 ]; then
                echo "出目が1です!このターンのポイントは0になります。"
                turn_total=0
                break
            else
                turn_total=$((turn_total + roll))
                echo "このターンのポイント:$turn_total"
                if [ $((player_score + turn_total)) -ge $target_score ]; then
                    player_score=$((player_score + turn_total))
                    return
                fi
            fi
        elif [ "$choice" == "n" ]; then
            player_score=$((player_score + turn_total))
            echo "現在のあなたの得点:$player_score"
            break
        else
            echo "無効な入力です。'y' か 'n' を入力してください。"
        fi
    done
}
  • 目的:プレイヤーがサイコロを振るかホールドするかを選択し、その結果を処理します。
  • 解説
    turn_total:そのターンでの一時的な得点を保持します。
    read -p:ユーザーからの入力を取得します。
    choice=${choice,,}:入力を小文字に変換し、大文字・小文字の入力に対応します。
    ・サイコロの出目が1の場合、ターンポイントは0になり、ターンが終了します。
    ・サイコロの出目が2〜6の場合、ターンポイントに加算されます。

5.コンピュータのターン関数 computer_turn

computer_turn() {
    echo "コンピュータのターンです。"
    turn_total=0
    while true; do
        roll=$((RANDOM % 6 + 1))
        echo "コンピュータがサイコロを振りました:$roll"
        if [ "$roll" -eq 1 ]; then
            echo "コンピュータの出目が1です!このターンのポイントは0になります。"
            turn_total=0
            break
        else
            turn_total=$((turn_total + roll))
            # コンピュータの戦略:ターンポイントが20以上ならホールド
            if [ $turn_total -ge 20 ] || [ $((computer_score + turn_total)) -ge $target_score ]; then
                computer_score=$((computer_score + turn_total))
                echo "コンピュータはホールドしました。現在のコンピュータの得点:$computer_score"
                break
            fi
        fi
        sleep 1
    done
}
  • 目的:コンピュータがサイコロを振る動作を自動的に行います。
  • 解説
    ・コンピュータの戦略として、ターンポイントが20以上になるか、総得点がターゲットスコアに達しそうな場合にホールドします。
    sleep 1:1秒待機して、人間らしい間を作ります。

6.ゲームループ

while true; do
    echo
    echo "--- あなたのターン ---"
    echo "あなたの得点:$player_score, コンピュータの得点:$computer_score"
    player_turn
    if [ "$player_score" -ge "$target_score" ]; then
        echo "おめでとうございます!あなたの勝ちです!"
        exit
    fi

    echo
    echo "--- コンピュータのターン ---"
    echo "あなたの得点:$player_score, コンピュータの得点:$computer_score"
    computer_turn
    if [ "$computer_score" -ge "$target_score" ]; then
        echo "残念!コンピュータの勝ちです。"
        exit
    fi
done

解説

  • プレイヤーとコンピュータのターンを交互に実行します。
  • 各ターンの後に、得点がターゲットスコアに達しているかをチェックします。
  • ゲームが終了するまでループを続けます。

ステップ4:スクリプトに実行権限を付与

スクリプトを保存してエディタを終了したら、実行権限を付与します。

user01@ubuntu:~$ chmod +x pig_game.sh

ステップ5:スクリプトの実行

スクリプトを実行して、ピッグダイスゲームを開始します。

user01@ubuntu:~$ ./pig_game.sh

実行例

=== ピッグ(Pig)ダイスゲームへようこそ! ===
先に100 点に到達した方が勝ちです。

--- あなたのターン ---
あなたの得点:0, コンピュータの得点:0
サイコロを振りますか?(y/n): y
サイコロの出目:4
このターンのポイント:4
サイコロを振りますか?(y/n): y
サイコロの出目:5
このターンのポイント:9
サイコロを振りますか?(y/n): y
サイコロの出目:1
出目が1です!このターンのポイントは0になります。

--- コンピュータのターン ---
あなたの得点:0, コンピュータの得点:0
コンピュータがサイコロを振りました:6
コンピュータがサイコロを振りました:3
コンピュータがサイコロを振りました:2
コンピュータがサイコロを振りました:1
コンピュータの出目が1です!このターンのポイントは0になります。

(以下続く)

解説

  • プレイヤーはサイコロを振るかホールドするかを選択します。
  • コンピュータは自動的にサイコロを振ります。
  • お互いに得点を積み重ね、先に100点に到達した方が勝ちです。

ここで作成したファイルの削除

ゲームのテストが終了したら、作成した pig_game.sh ファイルを削除します。

user01@ubuntu:~$ rm pig_game.sh

まとめ

  • シェルスクリプトの応用:ピッグダイスゲームを通じて、シェルスクリプトでのゲーム作成方法を学びました。
  • 変数と演算:得点やターンポイントを変数で管理し、算術演算を行いました。
  • ランダム性の導入$RANDOM 変数を使用して、サイコロの出目をランダムに生成しました。
  • 条件分岐とループif 文や while ループを使って、ゲームのロジックを制御しました。
  • ユーザー入力の処理read コマンドを使用してユーザーの入力を受け取り、入力をバリデーションしました。
  • 関数の活用player_turncomputer_turn のように、関連する処理を関数としてまとめ、コードの再利用性と可読性を向上させました。

 シェルスクリプトは、システム管理以外にも多くの用途で活用できます。今回のピッグダイスゲームを基に、コンピュータの戦略を高度化したり、マルチプレイヤーモードを追加したり、サイコロの数を増やしたりして、さらなる機能拡張に挑戦してみてください。