このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

Linuxコマンドの基本:シェルスクリプト:ハングマンゲーム

シェルスクリプト:ハングマンゲーム

 シェルスクリプトは、システム管理やタスクの自動化だけでなく、簡単なゲームやツールの作成にも活用できます。ここでは、シェルスクリプトを使って「ハングマンゲーム」を作成し、その作成から実行までの手順と詳細な解説を行います。このゲームを通じて、シェルスクリプトの基本的な構文、配列、関数、ループ、条件分岐などの知識を総合的に学ぶことができます。

ハングマンゲームの概要

  • 目的:隠された単語の文字を一文字ずつ推測し、制限回数内に全ての文字を当てるゲーム。
  • ルール
    ・コンピューターがランダムに選んだ単語の文字数のみが表示されます(例:_ _ _ _ _)。
    ・ユーザーはアルファベット一文字を入力して、単語にその文字が含まれているかを確認します。
    ・間違えられる回数(試行回数)は6回までです。
    ・全ての文字を当てると勝利、試行回数が0になると敗北となります。

スクリプトの作成から実行までの手順と解説

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

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

user01@ubuntu:~$ nano hangman.sh

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

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

#!/bin/bash

# 単語のリストを配列で定義
words=("linux" "computer" "script" "terminal" "network" "variable" "function" "process" "command" "software")

