こんにちは!
スマレジ・テックファームのWebエンジニアやまてと申します。
はじめに
今回から「CLIで操作するブラックジャックゲームをPHPで作ってみる」という題目で、トータルで何回になるかわかりませんが、完成までの道のりを投稿していきたいと思います。
今回は「①制作物の確認」をします。
この課題は、『独学エンジニア』というWeb開発(主にサーバーサイド)の動画学習教材の課題です。
2020年8月にこの教材と出会って、丸2年、動画や課題での学習を続けています。
独学エンジニアは今も未完成の超大作の教材で、私は全幅の信頼を寄せていて、この教材に出会ったおかげで未経験からWebエンジニアに独学で転職できたと思っています。
また、転職後の今もなお受講している理由は、実務3年までに身につけておきたいレベルを想定して教材を作成されているそうなので、この教材とじっくり向き合うことで実務3年までに身につけておきたいことは全て身につけたいと思っているためです。
記事を書く目的
試行錯誤含め作成過程を全てアウトプットして、自分の思考を整理するとともに、作成過程を復習していくためです。
完成するまでの過程はボロボロだとしても、出来上がったものが満足のいく制作物になるよう、これまで学んできたことを出し切って、まだわからないことも吸収しつつ進んでいこうと思います。
INDEX
課題内容
「ブラックジャックゲームを作ろう」という今回の課題は、PART3「PHPとオブジェクト指向」の集大成の課題です。
受講生が自力で臨むために、回答例は用意されていません。
環境
1. 制作するもの
以下のとおり、ブラックジャックゲームの基本的なルールに沿って、そのとおり作っていくことになります。
ブラックジャックはカジノで行われるカードゲームの一種です。
1〜13までの数が書かれたカード52枚を使ってゲームが行われます。ルールは次の通りです。
- 実行開始時、ディーラーとプレイヤー全員に2枚ずつカードが配られる
- 自分のカードの合計値が21に近づくよう、カードを追加するか、追加しないかを決める
- カードの合計値が21を超えてしまった時点で、その場で負けが確定する
- プレイヤーはカードの合計値が21を超えない限り、好きなだけカードを追加できる
- ディーラーはカードの合計値が17を超えるまでカードを追加する
各カードの点数は次のように決まっています。
- 2から9までは、書かれている数の通りの点数
- 10,J,Q,Kは10点
- Aは1点あるいは11点として、手の点数が最大となる方で数える
このゲームには何人かのプレイヤーがおり、カードの合計値を競います。
このように、完成形は決まっており、「どのようなものを作るか」については考えることはありません。
ステップも課題として与えられており、以下のとおり4ステップです。
◯ステップ1
ディーラーとプレイヤーの2人で対戦するコンソールゲームを作成しましょう。
以下のルールの元、コンソール(ターミナル)上で動作するようにします。
- プレイヤーは実行者、ディーラーはCPUが自動実行する
- 実行開始時、プレイヤーとディーラーはそれぞれ、カードを2枚引く。引いたカードは画面に表示する。ただし、ディーラーの2枚目のカードは分からないようにする
- その後、先にプレイヤーがカードを引く。プレイヤーのカードの合計値が21を超えたらプレイヤーの負け
- プレイヤーはカードを引くたびに次のカードを引くか選択できる
- プレイヤーがカードを引き終えたら、ディーラーは自分のカードの合計値が17以上になるまで引き続ける
- プレイヤーとディーラーが引き終えたら勝負。カードの合計値が21により近い方が勝ち
- Aは1点として取り扱う
コンソール画面のイメージです。
ブラックジャックを開始します。 あなたの引いたカードはハートの7です。 あなたの引いたカードはクラブの8です。 ディーラーの引いたカードはダイヤのQです。 ディーラーの引いた2枚目のカードはわかりません。 あなたの現在の得点は15です。カードを引きますか?(Y/N) Y あなたの引いたカードはスペードの5です。 あなたの現在の得点は20です。カードを引きますか?(Y/N) N ディーラーの引いた2枚目のカードはダイヤの2でした。 ディーラーの現在の得点は12です。 ディーラーの引いたカードはハートのKです。 あなたの得点は20です。 ディーラーの得点は22です。 あなたの勝ちです! ブラックジャックを終了します。
◯ステップ2
Aを1点あるいは11点のどちらかで扱うようにプログラムを修正しましょう。
Aはカードの合計値が21以内で最大となる方で数えるようにします。
◯ステップ3
最大3人までのプレイヤーでプレイできるようにしましょう(ディーラーと合わせて合計4人)。増えたプレイヤーはCPUが自動的に操作します。
◯ステップ4(任意)
ダブルダウン、スプリット、サレンダーのルールを追加しましょう。ルールは各自調べてみてください。
2. 制作過程のルール
あとは実装する際のルールについて、下記のとおり設定されています。
なお、実装する際には次の点を守るようにしてください。
テストを先に書きながら進めましょう。
最初に全てのテストを用意するのではなく、今実装したい機能のテストを先に書いてからその機能を実装する形で進めてください(テストもどんどん修正してOKです)
静的解析ツールは一通り通る状態にしておきましょう
- 変更しづらかったり読みづらい箇所は何度もリファクタリングしましょう
PHPUnit での自動テスト
テストには、PHPUnitを使います。
https://phpunit.readthedocs.io/ja/latest/#phpunit.readthedocs.io
テストを書きながら進める、という点について、ここまで動画講義と課題を進めていく中でも、なかなか身に付きませんでした。気づいたらテストが徐々に後で書くようになっていき、終いには実装ができた後にテストを書いている状態になっていきます…
今回こそ、なるべくテストを先に書こうとしながら取り組みます。
静的解析ツール の利用
静的解析ツールは、講義の中で学んできた、以下の3つを通る状態にします。
- PHP_CodeSniffer
コーディング規約に則ってコードをかけているかをチェックしてくれます。
- PHPMD
PHPMDは、考えられるバグや最適でないコード、複雑なコード、未使用のパラメーター、メソッド、プロパティなど、問題のありそうなコードを検知して教えてくれるツールで、良いコードに近づけてくれます。
- PHPStan
こちらもバグを見つけてくれるツールです。
リファクタリング
リファクタリングについては、読みやすいコードになるよう試行錯誤して、臆さず修正しまくろうと思います。
3. その他
その他、講義で学んできたことを全部取り入れていきたいため、下記について、利用したり、則っていけたらと思います。
Git / GitHub の利用
自分だけでの実装ですが、ブランチ作成、コード変更、プルリク、マージしながら(GitHub flow )、進めます。
デバッグツール Xdebug の利用
また、VSCodeの拡張機能として導入した、Xdebug でステップ実行してデバッグしながらコーディングします。
UMLの利用
UMLはコードを書き始めるまでに、 下記の3つを PlantUML で書きます。
- ユースケース図
- クラス図
- シーケンス図
余談ですが、覚えたての Mermaid を使う機会を窺っていますが、今回は PlantUML で描き始めていたのでまたの機会にします。
SOLID原則
SOLID原則は下記の5つの原則ですが、それぞれをチェック項目として、ステップを進めていく中で、SOLID原則に則っているかどうか確認していきたいと思います。則っていない場合は、コードを書き換えていきます。
- 単一責任の原則
- オープン・クローズドの原則
- リスコフの置換原則
- インターフェース分離の原則
- 依存性逆転の原則
デザインパターンの利用
講義中に学んだデザインパターンは以下の3つです。
- Adapter パターン
- Abstract Factory パターン
- Composite パターン
現状この3つのみ知っている(理解は進んでいない)ため、少なくとも、使えるパターンがないかを見比べて、導入できそうな箇所がないか照合してみたいと思います。そうすることで、デザインパターンの理解を進めたいと思います。
なお、言語フレームワークは使いません。
また、Docker環境は構築せず、動画講座で使用したものをそのまま使います。
おわりに
今回は「CLIで操作するブラックジャックゲームをPHPで作ってみる」という題目での投稿の第一回として、課題の内容と、制作過程でのルール、チェックの観点として押さえておきたい点をまとめました。
完成までの道のりを進捗に合わせて投稿していきたいと思います。
今回の記事は以上です!
ありがとうございました。
あー!#独学エンジニア でサーバーサイドエンジニアの学習して、 #スマレジ のテックファームに転職した身としてはスクショしたくなる胸熱な広告!… pic.twitter.com/7SVrN1LeRR
— やまて|Webエンジニア2年目 (@r_yamate) 2022年4月3日
独学エンジニアで学習していることを弊社人事に伝えたら、しばらくしたら広告貼ってあっていろいろ驚きました。笑
独学エンジニアで学習 → スマレジテックファーム に就職、は実務未経験からエンジニア転職するルートとしては、自分の中では結果的に最良だったと思っています。