シェルスクリプトでRPG風ゲームを作ってみる③

だしまき
2026-06-03
2026-06-03

はじめに

この間、初めて愛知の豊橋に行った際に名物のカレーうどんを食べてみたのですが、
カレーうどんの下にとろろご飯が仕込まれていて驚きました。

こんにちは、だしまきです。

かなり期間は空いたのですが、
シェルでRPGを作ってみよう第三弾!
という事でまた機能を追加してみようと思います。

前回まで

前回の記事はこちら
 シェルスクリプトでRPG風ゲームを作ってみる② 

前回はレベルアップ要素を追加しました。
まだまだRPGとしては味気が無いので、今回はこちらの機能を追加してみます。

・モンスターの種類を追加

では早速作っていきます!

モンスターの種類の追加

今まではモンスターの名前はモンスターとしか出していませんでしたが、
今回はモンスターの種類を追加し、それぞれに特徴を持たせていきたいと思います。

spawn_enemy() {

  case $((RANDOM % 5)) in

    0)
      enemy_name="スライム"
      enemy_hp=$((RANDOM % 11 + 20))     # 20〜30
      enemy_attack_max=8
      ;;

    1)
      enemy_name="ゴブリン"
      enemy_hp=$((RANDOM % 51 + 100))    # 100〜150
      enemy_attack_max=12
      ;;

    2)
      enemy_name="オーク"
      enemy_hp=$((RANDOM % 61 + 140))    # 140〜200
      enemy_attack_max=18
      ;;

    3)
      enemy_name="ゴースト"
      enemy_hp=$((RANDOM % 41 + 80))     # 80〜120
      enemy_attack_max=22
      ;;

    4)
      enemy_name="ドラゴン"
      enemy_hp=$((RANDOM % 101 + 250))   # 250〜350
      enemy_attack_max=35
      ;;

  esac

  echo "野生の $enemy_name が現れた!(HP: $enemy_hp)"
}

今回モンスターを5種類追加しました。
まず spawn_enemy を定義しこの後の戦闘開始時に呼び起せるようにします。
「case RANDOM % 5」で0~4のランダムな数字を作成し、5種類の敵から1体をランダムに選ぶ仕組みを作っています。
その後モンスターの名前、HP、最大攻撃力を設定しそれぞれ;;でcaseの1パターン終了の合図を出しています。
そしてesacでcase文の終了を宣言し、echoで上記処理で選ばれたモンスターの名前とHPを表示させています。


これでモンスターの種類追加が完了しました!

しかしながらこのままでは圧倒的違和感、、、何かというと

スライムとドラゴンの経験値が一緒!!
このままではドラゴンさんが威厳の無さで泣いてしまうので、
各モンスターに経験値を設定してあげましょう。
先程の各モンスターの設定項目の下にそれぞれ以下の設定と

 enemy_exp=$((RANDOM % 11 + 15)) # 15〜25 

(↑の場合は、倒した際に15~25の経験値を貰えるように設定)

 - gained_exp=$((RANDOM % 31 + 20)) # 20〜50
+ gained_exp=$enemy_exp

これまではモンスターを倒した後に、固定で20~50の経験値を得られるようにしていましたが、
設定した各モンスターごとの経験値を得られるように変更しました。

さいごに

という事で今回はモンスターの種類の設定をしてみました。
バリエーションが増えるだけでRPGっぽさが出てきますね。
更にやってみたい案としては、スキルの追加・回復システムの変更(アイテム等)など
まだまだ進化できる余地があるので、引き続き気が向いた時に遊んでみようと思います!
それでは~~

(今回追加したのも含めてシェルの中身を全て貼っておきます。)

#!/bin/bash

# ========================
# プレイヤーステータス
# ========================
player_level=1
player_exp=0
exp_to_levelup=100

player_hp=100
player_max_hp=100

player_attack_min=10
player_attack_max=30

# ========================
# ステータス表示
# ========================
show_status() {
  echo "========================"
  echo "現在のステータス:"
  echo "Lv.$player_level"
  echo "HP: $player_hp / $player_max_hp"
  echo "攻撃力: ${player_attack_min}〜${player_attack_max}"
  echo "EXP: $player_exp / $exp_to_levelup"
  echo "========================"
}

