モビルファイト対戦処理のコード、裏側の仕様を大公開する件について

今回は超貴重なモビルファイト(以下MF)の対戦処理プログラムを公開する。
※これは2017年時のもので、現在と異なっている
実はMFでは実際の対戦に使われている処理は90行程度である。
今回はそれを公開する。見たい方は是非考察いただきたい。

#
#戦闘実行処理
#
for(my $turn = 0; $turn < 200; $turn++){
    #ゲージ増加スピード依存
    $my_gauge += $my_sp;
    $vs_gauge += $vs_sp;
    if ($my_gauge >= $vs_gauge and $my_atcnt > 0){
        $my_prob = int(rand(100) + 1);
        if ($my_hit >= $my_prob){
            if ($my_cho >= $my_prob){
                #クリティカル
                $$VS_STATE[13] -= int(($my_at * 1.4));$my_meichu[$my_cnt] = 3;
            } else {
                #ヒット
                $$VS_STATE[13] -= $my_at;$my_meichu[$my_cnt] = 2;
            } 
            $my_gauge = 0;$my_atcnt--;$my_cnt++;
        } else {
            #ハズレ
            $my_meichu[$my_cnt] = 1;$my_gauge = 0;$my_atcnt--;$my_cnt++;
        }
        #ターンメッセージ
        $turn_msg .= "◯";
    } elsif ($vs_gauge >= $my_gauge and $vs_atcnt > 0){
        $vs_prob = int(rand(100) + 1);
        if ($vs_hit >= $vs_prob){
            if ($vs_cho >= $vs_prob){
                #クリティカル
                $$MY_STATE[13] -= int(($vs_at * 1.4));$vs_meichu[$vs_cnt] = 3;
            } else {
                #ヒット
                $$MY_STATE[13] -= $vs_at;$vs_meichu[$vs_cnt] = 2;
            } 
            $vs_gauge = 0;$vs_atcnt--;$vs_cnt++;
        } else {
            #ハズレ
            $vs_meichu[$vs_cnt] = 1;$vs_gauge = 0;$vs_atcnt--;$vs_cnt++;
        }
        #ターンメッセージ
        $turn_msg .= "▽";
    }
    #敵撃墜判定
    if ($$VS_STATE[13] <= 0){
        $$VS_STATE[24] = 0;$$VS_STATE[13] = 0;
        if ($nb_flag eq "1"){
            $msg = "「$$MY_STATE[0]」が「$$VS_STATE[0]」を撃破。「$$VS_STATE[3]」機は中破。";
        } else {
            $msg = "「$$MY_STATE[0]」が「$$VS_STATE[0]」を撃破。「$$VS_STATE[3]」機は大破。";
        }
        $msg2 = "「$$MY_STATE[0]」が「$$VS_STATE[0]」を撃破。";
        $result = 1;
        #自爆大破
        if ($mission eq "12"){
            $$MY_STATE[24] = 0;
        }
        last;
    }
    #自機大破判定
    if ($$MY_STATE[13] <= 0){
        $$MY_STATE[24] = 0;$$MY_STATE[13] = 0;
        if ($nb_flag eq "1"){
            $msg = "「$$VS_STATE[0]」が「$$MY_STATE[0]」を撃破。「$$MY_STATE[3]」機は中破。";
        } else {
            $msg = "「$$VS_STATE[0]」が「$$MY_STATE[0]」を撃破。「$$MY_STATE[3]」機は大破。";
        }
        $msg2 = "「$$VS_STATE[0]」が「$$MY_STATE[0]」を撃破。";
        $result = 0;
        last;
    }
    #自機攻撃終了判定
    if ($my_atcnt <= 0){
        $my_gauge = 0; $my_sp = 0; $vs_at = $vs_at_down; $vs_hit = $vs_hit_down;
        if ($skill_msg eq ""){
            $skill_msg = "自機の攻撃終了特殊補正が発動。";
        }
    }
    #敵機攻撃終了判定
    if ($vs_atcnt <= 0){
        $vs_gauge = 0; $vs_sp = 0; $my_at = $my_at_down; $my_hit = $my_hit_down;
        if ($skill_msg eq ""){
            $skill_msg = "敵機の攻撃終了特殊補正が発動。";
        }
    }
    #両機未大破終了判定
    if ($my_atcnt == 0 and $vs_atcnt == 0){
        $msg = "「$$MY_STATE[0]」と「$$VS_STATE[0]」は交戦後、戦闘を終了。";
        $msg2 = "「$$MY_STATE[0]」と「$$VS_STATE[0]」が交戦。";
        $result = 2;
        last;
    }
}

