シェルスクリプト:ワードルゲーム

 シェルスクリプトは、システム管理やタスクの自動化だけでなく、ゲームやツールの作成にも活用できます。ここでは、シェルスクリプトを使って「ワードルゲーム」を作成し、その手順と詳細な解説を行います。この演習を通じて、シェルスクリプトの基本的な構文、配列操作、ループ、条件分岐、文字列操作などを学ぶことができます。

ワードルゲームの概要

  • 目的:5文字の英単語を6回以内に推測して当てるゲームです。
  • ルール
    ・コンピューターがランダムに5文字の英単語を選択します。
    ・ユーザーは5文字の英単語を入力して推測します。
    ・各試行ごとに、以下のフィードバックが与えられます。
     ・Correct(正解):文字と位置の両方が正しい。
     ・Present(存在):文字は単語に含まれているが、位置が違う。
     ・Absent(不正解):文字が単語に含まれていない。

フィードバックの例

位置12345
正解の単語WORDS
ユーザーの推測WORLD
フィードバックCorrectCorrectCorrectAbsentPresent

解説

  • 1〜3文字目:文字と位置が正しいため「Correct」。
  • 4文字目L は正解の単語に含まれていないため「Absent」。
  • 5文字目D は単語に含まれているが位置が違うため「Present」。

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

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

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

user01@ubuntu:~$ nano wordle.sh

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

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

#!/bin/bash

# 5文字の英単語リストを定義
words=("apple" "grape" "brain" "chair" "table" "plant" "house" "light" "water" "sound")

