プログラミング

命中率補正と交代技編 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ポケモンでは「命中率補正」と「交代技」についてご紹介しました。

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

 

注目の記事

npm run watch-poll中にPCがフリーズした時の解決法
プログラミング
CSS,JavaScript,Laravel,Linux
npm run watch-poll中にPCがフリーズした時の解決法

  Laravelで開発中にPCが頻繁にフリーズするという問題にぶち辺り、原因がnpm run watch-pollだということが解ったので、その解決方法をまとめておきます。 複雑な原因でもなく大きな問題にもならなかったのですが、これが原因でデータ破損となれば困るので、同じような問題に直面した開発者向けです。    ...

電話対応必勝法!理不尽クレーマーに強くなる秘策を伝授します
雑記
電話対応必勝法!理不尽クレーマーに強くなる秘策を伝授します

  「電話対応って難しい・・・」 「クレーマーに日々苦しめられている・・・」   サラリーマンなど電話対応を業務している人にとっては大きな悩みではないでしょうか。 今回はそういった方に向けて、過去多くの理不尽クレーマーと向き合ってきた経験を元に「電話対応必勝法!理不尽クレーマーに強くなる...

データ軽量化編 β版へ向けて  PHPポケモン 90
プログラミング
PHP,PHPポケモン,ポケモン
データ軽量化編 β版へ向けて PHPポケモン 90

β版の実装に向けて 大型アップデートにより、ある程度機能改善や実装箇所も増えてきましたが、それと同時に次の段階への移行が本格的に見えてきました。それがβ版です。   PHPポケモンは2020年12月現在α版となっており、完全な試作段階のWEBアプリケーションです。セーブ機能はなく、セッションの有効期...

フリーランス必見!良質案件を獲得するための3つのプロセス
フリーランス
フリーランス必見!良質案件を獲得するための3つのプロセス

  「良い案件に巡り会えない」 「なかなか仕事が受注できない」   駆け出しフリーランスや、これから独立しようと考えている人が直面する大きな悩みの1つですね。 ですが、意外にも自分でその案件自体を制限していたり、良質だった案件を自らで質を下げてしまっているというケースは少なくありません。...

初心者必見!仕事がデキる人のIllustrator活用術3選
デザイン
Adobe,Illustrator,サムネイル
初心者必見!仕事がデキる人のIllustrator活用術3選

  仕事の速い人の大半は、「効率の良い方法」や「便利な使い方」を知っていて使いこなしています。これは、デザインの現場でも同じです。 今回はその中でもIllustratorで知っておくと便利な機能を3つご紹介します。この3つを押さえておくだけで、作業効率は格段にアップするので、これからソフトの使い方を覚...

反動技編(はかいこうせん・とびひざげり)PHPポケモン40
プログラミング
PHP,PHPポケモン,ポケモン
反動技編(はかいこうせん・とびひざげり)PHPポケモン40

反動技とは ポケモンでは反動技というものがあります。反動によっても様々で、現在の仕組みのままでも実装可能なものや、新たに処理が必要なものまであります。なので、一律で反動技という同じ処理は出来ません。  反動技(ポケモンwiki) https://wiki.ポケモン.com/wiki/反動技 反動技(はんどうわざ...

命中率補正と交代技編 PHPポケモン 45
プログラミング
PHP,PHPポケモン,ポケモン
命中率補正と交代技編 PHPポケモン 45

命中率補正とは ダメージ計算や行動順判定には補正(ランク)を計算した結果を反映していましたが、命中率補正についてはまだ未実装だったため、今回はこちらを作成していきたいと思います。 まずはwikiを参考に、計算方法を見ていきましょう。 命中(ポケモンwiki) https:// wiki.ポケモン.com/wiki/命中 第...

具体的にフリーランスで生きていくには -独立してからの働き方を徹底解説-
フリーランス
フリーランス,独立
具体的にフリーランスで生きていくには -独立してからの働き方を徹底解説-

  安定した仕事に就きたい。。。   多くの人がそう思っていた時代はどんどんと変化して、今やフリーランスでいることの方が安定しているのではないかと言えるような時代です。 そう、もはや会社員でいる人の大半が安定ではなくなってきているのです。 フリーランスでいる人も、根本的に安定という...

カテゴリ

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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力