# ランダムに単語を選択
word=${words[$RANDOM % ${#words[@]}]}
word_length=${#word}
guessed_letters=()
attempts_left=6  # 残りの試行回数

# 単語の文字をアンダースコアで表示
display_word() {
    display=""
    for (( i=0; i<$word_length; i++ )); do
        letter=${word:$i:1}
        if [[ " ${guessed_letters[@]} " =~ " $letter " ]]; then
            display+="$letter "
        else
            display+="_ "
        fi
    done
    echo "$display"
}

echo "ハングマンゲームへようこそ!"
echo "単語を推測してください。残り試行回数: $attempts_left"
display_word

# ゲームループ
while [[ $attempts_left -gt 0 ]]; do
    read -p "文字を入力してください: " guess

    # 入力のバリデーション
    if [[ ! "$guess" =~ ^[a-zA-Z]$ ]]; then
        echo "エラー: アルファベット一文字を入力してください。"
        continue
    fi

    guess=$(echo "$guess" | tr '[:upper:]' '[:lower:]')  # 小文字に変換

    if [[ " ${guessed_letters[@]} " =~ " $guess " ]]; then
        echo "既に推測した文字です。別の文字を入力してください。"
        continue
    fi

    guessed_letters+=("$guess")

    if [[ "$word" == *"$guess"* ]]; then
        echo "正解!"
    else
        attempts_left=$((attempts_left - 1))
        echo "不正解。残り試行回数: $attempts_left"
    fi

    display_word

    # 全ての文字を当てたか確認
    if [[ ! "$(display_word)" =~ "_" ]]; then
        echo "おめでとうございます!単語を当てました。"
        break
    fi
done

if [[ $attempts_left -eq 0 ]]; then
    echo "ゲームオーバー。正解の単語は '$word' でした。"
fi

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

1.シェバン行

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

2.単語のリストを配列で定義

words=("linux" "computer" "script" "terminal" "network" "variable" "function" "process" "command" "software")
  • ゲームで使用する単語を words 配列に格納します。

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

word=${words[$RANDOM % ${#words[@]}]}
word_length=${#word}
guessed_letters=()
attempts_left=6  # 残りの試行回数
  • ${#words[@]} で配列の要素数を取得。
  • $RANDOM を使用して、配列からランダムに単語を選択。
  • word_length は選択した単語の文字数を格納。
  • guessed_letters はユーザーが推測した文字を格納する配列。
  • attempts_left はユーザーが間違えられる残りの回数。

4.単語の文字をアンダースコアで表示する関数

display_word() {
    display=""
    for (( i=0; i<$word_length; i++ )); do
        letter=${word:$i:1}
        if [[ " ${guessed_letters[@]} " =~ " $letter " ]]; then
            display+="$letter "
        else
            display+="_ "
        fi
    done
    echo "$display"
}
  • この関数は、現在の単語の状態を表示します。
  • 推測された文字はそのまま表示し、未推測の文字は _ で表示します。

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

echo "ハングマンゲームへようこそ!"
echo "単語を推測してください。残り試行回数: $attempts_left"
display_word
  • ゲームの開始をユーザーに知らせ、現在の単語の状態を表示します。

6.ゲームループの開始

while [[ $attempts_left -gt 0 ]]; do
    # ゲームの処理
done
  • 残りの試行回数が0になるまでゲームを続けます。

7.ユーザーからの入力とバリデーション

read -p "文字を入力してください: " guess

# 入力のバリデーション
if [[ ! "$guess" =~ ^[a-zA-Z]$ ]]; then
    echo "エラー: アルファベット一文字を入力してください。"
    continue
fi

guess=$(echo "$guess" | tr '[:upper:]' '[:lower:]')  # 小文字に変換
  • ユーザーにアルファベット一文字を入力してもらいます。
  • 入力がアルファベット一文字かを正規表現でチェックします。
  • 入力を小文字に変換して統一します。

8.既に推測した文字の確認

if [[ " ${guessed_letters[@]} " =~ " $guess " ]]; then
    echo "既に推測した文字です。別の文字を入力してください。"
    continue
fi
  • ユーザーが既に推測した文字を再度入力していないか確認します。

9.推測した文字の保存

guessed_letters+=("$guess")
  • 推測した文字を guessed_letters 配列に追加します。

10.推測の結果と試行回数の更新

if [[ "$word" == *"$guess"* ]]; then
    echo "正解!"
else
    attempts_left=$((attempts_left - 1))
    echo "不正解。残り試行回数: $attempts_left"
fi
  • 推測した文字が単語に含まれているかを確認します。
  • 不正解の場合、残りの試行回数を1減らします。

11.現在の単語の状態を表示

display_word
  • 現在の単語の状態を再度表示します。

12.全ての文字を当てたか確認

if [[ ! "$(display_word)" =~ "_" ]]; then
    echo "おめでとうございます!単語を当てました。"
    break
fi
  • 単語の表示にアンダースコアが含まれていない場合、全ての文字を当てたと判断します。

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

if [[ $attempts_left -eq 0 ]]; then
    echo "ゲームオーバー。正解の単語は '$word' でした。"
fi
  • 残りの試行回数が0になった場合、ゲームオーバーとして正解の単語を表示します。

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

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

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

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

スクリプトを実行して、ハングマンゲームを開始します。

user01@ubuntu:~$ ./hangman.sh

実行例

ハングマンゲームへようこそ!
単語を推測してください。残り試行回数: 6
_ _ _ _ _ _ _ _ 
文字を入力してください: a
正解!
_ _ _ _ _ _ a _ 
文字を入力してください: t
正解!
t _ _ _ _ _ a _ 
文字を入力してください: e
正解!
t e _ _ _ _ a _ 
文字を入力してください: r
正解!
t e r _ _ _ a _ 
文字を入力してください: n
正解!
t e r _ _ n a _ 
文字を入力してください: m
正解!
t e r m _ n a _ 
文字を入力してください: l
正解!
t e r m _ n a l 
文字を入力してください: i
正解!
t e r m i n a l 
おめでとうございます!単語を当てました。

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

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

user01@ubuntu:~$ rm hangman.sh

まとめ

  • シェルスクリプトの活用:シェルスクリプトを使ってハングマンゲームを作成し、基本的な構文や制御構造を学びました。
  • 配列の利用:単語リストや推測した文字を配列で管理し、効率的なデータ操作を実現しました。
  • 関数の定義:単語の表示を行う関数を定義し、コードの再利用性と可読性を高めました。
  • ループと条件分岐while ループや if 文を使用して、ゲームのロジックを実装しました。
  • 入力のバリデーション:ユーザーからの入力を正規表現でチェックし、不正な入力に対して適切なエラーメッセージを表示しました。
  • 文字列操作:部分文字列の抽出や文字列の比較を行い、ユーザーの推測を正しく処理しました。

 シェルスクリプトを活用することで、さまざまなツールやゲームを簡単に作成することができます。今回のハングマンゲームを基に、単語のリストを増やしたり、試行回数を調整したり、ヒント機能を追加したりして、自分なりのゲームを作成してみてください。