概要
LaravelのToy problemとして、簡単なじゃんけんのアプリケーションを作る。
- 初期画面にRock/Paper/Scissorsの3つのラジオボタンと”Match!”ボタンを表示
- ユーザーがラジオボタンのいずれかを選択して”Match!”ボタンを押すと、コンピューター側の手をランダムに発生させて勝敗比較
- ユーザー/コンピューターの名前と手、結果を表示に加えて再表示
ユーザー、コンピューターのオブジェクトを生成するPlayer
クラスを作成する。
また、手の値のバリデーションは行っていない。
Playerクラス
ユーザー/コンピューターに関わらず、プレーヤーの名前と現在の手(Rock/Paper/Scissors)を保持し、勝ち負け・あいこの判定機能を備えるクラス。
クラスファイルはpublic下のサブディレクトリ―に置く
- クラスファイルの配置は
public/rock_paper_scissors/Player.php
- コントローラーなどからアクセスする場合、
public_path()
を使う
クラスの仕様は以下の通り。
- 名前空間を含むフルパスのクラス名は
rock_paper_scissors\Player
- このクラスからユーザーとコンピューターそれぞれのインスタンスを生成
Player
のプロパティーは名前($name
)とじゃんけんの手($hand_number
)$hand_number
は0:rock
、1:paper
、2:scissors
に対応$hand_number
は外部からpublic
メソッドで設定$hand_number
に対応した手の名称をクラス定数の配列として準備し、現在の手の名前を返すメソッドを準備- 自身が他の
Player
に対して勝っているか(wins)、あいこか(draws)を判定するメソッドをそれぞれ準備
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?php // 名前空間を定義 namespace rock_paper_scissors; /** * じゃんけんのプレーヤーのクラス */ class Player { /** @var array 手の数値(0, 1, 2)に対応したじゃんけんの手の名称 */ const HANDS = ['Rock', 'Paper', 'Scissors']; /** @var string プレーヤーの名前 */ private $name; /** @var int じゃんけんの手の数値(0, 1, 2) */ private $hand_number; /** * コンストラクターでプレーヤーの名前を指定する。 * * @param string $name プレーヤーの名前 */ public function __construct($name) { $this->name = $name; // 手の数値の初期値はnull $hand_number = null; } /** * プレーヤーの名前を返す。 * * @return string プレーヤーの名前 */ public function getName() { return $this->name; } /** * 現在設定されている手の文字列表現を返す。 * * @return string $hand_numberプロパティーの値に対応したHANDSの要素文字列。 * 手が未設定の場合はnull。 */ public function getHand() { if (isset($this->hand_number)) { return self::HANDS[$this->hand_number]; } else { return null; } } /** * 手の値(0, 1, 2)をプロパティーにセットする。 */ public function setHandNumber($hand_number) { $this->hand_number = $hand_number; } /** * プレーヤーが引数のプレーヤーに勝っているかどうかを判定する。 * * @return boolean ユーザーが引数のユーザーに勝っていればtrue、負けていればfalse */ public function wins($other) { // 0:Rock, 1:Paper, 2:Scissorsの勝つパターンをチェック if ($this->hand_number === 0 && $other->hand_number === 2 || $this->hand_number === 1 && $other->hand_number === 0 || $this->hand_number === 2 && $other->hand_number === 1) { return true; } else { return false; } } /** * プレーヤーが引数のプレーヤーとあいこになっているかどうかを判定する。 * * @return boolean ユーザーが引数のユーザーとあいこならtrue、そうでなければfalse */ public function draws($other) { return $this->hand_number === $other->hand_number ? true : false; } } |
ルーティング
ルーティングはGETメソッドとPOSTメソッドに対応して2つ。
1 2 |
Route::get('rock_paper_scissors', 'MyController@rockPaperScissors'); Route::post('rock_paper_scissors', 'MyController@rockPaperScissorsMatch'); |
コントローラー
コントローラーのアクションは、GETに対する初期ページへの遷移と、POSTに対する処理・遷移の2つ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; // 名前空間の指定 use \rock_paper_scissors\Player; class MyController extends Controller { // GETメソッドに対して初期ページへ遷移 public function rockPaperScissors() { return view('assignments.rock_paper_scissors'); } // POSTメソッドに対して手の設定、勝敗判定をし、結果ページへ遷移 public function rockPaperScissorsMatch(Request $request) { // プレーヤークラスを使う require public_path('rock_paper_scissors/Player.php'); // コンピューターとユーザーの名前を設定 $computer = new Player('COM'); $user = new Player('USER'); // コンピューターの手は乱数で設定 $computer->setHandNumber(random_int(0, 2)); // ユーザーの手はフォーム入力から得る $user->setHandNumber((int)$request->hand); // コンピューターとユーザーのオブジェクトを渡してビューに遷移 $vars = [ 'computer' => $computer, 'user' => $user, ]; return view('assignments.rock_paper_scissors', $vars); } } |
ビュー
GETの場合はフォームだけ表示し、POSTでじゃんけんを実行したときには結果も表示する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>じゃんけん</title> </head> <body> <h1>Rock-Paper-Scissors</h1> {{-- ユーザーの手を選択するフォーム/初期状態でRockを選択 --}} <form method="post"> @csrf <p> <label><input type="radio" name="hand" value="0" checked="checked">Rock</label> <label><input type="radio" name="hand" value="1">Paper</label> <label><input type="radio" name="hand" value="2">Scissors</label> </p> <input type="submit" value="Match!"> </form> <hr> {{-- POSTの場合の勝敗判定表示。 GETの場合は$userインスタンスが生成されていないのでこのブロックはスルー。 --}} @if (isset($user)) <h2>User</h2> <ol> <li>Name: {{ $user->getName() }}</li> <li>Hand: {{ $user->getHand() }}</li> </ol> <h2>Computer</h2> <ol> <li>Name: {{ $computer->getName() }}</li> <li>Hand: {{ $computer->getHand() }}</li> </ol> <h2>Result</h2> @if ($user->draws($computer)) <p>Draw</p> @elseif (($user->wins($computer))) <p>User won</p> @else <p>Computer won</p> @endif @endif </body> </html> |
実行結果
初期表示
Rock-Paper-Scissors
結果表示
Rock-Paper-Scissors
User
- Name: USER
- Hand: Rock
Computer
- Name: COM
- Hand: Paper
Result
Computer won