/log・/sql・/user とエイリアスを if-elsif に足し続けると、1つの関数にルーティング・解析・権限・検証が詰まっていく。単一責任と開放閉鎖の原則に反する点を、コードで確かめる。
受け取ったメッセージを正規表現で解析し、/deploy・/restart・/status を実行する素朴なボットを書く。引数の検証も入れて、50個に増えたらどこが苦しくなるのかを先に見ておく回。
Plack で Slack の Webhook を受け取り、HTTP::Tiny で返信するオウム返しボットを作る。X-Slack-Signature の署名検証でなりすましを防ぐところまでが、全9回の連載の出発点。
Perl と Moo でテキスト RPG の戦闘エンジンを作りながら、Command・State・Strategy・Observer を学ぶ全10回の連載。目次を兼ねた案内板で、読む順と各回の内容をまとめています。
Command は行動、State はフェーズ、Strategy は判断、Observer は通知と、RPG 戦闘の4つの関心事にパターンを1つずつ当てた理由を整理する。SOLID 原則との対応と、ボードゲームAIなど他の場面への応用も扱う最終回。
PlayerTurnState に標準入力を受け付ける処理を足し、1: 攻撃 2: 防御 3: 魔法 4: アイテムを選んで敵と戦う REPL 形式のバトルを完成させる。ここまでのパターンを1つの動くゲームにまとめる回。
ここまでの4つのパターンが、BattleContext を中心にどう連携して1ターンを進めるかを関係図とコードで俯瞰する。プレイヤーの行動は Command、敵の行動は Strategy が決め、結果を Observer が受け取る流れを確かめる。
ダメージ表示や戦闘後の報酬を戦闘ロジックの中に書かず、Subject が attach された購読者へ notify する形にする。BattleLogger・DamageEffect・BattleReward を購読者として足し、戦闘側のコードは変えずに反応を増やす。
毎ターン攻撃するだけの敵を、AIStrategy ロールを実装した AggressiveAI・DefensiveAI などに分けて差し替えられるようにする。HP が半分以下なら回復を優先する防御的AIなど、敵ごとの性格を戦闘コードに触れず変えられる。
戦闘開始 → プレイヤーターン → 敵ターン → 戦闘終了の流れを、BattleState ロールと BattleContext で状態遷移として整理する。フェーズごとの enter / execute / exit に処理を分け、ターンの切り替えを一か所で扱う。
if/elsif で選んでいた行動を、Moo::Role で execute を要求する Command オブジェクトにまとめ直す。攻撃・防御・アイテムをコマンドとして作り、行動を足しても選択側のコードを書き換えなくて済む形にする。
プレイヤーの選択を if/elsif で行動クラスに振り分け、魔法 (ファイアボール・ブリザード・サンダー) とアイテム (ポーション・ハイポーション・エリクサー) を足していく。分岐が伸びて、なぜ直したくなるのかを実コードで体験する回。
攻撃・防御・アイテム使用を Character に足し続けるとクラスが膨らむので、行動ごとに Action クラスを作って Character から切り出す。防御フラグや回復量の上限 (max_hp) の扱いも Moo のコードで見る。
Moo で Character クラスを作り、勇者とスライムが交互に殴り合ってどちらかが倒れるまでのターン制戦闘ループを書く。全10回の連載の出発点で、最後に作る対話型バトルの完成イメージも示す。
Perl で天気 API を呼ぶところから始め、Adapter と Facade で複数 API をまとめる全8回の連載。目次を兼ねた案内板で、読む順と各回の内容をまとめています。