Skip to content

Commit

Permalink
Merge pull request #11 from ryamate/feature-step3-solid
Browse files Browse the repository at this point in the history
Feature step3 solid
  • Loading branch information
ryamate committed Aug 22, 2022
2 parents 8e65046 + 0141d07 commit dac127a
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 243 deletions.
2 changes: 1 addition & 1 deletion src/.phpunit.result.cache

Large diffs are not rendered by default.

111 changes: 59 additions & 52 deletions src/docs/class.plantuml
Expand Up @@ -3,6 +3,7 @@
class Game {
-array<int,Player> players
-Dealer dealer

+__construct()
+play()
-set()
Expand All @@ -12,40 +13,37 @@ class Game {
-end()
}

class Message {
+getSettingMessage()
+getInputNumOfPlayerMessage()
+getSettingInputErrorMessage()
+getStartMessage()
+getFirstHandMessage()
+getDealerFirstHandMessage()
+getLoseByBurstMessage()
+getProgressMessage()
+getProgressQuestionMessage()
+getCardDrawnMessage()
+getInputErrorMessage()
+getScoreTotalResultMessage()
+getStandMessage()
+getDealerBurstMessage()
+getWinByBurstMessage()
+getResultMessage()
+getEndMessage()
class Deck {
-array<int,array<string,int|string>> deck

+__construct()
+getDeck()
+initDeck()
+takeACard()
}

class Card {
-CARD_SCORE

-array suits
+createNewDeck()
}

class Player {
abstract Player {
-string name
-array<int,array<string,int|string>> hand
-int scoreTotal
-int countAce
-string status

+{abstract} action()
+{abstract} selectHitOrStand()

+__construct()
+getName()
+getHand()
+getScoreTotal()
+getCountAce()
+getStatus()
+action()
#selectHitOrStand()
+addACardToHand()
+calcScoreTotal()
-calcAceScore()
Expand All @@ -54,52 +52,61 @@ class Player {

class Dealer {
-NUM_OF_FIRST_HAND
-string name
-array hand
-int scoreTotal
-int countAce
-string status
-Deck deck
+__construct()

+dealOutFirstHand()
+dealOneCard()
+checkBurst()
+judgeWinOrLose()
-hasStand()
-compareScoreTotal()

+action()
+selectHitOrStand()
}

class NonPlayerCharacter {
#selectHitOrStand()
class ManualPlayer {
+action()
+selectHitOrStand()
}

class Deck {
-array<int,array<string,int|string>> deck
+__construct()
+getDeck()
+initDeck()
+takeACard()
class AutoPlayer {
+action()
+selectHitOrStand()
}

class Card {
-CARD_SCORE
-array suits
+createNewDeck()
class Message {
+getSettingMessage()
+getInputNumOfPlayerMessage()
+getSettingInputErrorMessage()

+getStartMessage()
+getFirstHandMessage()
+getDealerFirstHandMessage()
+getLoseByBurstMessage()

+getProgressMessage()
+getProgressQuestionMessage()
+getCardDrawnMessage()
+getInputErrorMessage()

+getScoreTotalResultMessage()
+getStandMessage()
+getDealerBurstMessage()
+getWinByBurstMessage()
+getResultMessage()

+getEndMessage()
}

Game -- Player
Game -- NonPlayerCharacter
Game -- Deck
Deck *-- Card
Game -- Dealer
Game -- Message
Message -- Player
Message -- Dealer
Dealer -- Player
Dealer -- Deck
Deck -- Card

Player <|-- Dealer
Player <|-- NonPlayerCharacter
Game -- ManualPlayer
Game -- AutoPlayer
Dealer --|> Player
ManualPlayer --|> Player
AutoPlayer --|> Player
Game --- Message


@enduml
57 changes: 57 additions & 0 deletions src/lib/AutoPlayer.php
@@ -0,0 +1,57 @@
<?php

namespace Blackjack;

require_once('Player.php');

use Blackjack\Player;

/**
* ノンプレイヤーキャラクタークラス
*/
class AutoPlayer extends Player
{
/**
* 選択したアクション(ヒットかスタンド)により進行する
*
* @param Deck $deck
* @param Dealer $dealer
* @return void
*/
public function action(Deck $deck, Dealer $dealer): void
{
$message = '';
while ($this->getStatus() === 'hit') {
echo Message::getProgressMessage($this);
echo Message::getProgressQuestionMessage();
$inputYesOrNo = $this->selectHitOrStand();

if ($inputYesOrNo === 'Y') {
$dealer->dealOneCard($deck, $this);
$dealer->checkBurst($this);
$message = Message::getCardDrawnMessage($this);
} elseif ($inputYesOrNo === 'N') {
$this->changeStatus('stand');
$message = PHP_EOL;
}
echo $message;
}
}

/**
* ヒットかスタンドを Y/N で選択する(カードの合計値が17以上になるまで引き続ける)
*
* @return string $inputYesOrNo
*/
public function selectHitOrStand(): string
{
if ($this->getScoreTotal() < 17) {
$inputYesOrNo = 'Y';
echo 'Y' . PHP_EOL;
} else {
$inputYesOrNo = 'N';
echo 'N' . PHP_EOL;
}
return $inputYesOrNo;
}
}
53 changes: 15 additions & 38 deletions src/lib/Dealer.php
Expand Up @@ -2,66 +2,41 @@

namespace Blackjack;

require_once('Player.php');
require_once('Deck.php');
require_once('Player.php');

use Blackjack\Player;
use Blackjack\Deck;
use Blackjack\Player;

class Dealer extends Player
{
private const NUM_OF_FIRST_HAND = 2;

/**
* コンストラクタ
*
* @param string $name プレイヤー名
* @param array<int,array<string,int|string>> $hand 手札
* @param int $scoreTotal プレイヤーの現在の得点
* @param int $countAce プレイヤーの引いた A の枚数
* @param string $status プレイヤーの状態
* @param Deck $deck
*/
public function __construct(
private string $name,
private array $hand = [],
private int $scoreTotal = 0,
private int $countAce = 0,
private string $status = 'hit',
private ?Deck $deck = null,
) {
parent::__construct($name, $hand, $scoreTotal, $countAce, $status);
$this->deck = $deck ?? new Deck();
$this->deck->initDeck();
}

/**
* 初めの手札2枚を配る
*
* @param Deck $deck
* @param Player $player
* @return Player $player
*/
public function dealOutFirstHand(Player $player): Player
public function dealOutFirstHand(Deck $deck, Player $player): void
{
for ($i = 1; $i <= self::NUM_OF_FIRST_HAND; $i++) {
$player = $this->dealOneCard($player);
$this->dealOneCard($deck, $player);
}
return $player;
}

/**
* カードを1枚配る(デッキからカードを1枚引いて、プレイヤーの手札に加える)
*
* @param Deck $deck
* @param Player $player
* @return Player $player
*/
public function dealOneCard(Player $player): Player
public function dealOneCard(Deck $deck, Player $player): void
{
$cardDrawn = array_slice($this->deck->getDeck(), 0, 1);
$this->deck->takeACard();
$cardDrawn = array_slice($deck->getDeck(), 0, 1);
$deck->takeACard();
$player->addACardToHand($cardDrawn);
$player->calcScoreTotal();
return $player;
}

/**
Expand All @@ -82,15 +57,16 @@ public function checkBurst(Player $player): bool
/**
* 勝敗を判定する
*
* @param Deck $deck
* @param array<int,Player> $players
* @return void
*/
public function judgeWinOrLose(array $players): void
public function judgeWinOrLose(Deck $deck, array $players): void
{
echo Message::getStandMessage($this);

if ($this->hasStand($players)) {
$this->action($this);
$this->action($deck, $this);

$messages = [];
$messages[] = Message::getScoreTotalResultMessage($this);
Expand Down Expand Up @@ -159,18 +135,19 @@ private function compareScoreTotal(Player $player): string
/**
* 選択したアクション(ヒットかスタンド)により進行する
*
* @param Deck $deck
* @param Dealer $dealer
* @return void
*/
public function action(Dealer $dealer): void
public function action(Deck $deck, Dealer $dealer): void
{
$message = '';
while ($this->getStatus() === 'hit') {
echo Message::getProgressMessage($dealer);
$inputYesOrNo = $this->selectHitOrStand();

if ($inputYesOrNo === 'Y') {
$dealer->dealOneCard($dealer);
$dealer->dealOneCard($deck, $dealer);
$dealer->checkBurst($dealer);
$message = Message::getCardDrawnMessage($dealer);
} elseif ($inputYesOrNo === 'N') {
Expand Down

0 comments on commit dac127a

Please sign in to comment.