プログラミング

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

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

 

注目の記事

フリーランスの仕事の取り方教えます!この3つを押さえておけばOKです【企業も応用可】
フリーランス
フリーランス,独立,起業
フリーランスの仕事の取り方教えます!この3つを押さえておけばOKです【企業も応用可】

  仕事ってどうやってとればいいの?   独立したい、起業したいと考えている人の多くが、仕事はどうやってとればいいのかと悩んで足踏みしています。 実は、基本的な3つのポイントさえ知っていれば、継続して仕事を受注することは簡単です。 今回は自分が実際にやっていることを例に「フリーランスなら...

稼ぐためには必ず知っておきたい100日継続法【100日坊主になりなさい】
雑記
稼ぐためには必ず知っておきたい100日継続法【100日坊主になりなさい】

  YouTubeやnoteで収益を上げたい   今やレッドオーシャンと呼ばれるそれらは、多くの人が挑戦して諦めてしまい、結局は上層が勝ち続けるという構造が揺らぎません。 しかし、多くの人は諦めるのが早すぎて、実際に結果が出るかも知れないものを断念しているのがほとんどです。 今回は、そういった人た...

WordPressで作ったサイトで実装するワンランク上のSEO対策
SEO対策
PHP,WordPress,プログラミング
WordPressで作ったサイトで実装するワンランク上のSEO対策

  WordPressでSEOに強いサイトを運営したい   近年、ブログを採用せずともWordPressを使用したサイト作りが増えてきました。 その理由には更新の手軽さはもちろん、優秀なプラグインが揃っていることでSEO対策に強いサイト作りが簡単だということが大きいです。   今回は、WordPressのブログやサイトで役立...

なぜプロは有線のマウスやキーボードを選ぶのか?【有線VS無線】
雑記
Bluetooth
なぜプロは有線のマウスやキーボードを選ぶのか?【有線VS無線】

  無線が普及する現代、何故有線のマウスやキーボードは売れているのか   いろんなものが製品の進化と共に無線化している一方、有線の需要も高く、とくにプロなど上層で活躍する人は有線を選択するケースが少なくありません。 今回は、そんな有線と無線の違いや、それぞれのメリットについて解説していき...

進化アニメーション 後編 PHPポケモン 60
プログラミング
PHP,PHPポケモン,ポケモン
進化アニメーション 後編 PHPポケモン 60

ポケモンの進化演出 前回に続いて、ポケモンの進化演出を実装していきます。バックエンドの処理はざっと説明をしたので、今回はフロントエンド(JavaScript)側の処理を作成していきましょう。   進化画面は新しく設けたので、こちらにもバトル画面で使っているメッセージ用JSを作成していきます。処理自体はほとん...

これってスパム?amazon・paypalを装う悪質メールの対処方法とは
ネットワーク
amazon,Paypal,Xserver,スパム,三井住友,楽天,迷惑メール
これってスパム?amazon・paypalを装う悪質メールの対処方法とは

定期更新、役立つコラムのコーナー!   今回の注目したのは「迷惑(悪質)メールについて」です。   以前はamazonや楽天を名乗る業者から届いた迷惑メールについて紹介、その対処方法について取り上げましたが、今回は更にレベルアップしたスパムがいくつか届いたので、それらも紹介がてら、騙されないため...

くれくれ姿勢が実は起業の近道だった!相手のことを考え過ぎるとハマる落とし穴とは
雑記
フリーランス,独立,起業
くれくれ姿勢が実は起業の近道だった!相手のことを考え過ぎるとハマる落とし穴とは

  仕事ください アドバイスしてください 〇〇について教えてください   こういったくれくれ姿勢の人は多く、投げかけられた側からすると「メリットは?」と感じてしまいます。 ですが実はこのくれくれ姿勢には意外な成功の要因が隠れています。多くの自己啓発記事やツイートをする人はこの本質的なものに触...

PHPポケモン「技クラス実装編」14
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「技クラス実装編」14

  前回せっかくBootstrapを使って見た目を整えたにも関わらず、ビューポートの記述が抜けているという凡ミスが発覚したので修正しています。 サーセン。   今回のPHPポケモンでは本格的な技システムを実装していきます。技システムが整えば、皆さん期待のバトルシステムも間近です。セキュリティ面やファイル構成...

カテゴリ

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