プログラミング

PHPポケモン「2進化ポケモン実装編」8

PHP PHPポケモン プログラミング学習 ポケモン
PHPポケモン「2進化ポケモン実装編」8

 

記念すべき?第8回目で遂にタイトル変更です。

(旧)ピカチュウから学ぶオブジェクト指向

(新) PHPポケモン

 

機能増設によりオブジェクト指向云々より、PHP学習がメインになったので泣く泣く変更です。(今の所)順調に続いているのも、多くの方?が見てくれているおかげです。感謝感激雨アレレということで、感謝の気持を込めて最後にはGitHubさんよりサンプルコードを配布しているので、ぜひ最後まで読んでからダウンロードしてやってください。

 

コードの説明については、第1回からできるだけわかりやすく説明をしているので、今回始めての人はぜひご参考ください。

ピカチュウから学ぶオブジェクト指向 〜入門編〜 1 ピカチュウから学ぶオブジェクト指向 〜入門編〜 1

オブジェクト指向とは  オブジェクト指向プログラミング https://ja.wikipedia.org/wiki/オブジェクト指向プログラミング オブジェクト指向プログラミングとは、互いに密接な関連性を持つデータとメソッドをひとつにまとめてオブジェクトとし、それぞれ異なる性質と役割を持たせたオブジェクトの様々な定...

 

今回は「2進化ポケモン実装編」です。今までピカチュウだけに頼っていましたが、新たに3匹増えるということもあって、ディレクトリ構造を大幅に変更しています。読み込み方法も少し変更したので、以下参考にしながら進めて行きましょう。

 

新たなディレクトリ構造

 

読み込み方法
require_once(__DIR__.'【記述ファイルからの相対パス※頭にスラッシュ有り】');

 

一旦上記の構造で進めていきます。公開ディレクトリだのアクセス制限が気になる人はもっとキレイに配置するかフレームワークでも使いましょう。

 

2進化ポケモンの実装

ピカチュウのおかげである程度機能が整ったので、今回は新たにポケモンを増やします。その映えある第1号に選ばれたのが、全国図鑑最上位に君臨するカエル三兄弟ことフシギダネさん一家です。

前回進化のシステムを導入したので、最終進化までセットで加えていきます。ステータスに関しては、ピカチュウ一家と同じく以下のデータを参考にします。 

種族値 → 執筆時段階での最新シリーズ

覚える技 → 初代

 

ポケモンの追加

 それでは、進化前のフシギダネから順に追加していきます。ピカチュウのクラスを参考にしながら、フシギダネのクラスを作成しましょう。

 