# ========================
# 敵生成
# ========================
spawn_enemy() {

  case $((RANDOM % 5)) in

    0)
      enemy_name="スライム"
      enemy_hp=$((RANDOM % 31 + 70))     # 70〜100
      enemy_attack_max=8
      enemy_exp=$((RANDOM % 11 + 35))    # 35〜45
      ;;

    1)
      enemy_name="ゴブリン"
      enemy_hp=$((RANDOM % 51 + 100))    # 100〜150
      enemy_attack_max=12
      enemy_exp=$((RANDOM % 11 + 45))    # 45〜55
      ;;

    2)
      enemy_name="オーク"
      enemy_hp=$((RANDOM % 61 + 140))    # 140〜200
      enemy_attack_max=18
      enemy_exp=$((RANDOM % 11 + 55))    # 55〜65
      ;;

    3)
      enemy_name="ゴースト"
      enemy_hp=$((RANDOM % 41 + 80))     # 80〜120
      enemy_attack_max=22
      enemy_exp=$((RANDOM % 11 + 65))    # 65〜75
      ;;

    4)
      enemy_name="ドラゴン"
      enemy_hp=$((RANDOM % 101 + 250))   # 250〜350
      enemy_attack_max=35
      enemy_exp=$((RANDOM % 11 + 215))    # 215〜225
      ;;

  esac

  echo "野生の $enemy_name が現れた!(HP: $enemy_hp)"
}

# 最初の敵出現
spawn_enemy

echo "========================"
echo "=== バトルスタート! ==="
echo "========================"

show_status

# ========================
# メインループ
# ========================
while [ $player_hp -gt 0 ]; do

  echo
  echo "あなたのHP: $player_hp / $player_max_hp"
  echo "$enemy_name のHP: $enemy_hp"

  echo "1: 攻撃  2: 回復"

  read -p "→ 行動を選んでください: " action

  # ========================
  # 攻撃
  # ========================
  if [ "$action" = "1" ]; then

    damage=$((RANDOM % (player_attack_max - player_attack_min + 1) + player_attack_min))

    echo "あなたの攻撃!"
    echo "$enemy_name に $damage ダメージ!"

    enemy_hp=$((enemy_hp - damage))

  # ========================
  # 回復
  # ========================
  elif [ "$action" = "2" ]; then

    heal=$((RANDOM % 31 + 10))  # 10〜40

    player_hp=$((player_hp + heal))

    if [ "$player_hp" -gt "$player_max_hp" ]; then
      player_hp=$player_max_hp
    fi

    echo "あなたは $heal 回復した!"

  else
    echo "無効な入力"
    continue
  fi

  # ========================
  # 敵撃破判定
  # ========================
  if [ $enemy_hp -le 0 ]; then

    echo "$enemy_name を倒した!"

    # 経験値獲得
    gained_exp=$enemy_exp

    player_exp=$((player_exp + gained_exp))

    echo "経験値を $gained_exp 獲得!"
    echo "現在: $player_exp / $exp_to_levelup"

    # ========================
    # レベルアップ
    # ========================
    if [ $player_exp -ge $exp_to_levelup ]; then

      player_level=$((player_level + 1))

      # 超過EXPを保持
      player_exp=$((player_exp - exp_to_levelup))

      # 次レベル必要EXP増加
      exp_to_levelup=$((exp_to_levelup + 50))

      # ステータス上昇
      hp_increase=$((RANDOM % 21 + 10))         # 10〜30
      atk_min_increase=$((RANDOM % 3 + 1))      # 1〜3
      atk_max_increase=$((RANDOM % 5 + 2))      # 2〜6

      player_max_hp=$((player_max_hp + hp_increase))
      player_hp=$player_max_hp

      player_attack_min=$((player_attack_min + atk_min_increase))
      player_attack_max=$((player_attack_max + atk_max_increase))

      echo
      echo "========================"
      echo "レベルアップ!!"
      echo "Lv.$player_level になった!"
      echo "========================"

      echo "最大HP +$hp_increase"
      echo "攻撃力 +${atk_min_increase}〜+${atk_max_increase}"

      echo "HPが全回復した!"
    fi

    echo
    echo "------------------------"

    # 次の敵出現
    spawn_enemy

    show_status

    continue
  fi

  # ========================
  # 敵ターン
  # ========================
  enemy_damage=$((RANDOM % (enemy_attack_max + 1)))

  echo
  echo "$enemy_name の攻撃!"
  echo "あなたに $enemy_damage ダメージ!"

  player_hp=$((player_hp - enemy_damage))

  # ========================
  # ゲームオーバー
  # ========================
  if [ $player_hp -le 0 ]; then

    echo
    echo "========================"
    echo "あなたは倒れた…"
    echo "ゲームオーバー"
    echo "========================"

    break
  fi

done