シェルスクリプト:迷路ゲーム
シェルスクリプトは、システム管理だけでなく、ゲームの作成にも活用できる強力なツールです。ここでは、シェルスクリプトを使って「迷路ゲーム」を作成し、その手順と詳細な解説を行います。この演習を通じて、シェルスクリプトの基本的な構文、配列の操作、条件分岐、ループ、関数の定義と利用、ユーザー入力の処理などの知識を総合的に学ぶことができます。
迷路ゲームの概要
ゲームの目的
- 迷路を出口まで進み、ゴールを目指します。
ゲームのルール
- 迷路の設定
・迷路は二次元配列で表現されます。
・壁は#
、通路は空白 で表現されます。
・プレイヤーの位置はP
、ゴールはG
で表します。 - ゲームの進行
・プレイヤーは上下左右に移動できます。
・壁の位置には移動できません。
・ゴールに到達するとゲームクリアです。
迷路の例
#######
# #
# ### #
# # #
# #G# #
# ### #
#P #
#######
maze.sh
の作成から実行までの手順と解説
ステップ1:スクリプトファイルの作成
ターミナルで以下のコマンドを実行し、新しいスクリプトファイル maze.sh
を作成します。
user01@ubuntu:~$ nano maze.sh
ステップ2:スクリプトの内容を記述
エディタが開いたら、以下のコードをコピーして貼り付けます。
#!/bin/bash
# 迷路の定義
maze=(
"#######"
"# #"
"# ### #"
"# # #"
"# #G# #"
"# ### #"
"#P #"
"#######"
)
# プレイヤーの初期位置を取得
get_player_position() {
for i in "${!maze[@]}"; do
row="${maze[$i]}"
col_index=$(expr index "$row" "P")
if [ $col_index -ne 0 ]; then
player_row=$i
player_col=$((col_index - 1))
return
fi
done
}
# 迷路の表示
display_maze() {
clear
for row in "${maze[@]}"; do
echo "$row"
done
}
# 移動の処理
move_player() {
local new_row=$player_row
local new_col=$player_col
case $1 in
w) new_row=$((player_row - 1)) ;;
s) new_row=$((player_row + 1)) ;;
a) new_col=$((player_col - 1)) ;;
d) new_col=$((player_col + 1)) ;;
*) echo "無効な入力です。w(上), a(左), s(下), d(右) のいずれかを入力してください。"; return ;;
esac
# 移動先の取得
line="${maze[$new_row]}"
target_char="${line:$new_col:1}"
if [ "$target_char" == "#" ]; then
echo "壁にぶつかりました。別の方向を試してください。"
else
# ゴール判定
if [ "$target_char" == "G" ]; then
echo "おめでとうございます!ゴールに到達しました。"
exit
fi
# プレイヤーの位置を更新
maze[$player_row]="${maze[$player_row]:0:$player_col} ${maze[$player_row]:$((player_col + 1))}"
maze[$new_row]="${maze[$new_row]:0:$new_col}P${maze[$new_row]:$((new_col + 1))}"
player_row=$new_row
player_col=$new_col
fi
}
# ゲーム開始
get_player_position
display_maze
# メインループ
while true; do
read -n1 -p "移動方向を入力してください (w:上, a:左, s:下, d:右): " direction
echo
move_player "$direction"
display_maze
done
ステップ3:スクリプトの内容の解説
1.シェバン行
#!/bin/bash
- スクリプトが Bash シェルで実行されることを指定します。
2.迷路の定義
maze=(
"#######"
"# #"
"# ### #"
"# # #"
"# #G# #"
"# ### #"
"#P #"
"#######"
)
- 目的:迷路を二次元配列として定義します。
- 解説:
・迷路は文字列の配列として表現されます。
・#
が壁、P
がプレイヤー、G
がゴールです。
3.プレイヤーの初期位置を取得する関数 get_player_position
get_player_position() {
for i in "${!maze[@]}"; do
row="${maze[$i]}"
col_index=$(expr index "$row" "P")
if [ $col_index -ne 0 ]; then
player_row=$i
player_col=$((col_index - 1))
return
fi
done
}
- 目的:迷路内からプレイヤーの初期位置を特定します。
- 解説:
・各行を調べて、P
の位置を見つけます。
・expr index
コマンドを使用して文字の位置を取得します。
4.迷路を表示する関数 display_maze
display_maze() {
clear
for row in "${maze[@]}"; do
echo "$row"
done
}
- 目的:迷路を画面に表示します。
- 解説:
・clear
コマンドで画面をクリアします。
・迷路の各行を順に表示します。
5.プレイヤーを移動する関数 move_player
move_player() {
local new_row=$player_row
local new_col=$player_col
case $1 in
w) new_row=$((player_row - 1)) ;;
s) new_row=$((player_row + 1)) ;;
a) new_col=$((player_col - 1)) ;;
d) new_col=$((player_col + 1)) ;;
*) echo "無効な入力です。w(上), a(左), s(下), d(右) のいずれかを入力してください。"; return ;;
esac
# 移動先の取得
line="${maze[$new_row]}"
target_char="${line:$new_col:1}"
if [ "$target_char" == "#" ]; then
echo "壁にぶつかりました。別の方向を試してください。"
else
# ゴール判定
if [ "$target_char" == "G" ]; then
echo "おめでとうございます!ゴールに到達しました。"
exit
fi
# プレイヤーの位置を更新
maze[$player_row]="${maze[$player_row]:0:$player_col} ${maze[$player_row]:$((player_col + 1))}"
maze[$new_row]="${maze[$new_row]:0:$new_col}P${maze[$new_row]:$((new_col + 1))}"
player_row=$new_row
player_col=$new_col
fi
}
- 目的:ユーザーの入力に基づいてプレイヤーを移動させます。
- 解説:
・case
文で入力された方向に応じて新しい位置を計算します。
・移動先が壁#
の場合、移動をキャンセルします。
・ゴールG
に到達した場合、ゲームを終了します。
・プレイヤーの位置を更新し、迷路を更新します。
6.ゲーム開始の準備
get_player_position
display_maze
解説
プレイヤーの初期位置を取得し、迷路を表示します。
7.メインループ
while true; do
read -n1 -p "移動方向を入力してください (w:上, a:左, s:下, d:右): " direction
echo
move_player "$direction"
display_maze
done
- 目的:ユーザーからの入力を待ち、プレイヤーを移動させます。
- 解説:
・read -n1
で1文字の入力を受け取ります。
・入力された方向に基づいてmove_player
関数を呼び出します。
・迷路を再表示します。
ステップ4:スクリプトに実行権限を付与
スクリプトを保存してエディタを終了したら、実行権限を付与します。
user01@ubuntu:~$ chmod +x maze.sh
ステップ5:スクリプトの実行
スクリプトを実行して、迷路ゲームを開始します。
user01@ubuntu:~$ ./maze.sh
実行例
#######
# #
# ### #
# # #
# #G# #
# ### #
#P #
#######
移動方向を入力してください (w:上, a:左, s:下, d:右): d
#######
# #
# ### #
# # #
# #G# #
# ### #
# P #
#######
移動方向を入力してください (w:上, a:左, s:下, d:右): d
#######
# #
# ### #
# # #
# #G# #
# ### #
# P #
#######
(中略)
おめでとうございます!ゴールに到達しました。
解説
- ユーザーは
w
、a
、s
、d
キーを使用してプレイヤーを移動させます。
・w
:上に移動a
:左に移動
・s
:下に移動
・d
:右に移動 - 壁
#
にぶつかった場合、移動できません。 - ゴール
G
に到達するとゲームクリアとなります。
ここで作成したファイルの削除
ゲームのテストが終了したら、作成した maze.sh
ファイルを削除します。
user01@ubuntu:~$ rm maze.sh
まとめ
- シェルスクリプトの応用:迷路ゲームを通じて、シェルスクリプトでのゲーム作成方法を学びました。
- 配列の操作:迷路を二次元配列で管理し、効率的にデータを扱いました。
- 関数の定義と利用:コードを関数に分割し、可読性と再利用性を向上させました。
- ユーザー入力の処理:
read
コマンドを使用してユーザーの入力を受け取りました。 - 条件分岐とループ:
if
文やcase
文、while
ループを使って、ゲームの進行とロジックを制御しました。 - 文字列操作:文字列の部分抽出や置換を行い、迷路の更新を行いました。
シェルスクリプトは、システム管理以外にも多くの用途で活用できます。今回の迷路ゲームを基に、迷路のサイズや複雑さを変更したり、アイテムや敵キャラクターを追加したりして、さらなる機能拡張に挑戦してみてください。