フシギダネ(/Classes/Pokemon/Fushigidane.php
<?php

require_once(__DIR__.'/../Pokemon.php');
require_once(__DIR__.'/Fushigisou.php');
 
// フシギダネ
class Fushigidane extends Pokemon
{
 
    /**
    * 正式名称
    * @var string(min:1 max:5)
    */
    protected $name = 'フシギダネ';
 
    /**
    * 初期レベル
    * @var array
    */
    protected $default_level = [
        5
    ];
 
    /**
    * レベルアップで覚える技
    * @var array
    */
    protected $level_move = [
        [1, 'たいあたり'],
        [1, 'なきごえ'],
        [7, 'やどりぎのタネ'],
        [13, 'つるのムチ'],
        [20, 'どくのこな'],
        [27, 'はっぱカッター'],
        [34, 'せいちょう'],
        [41, 'ねむりごな'],
        [48, 'ソーラービーム'],
    ];
 
    /**
    * 種族値
    * @var array
    */
    protected $base_stats = [
        'HP' => 45,
        'こうげき' => 49,
        'ぼうぎょ' => 49,
        'とくこう' => 65,
        'とくぼう' => 65,
        'すばやさ' => 45,
    ];
 
    /**
    * インスタンス作成時に実行される処理
    *
    * @return void
    */
    public function __construct()
    {
        $this->setLevel();
        $this->setDefaultExp();
        $this->setDefaultMove();
        $this->setIv();
        echo '<p>フシギダネをゲットした</p>';
    }
 
    /**
    * 進化 → フシギソウ
    *
    * @return Classes\Pokemon\Fushigisou
    */
    public function evolve()
    {
        return new Fushigisou($this);
    }
 
}

※ポケモンの名前を英語で統一させようと考えていましたが、フシギダネの英語名は「Bulbasaur」で、増えていくと絶対に判別できなくなると判断したので断念しました

 

フシギソウはまだ作成していませんが、作成する前提でプログラムを組んでいきます。

 

親コンストラクタの活用 

フシギダネのクラスを作りましたが、1点気になる箇所がありますね。それはコンストラクタ(__construct)の処理です。

/**
* インスタンス作成時に実行される処理
*
* @return void
*/
public function __construct()
{
    $this->setLevel();
    $this->setDefaultExp();
    $this->setDefaultMove();
    $this->setIv();
    echo '<p>フシギダネをゲットした</p>';
}

 

インスタンス化した際の一連の処理は、基本的に全ポケモン共通です。進化の分岐はありますが、同じ処理はできる限りまとめて置くほうが保守性は高まります。なので、親クラスであるポケモンクラス(Pokemon)のコンストラクタを活用します。

 

ポケモン(/Classes/Pokemon.php
/**
* インスタンス作成時に実行される処理
*
* @return void
*/
public function __construct()
{
    $this->setLevel();
    $this->setDefaultExp();
    $this->setDefaultMove();
    $this->setIv();
    echo '<p>'.$this->name.'をゲットした</p>';
}

 

もし子クラスにコンストラクタがなく、親のコンストラクタが存在している場合は、親のコンストラクタが呼び出されます。もしどちらも記述されている場合は、子が優先されます。

なので、基本的には親のコンストラクタを使用、例外処理が必要になるポケモンに関しては子のコンストラクタを使用しましょう。

コンストラクタ(PHP.net)

子クラスがコンストラクタを有している場合、親クラスのコンストラクタが 暗黙の内にコールされることはありません。

  

進化前の判定

進化についても、基本的な処理は同じです。なので親であるポケモンのコンストラクタで分岐させるのが好ましいですね。そのためには、正しい進化元かどうかを判別するためのプロパティが必要になります。進化ポケモンのクラスにchild_classというプロパティを追加しましょう。以下、フシギソウ(Fushigisou)のクラスです。

 

フシギソウ(/Classes/Pokemon/Fushigisou.php
<?php

require_once(__DIR__.'/../Pokemon.php');
require_once(__DIR__.'/Fushigibana.php');
 
// フシギソウ
class Fushigisou extends Pokemon
{
 
    /**
    * 正式名称
    * @var string(min:1 max:5)
    */
    protected $name = 'フシギソウ';
 
    /**
    * 進化前(クラス名)
    * @var string
    */
    protected $child_class = 'Fushigidane';
 
    /**
    * 初期レベル
    * @var array
    */
    protected $default_level = [
        16
    ];
 
    /**
    * レベルアップで覚える技
    * @var array
    */
    protected $level_move = [
        [1, 'たいあたり'],
        [1, 'なきごえ'],
        [1, 'やどりぎのタネ'],
        [7, 'やどりぎのタネ'],
        [13, 'つるのムチ'],
        [22, 'どくのこな'],
        [30, 'はっぱカッター'],
        [38, 'せいちょう'],
        [46, 'ねむりごな'],
        [54, 'ソーラービーム'],
    ];
 
    /**
    * 種族値
    * @var array
    */
    protected $base_stats = [
        'HP' => 60,
        'こうげき' => 62,
        'ぼうぎょ' => 63,
        'とくこう' => 80,
        'とくぼう' => 80,
        'すばやさ' => 60,
    ];
 
    /**
    * 進化 → フシギソウ
    *
    * @return Classes\Pokemon\Fushigibana
    */
    public function evolve()
    {
        return new Fushigibana($this);
    }
 
}

 

それでは新しく追加したプロパティを見てみましょう。

/**
* 進化前(クラス名)
* @var string
*/
protected $child_class = 'Fushigidane';

 

フシギソウの進化前はフシギダネです。そして判別するためにはクラス名が必要になるので、フシギダネのクラス名である「Fushigidane」をセットしています。前回作成したライチュウには「Pikachu」をセットしておきましょう。

 

次に、ポケモンクラスのコンストラクタ内に進化の判定を追加します。

 

ポケモン(/Classes/Pokemon.php
/**
* インスタンス作成時に実行される処理
*
* @param object|null
* @return void
*/
public function __construct($before=null)
{
    // 進化前のポケモンと一致しているかチェック
    if(is_a($before, $this->child_class ?? null)){
        // 進化した際の処理
        $this->takeOverAbility($before);
        echo '<p>'.$this->name.'に進化した</p>';
    }else{
        // 捕まえた際の処理
        $this->setLevel();
        $this->setDefaultExp();
        $this->setDefaultMove();
        $this->setIv();
        echo '<p>'.$this->name.'をゲットした</p>';
    }
}

 

変更された条件分岐の部分を見てみましょう。

if(is_a($before, $this->child_class ?? null)){

 

is_a(クラスの判定)の第2引数(クラス名)に、先程追加したchild_classのプロパティを指定しています。これで、現在インスタンスを呼び出されてたポケモンが$beforeで受け取ったポケモンと一致しているかを判定しています。

ただし、ピカチュウやフシギダネは進化前を持たないため、プロパティを設定する必要ありません。その判定用としてNull合体演算子を使用して、なければnullをセットする仕様にしています。

【PHP7】はてな2つとは??Null合体演算子を使った存在チェック 【PHP7】はてな2つとは??Null合体演算子を使った存在チェック

  PHP Notice:  Undefined variable: 変数名 in /***/***.php on line 2   PHPで変数や対象のキーが存在しない配列を使おうとすれば、上記のようなエラーが吐き出されますね。PHP5.6までは初期値を設定したり、issetで判定したりしてそれを回避していましたが、2015年末にリリースされたPHP7からは新しくN...

 

これで進化時の判定を追加することができました。残りのフシギバナのクラスを作成して、出力をしてみましょう。

 

フシギバナ(/Classes/Pokemon/Fushigibana.php
<?php

require_once(__DIR__.'/../Pokemon.php');
 
// フシギバナ
class Fushigibana extends Pokemon
{
 
    /**
    * 正式名称
    * @var string(min:1 max:5)
    */
    protected $name = 'フシギバナ';
 
    /**
    * 進化前(クラス名)
    * @var string
    */
    protected $child_class = 'Fushigisou';
 
    /**
    * 初期レベル
    * @var array
    */
    protected $default_level = [
        32
    ];
 
    /**
    * レベルアップで覚える技
    * @var array
    */
    protected $level_move = [
        [1, 'たいあたり'],
        [1, 'なきごえ'],
        [1, 'やどりぎのタネ'],
        [1, 'つるのムチ'],
        [7, 'やどりぎのタネ'],
        [13, 'つるのムチ'],
        [22, 'どくのこな'],
        [30, 'はっぱカッター'],
        [43, 'せいちょう'],
        [55, 'ねむりごな'],
        [65, 'ソーラービーム'],
    ];
 
    /**
    * 種族値
    * @var array
    */
    protected $base_stats = [
        'HP' => 80,
        'こうげき' => 82,
        'ぼうぎょ' => 83,
        'とくこう' => 100,
        'とくぼう' => 100,
        'すばやさ' => 80,
    ];
 
}

 

出力ファイル(/index.php
<?php
require_once(__DIR__.'/Classes/Pokemon/Fushigidane.php');

// HTML出力用関数
function echoKeyToVal($array)
{
    foreach($array as $key => $val){
        echo '<p>'.$key.':'.$val.'</p>';
    }
}
 
// フシギダネをゲット
$pokemon = new Fushigidane;
echoKeyToVal($pokemon->getDetails());
echoKeyToVal($pokemon->getStats());
 
// フシギソウに進化
$pokemon = $pokemon->evolve();
echoKeyToVal($pokemon->getDetails());
echoKeyToVal($pokemon->getStats());
 
// フシギバナに進化
$pokemon = $pokemon->evolve();
echoKeyToVal($pokemon->getDetails());
echoKeyToVal($pokemon->getStats());
?>

※ステータスや詳細の出力を毎回書くのが面倒になったので、出力用の関数を作成して使用しています

 

# 出力結果
 
フシギダネをゲットした
 
正式名称:フシギダネ
ニックネーム:フシギダネ
現在のレベル:5
覚えている技:たいあたり,なきごえ
現在の経験値:125
次のレベルまでに必要な経験値:91
 
HP:20
こうげき:10
ぼうぎょ:11
とくこう:12
とくぼう:12
すばやさ:9
 
フシギソウに進化した
 
正式名称:フシギソウ
ニックネーム:フシギソウ
現在のレベル:5
覚えている技:たいあたり,なきごえ
現在の経験値:125
次のレベルまでに必要な経験値:91
 
HP:21
こうげき:12
ぼうぎょ:12
とくこう:13
とくぼう:13
すばやさ:11
 
フシギバナに進化した
 
正式名称:フシギバナ
ニックネーム:フシギバナ
現在のレベル:5
覚えている技:たいあたり,なきごえ
現在の経験値:125
次のレベルまでに必要な経験値:91
 
HP:23
こうげき:14
ぼうぎょ:14
とくこう:15
とくぼう:15
すばやさ:13

 

これでフシギダネからフシギバナまで、無事進化することができました。

 

サンプルコードの配布

 第8回終了時点のPHPポケモンのコードをGitHubより配布します。好きにダウンロードして使用してください。

 

コードは毎回終了時に配布するわけではありません。ある程度溜まったら、そのタイミングで終了時点のコードを配布予定です。ぜひ学習用としてお役立てください。

 

まとめ

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

今回のPHPポケモンは「2進化ポケモン実装編」についてご紹介しました。

好きなポケモンがいる人は、試しに追加してみてください。言語を問わず、プログラミングの学習は楽しみながらすることが習得の近道ですので、ぜひ参考にしてくださいね。

 

注目の記事

動画編集に役立つ基本的な考え方【Adobe AfterEffects】
動画編集
Adobe,AfterEffects,PremierePro,YouTube
動画編集に役立つ基本的な考え方【Adobe AfterEffects】

  YouTubeの人気に合わせて、動画編集の需要も高まってきましたが、その大変さから挫折してしまう人も続出しています。 動画編集は奥が深く、技術的な部分に関してはプロのクリエイターであっても自分がよく使うような一部しか把握していないのが普通であり、調べても該当する情報が出てきにくいということもあ...

初心者向けのブログで稼ぐ方法【アフィリエイト編:Google AdSense】
SEO対策
Google AdSense,アフィリエイト,クリック単価,クリック数,ブログ,広告収入
初心者向けのブログで稼ぐ方法【アフィリエイト編:Google AdSense】

  ブログを始めたほとんどの人が アフィリエイトで稼ぎたい   という強い思いを持っているのではないでしょうか。しかし現実は厳しく、広告の審査さえ通らず挫折してしまうといったことは多いです。 中には審査が通っているが、全然広告収入が得られないという人もいるでしょう。 毎日ブログを書いているの...

ポケモンセンター編 PHPポケモン 37
プログラミング
PHP,PHPポケモン,ポケモン
ポケモンセンター編 PHPポケモン 37

ポケモンセンター  バトルシステムを作る関係上、どうしてもダメージを受けることが多くなってきたので、そろそろポケモンセンターを建設(作成)します。 とは言っても、ポケモンセンターに行って交換やらボックス整理などができるわけではなく、ただ回復ポイントを設置するだけの簡単な処理です。   HPの回復 ...

そらをとぶ&あなをほる編 PHPポケモン46
プログラミング
PHP,PHPポケモン,ポケモン
そらをとぶ&あなをほる編 PHPポケモン46

チャージ中の回避技 以前は「ロケットずつき」や「ソーラービーム」をサンプルとしてチャージ技を実装しましたが、今回は少し特別な効果をもったチャージ技を実装します。それが「そらをとぶ」と「あなをほる」です。これらは初代ポケモンでも重宝される技であり、チャージ中に相手からの攻撃を回避することができま...

ピカチュウから学ぶオブジェクト指向 〜ステータス導入編〜 6
プログラミング
PHP,PHPポケモン,オブジェクト指向,ポケモン
ピカチュウから学ぶオブジェクト指向 〜ステータス導入編〜 6

  PHPをピカチュウ(ポケモン)から学ぶ大人気コーナー、第6回目は「ステータス機能の導入編」です。   前回(第5回)で終了段階でのサンプルコードを公開しているので、もし本記事から始める人はぜひそちらを参考にしてください。    ※お詫び   調べたところによると、ポケモンの経験...

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

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

PHPポケモン「オートローダー編」16
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「オートローダー編」16

  今までは技やタイプを一括requireという荒業で対応していましたが、フシギダネ系列の技を実装した際に「こんなん全部読み込んでられるか!」と流石になったので、簡易ながらオートローダーを実装していきます。 そして、実装したらしたで色々と問題も浮かび上がってきたので、このあたりは回を進めて行きなが...

【jQuery】移動式マルチプルフォームの作り方【sortable】
プログラミング
HTML,JavaScript,jQuery,jQuery UI
【jQuery】移動式マルチプルフォームの作り方【sortable】

  移動式マルチプルフォーム       htmlの標準マルチプルフォームは、選択したものに色が付く仕様ですが、数が多くなってくると選択しているものがわかり難いということや、並び順の変更がしにくいという難点があります。そういった条件も込みで再現するような選択要素移動式の...

カテゴリ

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