プログラミング

命中率補正と交代技編 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選
フリーランス
フリーランスになるなら知っておきたい!無料サービス3選

  「フリーランスになる前に何を準備すればいいの?」 「フリーランス向けの便利なサービスが知りたい」   今回はそんな悩みを抱えた人へ向けて「フリーランスになるなら知っておきたい!無料サービス3選」をご紹介します。 この記事を読んで、フリーランスにとっての悩みである以下の3つの問題を一緒...

甘い誘惑に気をつけよう「わからないことへの対処法」
雑記
甘い誘惑に気をつけよう「わからないことへの対処法」

  最近は開発記事が多めだったので、今回は気分転換も込めてみんな大好きコラムのコーナーです。開発疲れという理由ももちろんありますが、久々に考えを書き綴りたくなったというのが本音です。   今回のテーマは「甘い誘惑に気をつけよう」です。高校生ぐらいまではあまり縁がなかったことでも、大学生・社会...

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

状態異常チェック 今回は少し先延ばししていた状態異常判定を一部作成していきましょう。 状態異常では「行動前」と「行動後」に判定するものに分けることができます。 行動前 まひ、ねむり、こおり  行動後 どく、もうどく、やけど   まずは簡単な行動前から実装していきます。行動前に判...

構成見直し編(クラス名) PHPポケモン49
プログラミング
PHP,PHPポケモン,ポケモン
構成見直し編(クラス名) PHPポケモン49

構成の見直し 今回は全体構成の見直しをします。ディレクトリについては変更ありませんが、ファイル名とクラス名について大幅な修正をかけていきます。   クラス名の重複回避 まず、クラス名の重複についてです。状態異常・状態変化の子クラスでは重複回避のために接頭語を着けて管理していましたが、他にも重複...

ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか
プログラミング
amazon,AWS,Honeycode,NoCode,プログラミング学習
ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか

  近年、プログラミングの需要は増え勢いを増していますが、それ以上にノーコードというソースコードを打たなくでもアプリ開発ができるというソフトウェアやプラットフォームが普及してきました。 これにより一部の期待感とは別に、プログラマーという職業は今後不要になるのではないかと危機感を抱く人が出て...

PHPポケモン「バトルシステム実装編〜タイプ相性の判定〜」デモ&配布有り 19
プログラミング
jQuery,PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜タイプ相性の判定〜」デモ&配布有り 19

  システムを組むなら、仕様書や設計書はしっかり作りましょう。   ということで、またまたフォルダ移動やページ分けなどを見えないところでやりました。正直説明すると全く進まなくなりそうなので、改修部分は必要最低限にします。 結論、説明しません。(コード配布するので許してください)   そして今...

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

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

CSSとの意外な関係「よくわかるSEO対策」スタイルシート編
SEO対策
CSS,スタイルシート,レンダリング
CSSとの意外な関係「よくわかるSEO対策」スタイルシート編

   今回の「よくわかるSEO対策」はスタイルシート(CSS)編です。   多くの人が 「SEO対策なのに、CSSの説明をするの?」 と思うかも知れませんが、これには意外な関係性があったのです。   現在CSSを学んでいる人、そしてCSSの書き方ならマスターしているといった人でも、SEOのことまでを考慮した記述ができて...

カテゴリ

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