目次へもどる

ジャマー発生数を計算しよう

スコア計算ができたということはいよいよジャマーの発生数をちゃんと計算できるということである!

ジャマーの発生数

ジャマーは連鎖スコアが大きいほど沢山発生する. ジャマーの発生数の式は以下.

ジャマー発生数 = 連鎖スコア / ジャマーレート

非常にわかりやすい. 続いてジャマーレートの式

ジャマーレート = 初期レート * レート倍率

レート倍率は経過時間によって増加する.また,レート倍率はマージンタイムの間は 増加しない.マージンタイムを過ぎると経過時間によって以下の表に基づいたレート倍率となる*1. ちなみに経過時間は16進数表記である点に注意.(20(16)=32秒)

経過時間(16)[s]020406080A0C0E01001201401601801A0以上
レート倍率3/42/43/82/83/162/163/322/323/642/643/1282/1283/2562/256

さて,またこんな表をだらだら書いといてなんだが,マージンタイムも含めたレート倍利率は以下の式で求まる.

レート倍率 = if rate_index < 0 then 1
             else if rate_index >= 14 then 2/256
             else (3 - rate_index % 2)/(4 * 2 ** (rate_index / 2))
ただし
rate_index = (sec - margin) / 0x20
レート倍率は最小が1で小数以下は切り捨てる

また,例えばジャマーレート70の時に,スコア100をたたくとジャマーは1コ発生するが,この時余った30は保存しておき,次のジャマーの個数計算に加算される*2

実装

あとは淡々と実装していこう.

class JammerManager
  def initialize(row_s, line_s)
    @row_s = row_s
    @line_s = line_s
    @jammers = 0
    @rest = 0
    @fall_max = (line_s / 3 + 1) * row_s
    @gen_jammers = 0
    init_order
  end
  def calc_effective_rate(rate, margin, playtime)
    playsec = playtime / 60
    rate_index = (playsec - margin) / 0x20
    if rate_index < 0 # margin
      effective_rate = rate
    elsif rate_index >= 14 # max rate
      effective_rate = (rate * Rational(2, 256)).to_i
    else
      effective_rate = (rate * Rational(3 - rate_index % 2, 4 * 2 ** (rate_index/2))).to_i
    end
    [effective_rate, 1].max
  end
  def calc_jammer(score, rate, margin, playtime)
    effective_rate = calc_effective_rate(rate, margin, playtime)
    score += @rest # prev calc rest
    @rest = score % effective_rate
    @gen_jammers = score / effective_rate
  end
end

デバッグや利便性を考えてスコアと同様にジャマーの発生数の計算結果をインスタンス変数に保存しておくことにした.ジャマーの発生数の計算をそのままプログラムしているだけなので特に問題は無いだろう.あるとすればRationalだろうか.これはRubyの組み込みクラスで分数を表すクラスである.整数や浮動点小数と普通にミックスして計算可能である.

class ScenePuyoPuyo < SceneBase
  def start
    @playtime = 0
    @margin_time = 96
    (略)
  end
  def update
    super
    @players.each do |controller|
      controller.update
    end

    @playtime += 1
  end
end

シーンのプレイタイム(フレーム)をカウントする@playtimeとマージンタイム@margin_timeを追加した.マージンタイムはプレイヤーのさらに上,ゲームルールに属するのでとりあえずシーンに追加することにした.

module GameMain
  def self.scene
    @scene.first
  end
end

シーンが持つ変数を取得しなければならないので,現在のシーンを取得するメソッドをGameMain?に追加した.

class Field
    def initialize(row_s, line_s, block_s, cbm, sm)
    @row_s = row_s
    @line_s = line_s
    @block_s = block_s
    @fallen = false
    @eliminated = false
    @cbm = cbm
    @sm = sm
    @chain = 0
    @jammer_rate = 70
    init_table
    init_jammer_manager
    init_blocklist
    init_connect_table
  end
  def eliminate
    @eliminated = false
    make_connect_table
    fair_connect_table
    @chain += 1 unless @connect_table.empty?
    @sm.score += @sm.calc_chain_score(@connect_table, @chain)
    scene = GameMain.scene
    unless @connect_table.empty?
      @jm.jammers += @jm.calc_jammer(@sm.chain_score, @jammer_rate, scene.margin_time, scene.playtime)
    end
    eliminate_connection
    @eliminated
  end
end

初期ジャマーレートはFieldクラスに追加した.なぜならぷよぷよフィーバーではキャラごとにレートが異なるほか,通常時とフィーバー時でレートが変動するためである.

そしてブロックの消去時にジャマーを発生させれば完成である.

実行

これでちゃんとジャマーの発生が計算されるようになった. デバッグのためマージンタイムを0にして実行した.

Loading the player ...

画面上に様々な情報を表示しているが,32秒経過したところでジャマーレートが下がったことに注目.


*1 これについてはサイトによって諸説あるがまあこまかいことはどうでも良い
*2 これもぷよぷよのバージョンによって加算されないものもあるが折角なので導入

添付ファイル: filePuyoPuyoChap28.flv 246件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-08-30 (金) 22:17:22 (1783d)