プログラミング

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進化ポケモン実装編」についてご紹介しました。

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

 

注目の記事

バズる!ビジネスの見つけ方 〜何で起業するか悩んでいませんか?〜
マーケティング
ビジネス,起業
バズる!ビジネスの見つけ方 〜何で起業するか悩んでいませんか?〜

  独立や起業を志している9割以上の人が「何をビジネスにするか?」を悩んでいます しかし、それは負のサイクルです。 起業するためにビジネスを考えるという行為自体が”矛盾している”ということに気づかなければ、このサイクルからは抜け出すことができません。 その結果、行動できずに終わってしまう人は多...

【Laravel】1対1リレーションをわかりやすく解説(belongsTo)
プログラミング
Laravel,PHP
【Laravel】1対1リレーションをわかりやすく解説(belongsTo)

Laravelの1対1リレーションのbelongsToについて、公式マニュアルでは専用単語ばかりでどうしてもわかりにくいと感じてしまっている方へ向けて、わかりやすく解説しました。 ※例で紹介しているコードについては、一部英語を日本語表記で使用している部分もありますので、コピペで使用する方は必要に応じて置き換え...

SEO対策で役立つ!ライティングスキルを向上させる3ステップ
ライティング
SEO,ブログ
SEO対策で役立つ!ライティングスキルを向上させる3ステップ

  ブログやメール、SNSなどライティングスキルが問われる場面が多く、それは質に直結しています。各プラットフォームによって特徴はありますが、基礎的な文章力自体がついていれば多様な場面で役立つことは間違いありません。 文章の質が高くなれば、ブログであればSEOに強い価値のあるサイトになりますし、SNS...

【Laravel】論理削除対応型existsバリデーションの実装方法
プログラミング
Laravel,PHP
【Laravel】論理削除対応型existsバリデーションの実装方法

  Laravelでは多くのバリデーションが提供されていますが、論理削除を使用している場合はそのままでは使えないものが複数あります。 今回は紐付けをする際に存在チェックで使用するexistsのソフトデリート対応のバリデーションを実装する方法をご紹介します。     カスタムバリデーションの追加   存...

ポケモン入れ替え編 PHPポケモン 83
プログラミング
PHP,PHPポケモン,ポケモン
ポケモン入れ替え編 PHPポケモン 83

ポケモンの入れ替え 複数ポケモンの所有、そして並び替えの機能が整ったので、いよいよバトルでのポケモン交代機能を実装します。ポケモンがバトル中に交代する方法は大きく分けて以下の4つです。 プレイヤー操作による交代 ひんしによる交代 相手ポケモンの技による交代 味方ポケモンの技による交代 ...

プレイヤー情報作成編 PHPポケモン72
プログラミング
PHP,PHPポケモン,ポケモン
プレイヤー情報作成編 PHPポケモン72

プレイヤー情報の作成 少し前よりプレイヤーをホーム画面に表示させるようにしましたが、ただイメージとして配置しただけでプレイヤー情報自体は設定していませんでした。なので、今回はプレイヤーとして持たせる必要のある情報を作成していきましょう。   クラスの作成 初代ポケモンではプレイヤー情報として閲...

プログラミングを優しく解説!学んで得する3つの理由
プログラミング
プログラミング教育
プログラミングを優しく解説!学んで得する3つの理由

  プログラミング教育が始まるけど、そもそもよくわかっていない   2020年からは小学校がプログラミング学習が必修化され、翌年には中学校でも導入予定です。 しかし、保護者からすると全くわからず困惑していたり、教える先生たち教師陣からしてもよくわかっていないケースは少なくありません。   今回...

たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは
マーケティング
コロナ,フリーランス,ホームページ制作,助成金
たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは

  仕事の依頼が全然来ない・・・ 営業しても話を聞いてくれない・・・   その多くが営業力以上に、営業をすべきタイミングがわかっていない人がほとんどです。 実は助成金等を活用することで、行政書士などの職業以外でも仕事を受注することは可能になります。   今回は筆者が、たった2日で200万...

カテゴリ

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

タグ

5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach fortify function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jetstream 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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 認証 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力