プログラミング

命中率補正と交代技編 PHPポケモン 45

PHP PHPポケモン ポケモン
命中率補正と交代技編 PHPポケモン 45

命中率補正とは

ダメージ計算や行動順判定には補正(ランク)を計算した結果を反映していましたが、命中率補正についてはまだ未実装だったため、今回はこちらを作成していきたいと思います。

まずはwikiを参考に、計算方法を見ていきましょう。

命中(ポケモンwiki

第三世代以降

A=技の命中率×ランク補正

ランク補正=自分のランク補正(命中率)-相手のランク補正(回避率)

 

他のランクと異なり、命中率の補正には「命中率」と「回避率」を計算する必要があります。単純にその差分を求めるだけですが、補正は他と同様に(ー6)〜(+6)の13段階のため、差分を求めて最大値・最小値に修正してから倍率を求めていきます。

 

命中率

ではまず命中率について見ていきましょう。

命中率(ポケモンwiki

 

命中ランクを減少させる技は初代の中でもいくつかありますが、上昇させることができるのは「ヨクアタール」というアイテムのみで技は存在しません。

今回は、命中率を下げる技の検証用として「すなかけ」を使って検証します。

 

すなかけ(/Classes/Move/SandAttack.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// すなかけ
class SandAttack extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'すなかけ';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手の命中率を1段階下げる。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Ground';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 100;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 15;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 相手の命中ランクを1段階下げる
        $msg = $def->subRank('Accuracy', 1);;
        $this->setMessage($msg);
    }
 
}

 

回避率

次に回避率について見ていきましょう。 

回避率(ポケモンwiki

 

こちらは命中率とは異なり、上昇させる技は初代でもいくつかある中、減少させる技がありません。

回避率を検証するための技には「かげぶんしん」を使用しましょう。

 

かげぶんしん(/Classes/Move/DoubleTeam.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// かげぶんしん
class DoubleTeam extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'かげぶんしん';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '自分の回避率を1段階上げる。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Normal';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = null;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 15;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 自分の回避率ランクを1段階上げる
        $msg = $atk->addRank('Evasion', 1);
        $this->setMessage($msg);
    }
 
}

 

命中判定への導入

それでは、ランク補正で算出した倍率を命中率に反映させましょう。ランク補正値は以下の通りです。

ランク -6以下 -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5 +6以上
倍率 2/8 2/7 2/6 2/5 2/4 2/3 2/2 3/2 4/2 5/2 6/2 7/2 8/2

※ランク = 自分の命中ランク – 相手の回避率ランク 

 

こうげき等のランク補正で算出したものと同じ式を使って倍率を求めていきます。詳細は以下の記事を参考にしてください。

 

ランク補正をかける箇所についてですが、一撃必殺技の命中率算出には補正がかかりません。なので、通常技の命中率計算でのみ補正がかかるよう、分岐内に記述しましょう。

 

攻撃用トレイト(/Traits/Service/Battle/ServiceBattleAttackTrait.php
/**
* 命中判定
*
* @param object $atk
* @param object $def
* @param object $move
* @return boolean
*/
private function checkHit($atk, $def, $move)
{
    // 一撃必殺技のチェック
    if($move->getOneHitKnockoutFlg()){
        if($atk->getLevel() < $def->getLevel()){
            // 相手の方がレベルが高ければ無効
            $this->setMessage($move->getOneHitKnockoutFailedMessage($def->getPrefixName()));
            return false;
        }
        // レベル差計算を含めた命中率を取得
        $accuracy = $move->getOneHitKnockoutAccuracy($atk, $def);
    }else{
        // 命中率取得
        $accuracy = $move->getAccuracy();
        // nullの場合は命中率関係無し
        if(is_null($accuracy)){
            return true;
        }
        /**
        * ランク補正
        * 攻撃側の命中率 - 防御側の回避率
        */
        $rank = $atk->getRank('Accuracy') - $def->getRank('Evasion');
        if($rank > 0){
            // プラス補正
            if($rank > 6){
                // 最大値丸め
                $rank = 6;
            }
            $per = (3 + $rank) / 3;
        }else{
            // マイナス補正
            if($rank < -6){
                // 最小値丸め
                $rank = -6;
            }
            $per = 3 / (3 - $rank);
        }
        // 倍率を切り捨てしてランク補正込みの命中率を算出
        $accuracy *= round($per, 2);
    }
    // カウンターの失敗判定
    if((get_class($move) === 'Counter') && empty($atk->getTurnDamage('physical'))){
        // 自身にこのターン物理ダメージが蓄積していなければ失敗
        $this->setMessage($move->getFailedMessage($atk->getPrefixName()));
        return false;
    }
    /**
    * 0〜100からランダムで数値を取得して、それより小さければ命中
    * 例:命中80%→mt_randで60が生成されたら成功、90なら失敗
    */
    if($accuracy >= mt_rand(0, 100)){
        // 攻撃成功
        return true;
    }
    // 攻撃失敗
    $this->setMessage($move->getFailedMessage($atk->getPrefixName()));
    return false;
}

 

checkHitメソッド内に追記しました。これで技の命中率に対して補正を掛けた値を命中率として判定を行うことができます。

それでは「すなかけ」と「かげぶんしん」を使って検証してみましょう。

 

すなかけ

 

 

 

 

 

 

 

かげぶんしん

 

 

 

 

  

「しっぽをふる」と「なきごえ」はともに命中率が100%の技です。なので、外れる判定が出ていればしっかりと回避率・命中率補正が入って判定がなされていることがわかります

もし正確な数値を確認したい人は、算出した命中率をvar_exportvar_dumpを使って出力してみてください。

 

交代技とは

数は限られていますが、ポケモンには「交代技」というものが存在します。最新世代のレーティングバトルでも採用されている戦略的な技のひとつです。

ポケモンチェンジ(ポケモンwiki

 

ポケモンを交代させる技にもいくつか種類がありますが、その中でも初代からある技は「ふきとばし」と「ほえる」の2つです。

 

「ふきとばし」と「ほえる」

この2つの技は基本的に同じ効果を持っています。特性などの関係上「ふきとばし」の方が優先的に採用されていますが、現段階でのPHPポケモンにおいては関係がありませんので、どちらも同等の技となります。

 

それでは、今回は検証用として「ふきとばし」を作成しましょう。

 

ふきとばし(/Classes/Move/Whirlwind.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// ふきとばし
class Whirlwind extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'ふきとばし';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Normal';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = null;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 20;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = -6;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // バトル終了
        $this->setMessage($def->getPrefixName().'は吹き飛ばされた');
        $this->setEmptyMessage('battle-end');
        $this->setResponse(true, 'end');
    }
 
}

 ※今回交代効果はeffectsメソッド内に記述していますが、こちらはバトルの仕様に合わせて変更となる可能性があります(トレーナー戦・ポケモンが複数所有できるなどの機能追加)

 

他の技と異なるポイントは、バトル強制終了用の空メッセージと、終了判定用のレスポンスをセットしている点です。こちらは後ほど別に判定箇所を設けます。

 

次に命中率判定についてです。こちらはポケモンwiki「ふきとばし」のページの技の仕様で記述があります。 

ふきとばし(ポケモンwiki

第五世代以降では、野生ポケモン戦では使用者よりレベルが高い相手に対するふきとばしは失敗する。トレーナー戦ではレベルに関係なく当たれば必ず交代させることができる。

 

現段階では野生ポケモンとのバトルしか存在していませんので、レベル差による命中判定のみを導入しましょう。この判定が採用されるのは「ふきとばし」と「ほえる」のみなので、カウンターを実装したときと同様に技クラス指定で判定を行います。

 

攻撃用トレイト(/App/Traits/Services/Battle/ServiceBattleAttackTrait.php
/**
* 命中判定
*
* @param object $atk
* @param object $def
* @param object $move
* @return boolean
*/
private function checkHit($atk, $def, $move)
{
    // ふきとばし・ほえるのチェック
    if(in_array(get_class($move), ['Whirlwind', 'Roar'], true)){
        if($atk->getLevel() < $def->getLevel()){
            $this->setMessage($def->getPrefixName().'は平気な顔をしている');
            return false;
        }
    }

 

checkHitメソッドの最初に判定を追加しました。レベル差を比較して失敗時にはそれに合わせたメッセージを返却しています。

 

バトル強制終了

それでは、ふきとばしのeffectsメソッドに記述したバトルの強制終了を受け取り判定する処理を追加しましょう。こちらは、サービス内に分岐を追加します。

 

「たたかう」のサービス
/**
* 行動順に攻撃処理
*
* @return boolean (false: ひんしポケモン有り)
*/
private function actionAttack($orders)
{
    foreach($orders as list($atk, $def, $move)){
        // 攻撃ポケモンの怒り解除
        $atk->releaseSc('ScRage');
        // 攻撃
        $this->attack($atk, $def, $move);
        // バトル終了のレスポンスチェック(交代技など)
        if($this->getResponse('end')){
            break;
        }
        // ひんしチェック
        $this->fainting = [
            $atk->getPosition() => $this->checkFainting($atk),
            $def->getPosition() => $this->checkFainting($def),
        ];
        // どちらかがひんし状態なら処理終了
        if($this->fainting['friend'] || $this->fainting['enemy']){
            $result = false;
            break;
        }
    } # endforeach
    // 結果返却
    return $result ?? true;
}

actionAttackメソッドで攻撃メソッドを呼び出した後、バトル終了判定が返ってきているかをチェックしています。「ふきとばし」や「ほえる」は優先度―6の技なので、基本的に後攻となりますが、相手も同優先度の技を使用していればこのタイミングでbreakしておかなければ內部でダメージ計算が行われてしまいます。

 

それでは「ふきとばし」を使って検証してみましょう。

 

高レベルの相手

 

 

低レベルの相手

 

 

 

 

高レベルの相手には失敗しましたが、低レベルの相手にはヒットしてバトルを強制終了することができました。

 

まとめ

いかがだったでしょうか。

今回のPHPポケモンでは「命中率補正」と「交代技」についてご紹介しました。

現在プログラミング学習に取り組んでいる方や、ゲームづくりに興味がある人は、ぜひ参考にしてみてくださいね。

 

注目の記事

PHPポケモン「バトルシステム編〜状態異常2〜」31
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜状態異常2〜」31

  前回に引き続き、状態異常チェックを実装します。 まず、前回実装した「ねむり」の処理についてですが、やはりターン数をセットして経過ターン数を引いていくという処理の方が解除率もゲーム再現になるので、まず修正をしておきます。サーセン。   チェック格納トレイト(/Traits/Battle/CheckTrait.php) ...

【PHP】可変長引数とは「点(ドット)3つ」 多次元連想配列の検索
プログラミング
PHP
【PHP】可変長引数とは「点(ドット)3つ」 多次元連想配列の検索

可変長引数とは  引数の数が決まっていない、状況に応じて複数の引数を指定したいときに、関数の引数で指定する点(ドット)3つのことです。PHP5.6以降で使用することができます。  PHPマニュアル 可変長引数リスト https://www.php.net/manual/ja/functions.arguments.php#functions.variable-arg-list ...

記事を書いてもブログが伸びないのは何故?SEOの評価を下げてしまう絶対にダメな3つのこと【知らない内に損してます】
SEO対策
SEO,ブログ
記事を書いてもブログが伸びないのは何故?SEOの評価を下げてしまう絶対にダメな3つのこと【知らない内に損してます】

  1年ブログを継続したけど、全くPVが伸びない・・・   ブログを育てるためには、毎日または定期的な更新が必ず必要ですが、それでも思うように伸びないという人は、実は他に致命的にな原因があることがほとんどです。 今回はそういった「努力しても結果が出ない」と悩んでいるブロガーやブログ運営者に...

パーティーの並び替え編 PHPポケモン 82
プログラミング
PHP,PHPポケモン,ポケモン
パーティーの並び替え編 PHPポケモン 82

パーティーの並び替え ポケモンをバトルに選出する際に欠かせないのが「パーティーの並び替え」です。パーティーの先頭(ひんし状態でない)がポケモンでは自動的に選択されるため、戦闘前に並び替えをしておく必要があります。 ゲーム上では簡単に見える処理ですが、これがPHPで行うとなれば少し厄介な問題が出てき...

Laravelで生成したCookie情報をjQueryで取得する方法【JavaScript】
プログラミング
ajax,api,JavaScript,jQuery,Laravel,PHP
Laravelで生成したCookie情報をjQueryで取得する方法【JavaScript】

  今回はLaravel開発備忘録です。 ajaxでapi認証してviewに記述したhtmlデータを取得するために、cookieを使ったapi_tokenの受け渡し手順をまとめてみました。   Laravelを使った開発をしている人は、ぜひ参考にしてくださいね。     Laravel側の処理   まずはcookieにデータをセットする必要があり...

PHPポケモン「バトルシステム実装編〜補正値計算・乱数・急所〜」21
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜補正値計算・乱数・急所〜」21

バトルシステムの実装  今回は「急所」と「乱数」と「タイプ一致」の判定と補正を実装していきます。 ちなみにですが、ポケモンwikiを熟読したところ、補正値の計算にも順番があり、計算後に小数点の切り捨てや五捨五超入をするなど、そこそこ複雑な計算順序がありましたが、今回はそこまで精密に再現せず、補正値(...

ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41
プログラミング
PHP,PHPポケモン,ポケモン
ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41

ダメージ固定技とは PHPポケモンでも作成したダメージ計算機能ですが、ポケモンの技の中にはそれを必要としない技がいくつかあります。それが「固定ダメージ技」です。 ポケモンwiki(ダメージ固定技) https://wiki.ポケモン.com/wiki/ダメージ固定技 ステータスに依存せず、わざ自体にダメージ量が決...

PHPポケモン「バトルシステム編〜状態変化〜」32
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜状態変化〜」32

状態変化とは  状態異常の実装が完了したので、いよいよ状態変化の実装に移ります。PHPポケモンで実装する状態変化とは以下の4つです。 こんらん ひるみ バインド やどりぎのタネ   上記4つを実装していきます。状態異常と異なり、技によっては追加になる可能性があります。 ※いかり状態など  ...

カテゴリ

SEO対策 イベント デザイン ネットワーク ビジネスモデル フリーランス プログラミング マーケティング ライティング 動画編集 雑記

タグ

5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO SEO対策 Sequel Pro Skype SNS SSH Symfony TCP/IP title Toastr Trait Twig Twitter UCC V系 WAN WebSub Wi-Fi wiki Windows WordPress XAMPP xml Xserver YouTube YouTuber Zoom アーティスト アウトプット アクセス層 アニメーション アフィリエイト イーブイ インターネット インプット エンジニア オブジェクト指向 お金配り クリック単価 クリック数 コミュニケーション能力 コロナ コンサルティング サムネイル システムエンジニア スタートアップ スタイルシート スパム データベース ディープフェイク デザイナー デザイン テレワーク ナンパ ニュース ネットワークモデル ノマドワーク バナー ピカチュウ ビジネス フィード フリーランス ブロガー ブログ プログラマー プログラミング プログラミング学習 プログラミング教育 プロトコル ホームページ制作 ポケモン マークアップ マーケティング メール リモートワーク レンダリング 三井住友 三宮 仕事依頼 児童デイ 児童デイサービス 児童発達支援 公開鍵 初心者 助成金 勉強法 営業 広告 広告収入 必勝マニュアル 放課後等デイサービス 朝活 楽天 深層学習 無線LAN 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力