# ランダムに単語を選択
secret=${words[$RANDOM % ${#words[@]}]}

max_attempts=6
attempt=0

echo "ワードルゲームへようこそ!5文字の英単語を当ててください。"

# メインゲームループ
while [ $attempt -lt $max_attempts ]; do
    attempt=$((attempt + 1))
    while true; do
        read -p "推測を入力してください($attempt/$max_attempts): " guess
        # 入力のバリデーション
        if [[ ! "$guess" =~ ^[a-zA-Z]{5}$ ]]; then
            echo "エラー: 5文字の英単語を入力してください。"
            continue
        fi
        guess=$(echo "$guess" | tr '[:upper:]' '[:lower:]')  # 小文字に変換
        break
    done

    if [ "$guess" == "$secret" ]; then
        echo "おめでとうございます!正解を当てました。"
        break
    else
        feedback=()
        for ((i=0; i<5; i++)); do
            guess_char=${guess:$i:1}
            secret_char=${secret:$i:1}
            if [ "$guess_char" == "$secret_char" ]; then
                feedback+=("[$guess_char: Correct]")
            elif [[ "$secret" == *"$guess_char"* ]]; then
                feedback+=("[$guess_char: Present]")
            else
                feedback+=("[$guess_char: Absent]")
            fi
        done
        echo "フィードバック: ${feedback[@]}"
    fi
done

if [ "$guess" != "$secret" ]; then
    echo "ゲームオーバー。正解は '$secret' でした。"
fi

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

1.シェバン行

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

2.単語リストの定義

words=("apple" "grape" "brain" "chair" "table" "plant" "house" "light" "water" "sound")

目的:ゲームで使用する5文字の英単語を配列 words に格納します。

3.ランダムに単語を選択

secret=${words[$RANDOM % ${#words[@]}]}

解説

  • ${#words[@]} は配列 words の要素数を取得します。
  • $RANDOM は0から32767の乱数を生成します。
  • % 演算子を使って、配列のインデックス範囲内のランダムな値を取得します。
  • そのインデックスの単語を secret に格納します。

4.変数の初期化

max_attempts=6
attempt=0

echo "ワードルゲームへようこそ!5文字の英単語を当ててください。"

解説

  • max_attempts:ユーザーが推測できる最大回数を6回に設定します。
  • attempt:現在の試行回数を0に初期化します。
  • ゲーム開始のメッセージを表示します。

5.メインゲームループ

while [ $attempt -lt $max_attempts ]; do
    attempt=$((attempt + 1))
    while true; do
        read -p "推測を入力してください($attempt/$max_attempts): " guess
        # 入力のバリデーション
        if [[ ! "$guess" =~ ^[a-zA-Z]{5}$ ]]; then
            echo "エラー: 5文字の英単語を入力してください。"
            continue
        fi
        guess=$(echo "$guess" | tr '[:upper:]' '[:lower:]')  # 小文字に変換
        break
    done

    if [ "$guess" == "$secret" ]; then
        echo "おめでとうございます!正解を当てました。"
        break
    else
        feedback=()
        for ((i=0; i<5; i++)); do
            guess_char=${guess:$i:1}
            secret_char=${secret:$i:1}
            if [ "$guess_char" == "$secret_char" ]; then
                feedback+=("[$guess_char: Correct]")
            elif [[ "$secret" == *"$guess_char"* ]]; then
                feedback+=("[$guess_char: Present]")
            else
                feedback+=("[$guess_char: Absent]")
            fi
        done
        echo "フィードバック: ${feedback[@]}"
    fi
done

解説

  • 試行回数の更新attempt を1増やします。
  • ユーザー入力のバリデーション
    ・正規表現 ^[a-zA-Z]{5}$ を使用して、5文字のアルファベットであることを確認します。
    ・入力を小文字に変換して統一します。
  • 正解の判定
    ・ユーザーの推測が secret と一致すれば、勝利メッセージを表示してループを終了します。
  • フィードバックの生成
    ・ループで各文字を比較します。
     ・Correct:文字と位置が一致する場合。
     ・Present:文字は含まれているが位置が違う場合。
     ・Absent:文字が含まれていない場合。
    ・フィードバックを配列 feedback に格納し、ユーザーに表示します。

6.ゲームオーバーの判定

if [ "$guess" != "$secret" ]; then
    echo "ゲームオーバー。正解は '$secret' でした。"
fi

解説

最大試行回数に達しても正解を当てられなかった場合、ゲームオーバーとして正解の単語を表示します。

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

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

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

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

スクリプトを実行して、ワードルゲームを開始します。

user01@ubuntu:~$ ./wordle.sh

実行例

ワードルゲームへようこそ!5文字の英単語を当ててください。
推測を入力してください(1/6): apple
フィードバック: [a: Present] [p: Absent] [p: Absent] [l: Absent] [e: Correct]
推測を入力してください(2/6): grape
フィードバック: [g: Absent] [r: Absent] [a: Present] [p: Absent] [e: Correct]
推測を入力してください(3/6): table
フィードバック: [t: Absent] [a: Present] [b: Absent] [l: Absent] [e: Correct]
推測を入力してください(4/6): plane
フィードバック: [p: Absent] [l: Absent] [a: Present] [n: Absent] [e: Correct]
推測を入力してください(5/6): trace
フィードバック: [t: Absent] [r: Absent] [a: Present] [c: Absent] [e: Correct]
推測を入力してください(6/6): brace
フィードバック: [b: Absent] [r: Absent] [a: Present] [c: Absent] [e: Correct]
ゲームオーバー。正解は 'house' でした。

解説

  • ユーザーの推測:ユーザーは5文字の英単語を入力します。
  • フィードバック:各文字に対して以下のフィードバックが与えられます。
    [文字: Correct]:文字と位置が正しい。
    [文字: Present]:文字は含まれているが位置が違う。
    [文字: Absent]:文字が含まれていない。
  • ゲームの終了:6回以内に正解を当てられなかった場合、ゲームオーバーとなり正解の単語が表示されます。

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

演習が終了したら、作成した wordle.sh ファイルを削除します。

user01@ubuntu:~$ rm wordle.sh

まとめ

  • シェルスクリプトの活用:シェルスクリプトを使って、ワードルゲームを作成しました。これにより、シェルスクリプトの基本的な構文や制御構造を学ぶことができます。
  • 配列の利用:単語リストやフィードバックを配列で管理し、効率的にデータを扱いました。
  • 文字列操作:部分文字列の取得や文字列の比較を行い、ユーザーの入力を適切に処理しました。
  • 入力のバリデーション:正規表現を使って、ユーザーからの入力が正しい形式であるかを確認しました。
  • 条件分岐とループif 文や while ループを使って、ゲームの進行や終了条件を制御しました。

 シェルスクリプトを活用することで、さまざまなツールやゲームを簡単に作成することができます。今回のワードルゲームを基に、単語リストを増やしたり、難易度を調整したりして、自分なりのゲームを作ってみてください。