素人が RPG の開発に挑戦してみる 3

必中固定ダメージではたとえ僅差であってもパラメータの違いが勝敗を決定付けてしまうことが分かった。そこで回避判定を入れてみる。Character クラスに器用度 deftness を加え、敵の敏捷度と比較した上で攻撃が命中したかどうかを判定する。

  attr_accessor :name, :life, :power, :toughness, :fleetness, :deftness

計算式をどうするかが悩みどころだが、先に各パラメータの算出基準を明確にする必要があるだろう。とりあえずオール 2D6、monster 君は全てにおいて adventurer 君を上回るとしたらこうなった。

■ adventurer 君
life      : 10
power     : 11
toughness :  9
fleetness :  5
deftness  :  6

■ monster 君
life      : 12
power     : 12
toughness : 10
fleetness :  6
deftness  :  7

この条件では adventurer 君には勝目がない。adventurer 君が 1 ターンに 1 ダメージしか与えられないのに対して、monster 君は 3 ダメージだからだ。攻撃を回避できない限り adventurer 君に未来はない。追加した deftness を使って彼にチャンスを与えてやろうではないか。まずは単純に攻撃側の器用度と防御側の敏捷度で勝負してみる。

  def resolve
    offense = defense = nil
    1.upto(20) do |turn|
      if turn % 2 == 1
        defense, offense = [@a, @b].sort{|a, b| amend_fleetness(a) <=> amend_fleetness(b)}
        puts "■第 #{sprintf('%02d', turn / 2 + 1)} ターン"
      end
      print "  #{offense.name} の攻撃: "
      if amend_deftness(offense) < amend_fleetness(defense)
        puts "  #{defense.name} には当たらなかった"
      else
        damage = offense.attack(defense)
        puts "  #{defense.name}#{damage} のダメージ"
        # 生死判定
        break unless defense.life > 0
      end
      # 攻守交代
      defense, offense = offense, defense
    end

    if @a.dead?
      puts "#{@a.name} は死んだ"
    elsif @b.dead?
      puts "#{@a.name}#{@b.name} を倒した"
    else
      puts "#{@a.life > @b.life ? @b.name : @a.name} は逃げ出した"
    end
  end

  def amend_fleetness(c)
    c.fleetness + rand(c.fleetness) * 0.5
  end

  def amend_deftness(c)
    c.deftness + rand(c.deftness) * 0.5
  end

ところで防御は diffence ではなく defence であった。そもそも diffence などという単語は存在しない模様。さらに攻撃を意味するのは offence ではなく offense らしい。つくづく英語弱いな。他にも補正メソッドの名前が気に入らなかったりターン計算がおかしかったりと問題だらけだったのでまとめて修正した。どうにもやっつけ感が拭えないが気にしない。

やはり通勤時間、始業前、昼休み、定時後休憩、帰宅時間で仕様を考えてコード書いて日記を書くというスケジュールに無理があるのかもしれない。帰宅後? ええと、FFCCLK は面白いよ。

気を取り直して、いざ勝負。

a = Character.new
a.name = 'adventurer'
a.life = 10
a.power = 11
a.toughness = 9
a.fleetness = 5
a.deftness = 6

b = Character.new
b.name = 'monster'
b.life = 12
b.power = 12
b.toughness = 10
b.fleetness = 6
b.deftness = 7

Judge.new(a, b).resolve

結果。わはは。こりゃイカン。逆に adventurer 君が不利になってる。補正していると言っても、結局は元の数値が大きい方が有利になってるから当然か。考えが浅すぎた。

■第 01 ターン
  monster の攻撃:   adventurer は 3 のダメージ
  adventurer の攻撃:   monster には当たらなかった
■第 02 ターン
  monster の攻撃:   adventurer は 3 のダメージ
  adventurer の攻撃:   monster は 1 のダメージ
■第 03 ターン
  adventurer の攻撃:   monster には当たらなかった
  monster の攻撃:   adventurer は 3 のダメージ
■第 04 ターン
  monster の攻撃:   adventurer は 3 のダメージ
adventurer は死んだ

これに武器だの防具だのが絡んできたらとても手に負えんな。なるほど RPG のこの辺のデザインと調整はまさしくノウハウなのだなと実感。根幹となる戦闘システムはいい加減な覚悟でどうにかなるものではないようだ。これはちょっとばかり解決には時間がかかりそうだぞ。……やっぱりパクるか。


ロールプレイングゲームプログラミング

ロールプレイングゲームプログラミング