ブログ主が運営しているゲームです。
こちらよりどうぞ

コメント

  1. 匿名 より:

    公開された貴重なコードですが、大変参考になります。

    そこで、さらなるお願いで恐縮なのですが、
    $my_hit
    $my_sp
    $my_at
    の計算式の部分も、公開していただけないでしょうか?
    $my_at = my武器攻撃 x (1 + (my攻撃ステータス – VS防御ステータス)/150) x (1 – VS防御属性%)
    みたいな部分です。

    ある意味、答え合わせです。

  2. 山羊丸 より:

    答えになるか分かりませんが、以下の計算式を用いています。
    おおよそ見当はつくと思いますが、攻撃と防御、回避と命中は連携しています。
    実際に使われるのは攻撃力と命中率のみとなります。
    なお速度と直感は完全に分離しています。
    後の解説はいたしせん。分析してご自分で解析してみてください。
    ちなみにステータスの補正は非常に複雑なので公開する予定はありません。あしからず。

    my $my_at = int($$MY_WEAPON[2] + ($$MY_WEAPON[2] * (($MY_STATE17 – $VS_STATE18) * 0.01)));#自機攻撃力
    my $vs_at = int($$VS_WEAPON[2] + ($$VS_WEAPON[2] * (($VS_STATE17 – $MY_STATE18) * 0.01)));#敵機攻撃力
    my $my_hit = int($$MY_WEAPON[4] + ($MY_STATE21 – $VS_STATE20));#自機命中率
    my $vs_hit = int($$VS_WEAPON[4] + ($VS_STATE21 – $MY_STATE20));#敵機命中率
    my $my_sp = int($MY_STATE19 – ($$MY_WEAPON[5] * 9));#自機スピード
    my $vs_sp = int($VS_STATE19 – ($$VS_WEAPON[5] * 9));#敵機スピード
    my $my_cho = int($MY_STATE22 * 0.65);#自機クリティカル率
    my $vs_cho = int($VS_STATE22 * 0.65);#敵機クリティカル率
    my $my_en = $$MY_WEAPON[6];#自機消費EN

  3. 山羊丸 より:

    コメントだと改行が煩わしいと思われるので
    メモ帳などに転記してじっくり見ることをおすすめします。

  4. 匿名 より:

    公開していただいてありがとうございました。

    答え合わせの結果です。

    ダメージの式、命中の式は、かなり合っていました。
    ダメージ式に関しては、もともと5%くらいの精度で計算できていたので、
    合っている自信はありましたが。
    命中の式は「たぶんダメージ式と同じだろう」と想像して実験してみると
    そこそこ合っていたので、それで満足していました。
    (確率を実験で精度良く測定することは、難しいのです)

    速度の式は、かなり違っていました。
    速度については、今でも分からないことが多数あって、
    特に速度の差が大きくなると、今回公開された情報を元にしても、
    うまく計算出来ていないです。

    >ちなみにステータスの補正は非常に複雑なので公開する予定はありません。

    それはわかります。
    天候補正、ペットステータス補正、ペット属性補正、機体補正(強襲とか)、戦法補正(通常攻撃とか)、
    あまりにもたくさんの補正がありましたからね。
    補正幅も小さく、足し算補正と仮定しようが、かけ算補正と仮定しようが、結果はそれほど変わりませんし。

    天候による速度補正は、攻撃側防御側同じようにかかっていたようで、
    どういう意味があったのか、最後まで分からなかったです。

    最後に、とてもおもしろいゲームを遊ばせて頂いた事に、とても感謝いたします。

  5. 山羊丸 より:

    目測で計算できているだけでもすごいですよ。
    なぜなら開発者の私自身、把握できてない状態で仕様を追加していましたから。
    おそらく純粋なダメージ計算器を導入していたのは貴殿のみだと思います。

    あえてヒントだけ申し上げるとすれば、ペットステ以外は大体%計算である乗算です。
    僕も全部見返すほど労力は使いたくないのでおぼろげな記憶ですが、
    大体はそんな感じだったと思います。

    モビルファイトはいつか再公開できればと考えています。
    現状では敗色濃厚ですが、色々考えてはいます。
    ただ、著作権の問題もありますし、体力面の問題もあります。
    しかし、何らかの形で復帰できないかとは考えています。
    と、ここまで書いてしまいましたが、期待はしないでください。
    もしかしたら10年後にいつの間にか復活しているかもしれない位の感覚でお願いします。