Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CardFramework/AiPlayer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace SoftwareDesign\CardFramework;

include_once __DIR__ . "/Autoload.php";

use SoftwareDesign\CardFramework\Player;
use SoftwareDesign\CardFramework\CardTemplate;

class AiPlayer extends Player
{
public function show(?array $canShowCardsIndex = null): CardTemplate
{
// I'm thinking...
sleep(1);

// Uno
if ($canShowCardsIndex !== null) {
if (count($canShowCardsIndex) === 1) {
$showCardIndex = $canShowCardsIndex[0];
} else {
$randomIndex = random_int(0, count($canShowCardsIndex) - 1);
$showCardIndex = $canShowCardsIndex[$randomIndex];
}
} else {
if (count($this->hands) > 0) {
$showCardIndex = random_int(0, count($this->hands) - 1);
} else {
$showCardIndex = 0;
}
}

$card = $this->hands[$showCardIndex];

array_splice($this->hands, $showCardIndex, 1);

return $card;
}
}
7 changes: 7 additions & 0 deletions CardFramework/Autoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

spl_autoload_register(function ($className) {
$className = explode('\\', $className)[2];

require_once __DIR__ . DIRECTORY_SEPARATOR ."{$className}.php";
});
67 changes: 67 additions & 0 deletions CardFramework/CardGameInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace SoftwareDesign\CardFramework;

require_once __DIR__ . DIRECTORY_SEPARATOR . "Autoload.php";

use SoftwareDesign\CardFramework\Player;

interface CardGameInterface
{
/**
* Set four Human\AI player.
*
* @return CardGameInterface
*/
public function setPlayer(): CardGameInterface;

/**
* Set game using deck.
*
* @return CardGameInterface
*/
public function setDeck(): CardGameInterface;

/**
* Set each player name.
*
* @param integer $playerIndex
* @return CardGameInterface
*/
public function setName(int $playerIndex): CardGameInterface;

/**
* Shuffle the card in the deck.
*
* @return CardGameInterface
*/
public function shuffle(): CardGameInterface;

/**
* Each player draw the card from the deck.
*
* @return CardGameInterface
*/
public function drawCard(): CardGameInterface;

/**
* The game start.
*
* @return CardGameInterface
*/
public function turnStart(): CardGameInterface;

/**
* Get the winner by following the game rule.
*
* @return Player
*/
public function getWinner(): Player;

/**
* Set each players game.
*
* @return CardGameInterface
*/
public function setPlayerGame(): CardGameInterface;
}
232 changes: 232 additions & 0 deletions CardFramework/CardGameTemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
<?php

namespace SoftwareDesign\CardFramework;

require_once __DIR__ . DIRECTORY_SEPARATOR . "Autoload.php";

use SoftwareDesign\CardFramework\DeckInterface;
use SoftwareDesign\CardFramework\Player;
use SoftwareDesign\CardFramework\HandleInput;
use SoftwareDesign\CardFramework\HumanPlayer;
use SoftwareDesign\CardFramework\AiPlayer;

abstract class CardGameTemplate implements CardGameInterface
{
/**
* The deck of this turn.
*
* @var DeckInterface
*/
protected DeckInterface $deck;

/**
* The game turn.
*
* @var integer
*/
protected int $turn = 0;

/**
* The winner of this turn.
*
* @var Player|null
*/
protected ?Player $winner = null;

/**
* The engagement player list.
* Sequentially express the order of each player.
*
* @var array<Player>
*/
protected array $playerList = [];

/**
* Set and start up the game process.
*/
public function __construct()
{
$this->setDeck()
->setPlayer()
->setPlayerGame()
->shuffle()
->drawCard()
->turnStart()
->getWinner();
}

/**
* Set player.
*
* @return Showdown
*/
public function setPlayer(): CardGameInterface
{
$playerAmount = 0;

while ($playerAmount < 4) {
print_r("請輸入玩家 " . $playerAmount + 1 . " 是否為機器人: (是 或 否) ");

$isAi = HandleInput::getInput();
$isAi = trim($isAi);

if ($isAi === '否') {
array_push($this->playerList, new HumanPlayer());

$this->setName($playerAmount);
} elseif ($isAi === '是') {
array_push($this->playerList, new AiPlayer());

$this->setName($playerAmount);
} else {
// throw Exception.
}

$playerAmount += 1;
}

return $this;
}

/**
* Set player name.
*
* @param int $playerIndex
* @param string $name
* @return Showdown
*/
public function setName(int $playerIndex): CardGameInterface
{
print_r("請輸入玩家 " . $playerIndex + 1 . " 名稱: ");

$playerName = HandleInput::getInput();

$this->playerList[$playerIndex]->setName($playerName);

return $this;
}

/**
* Shuffle the cards of Deck.
*
* @return Showdown
*/
public function shuffle(): CardGameInterface
{
$this->deck->shuffle();

return $this;
}

/**
* 斗露
*
* @return Showdown
*/
public function drawCard(): CardGameInterface
{
$cardAmount = count($this->deck->getDeck());
$playerIndex = 0;

print_r("是否需要全部玩家自動抽牌? (範例: 是 或 否) : ");
$isAutoDraw = HandleInput::getInput();

while ($this->IsOverDrawCardAmount($cardAmount)) {
if ($cardAmount !== count($this->deck->getDeck())) {
// throw Exception;
exit;
}

$player = $this->playerList[$playerIndex];

if ($isAutoDraw === '是') {
$drawIndex = random_int(1, $cardAmount);
} elseif ($isAutoDraw === '否') {
if ($player instanceof AiPlayer) {
$drawIndex = random_int(1, $cardAmount);
} else {
print_r("{$player->getName()} 你好, 目前牌數 {$cardAmount} , 請問要抽牌堆中的第幾張呢? (範例: 1) : ");
$drawIndex = HandleInput::getInput();
}
} else {
// throw Exception.
exit;
}

if ($drawIndex > $cardAmount) {
// throw Exception.
print_r("輸入牌數比目前牌數多" . PHP_EOL);
exit;
} elseif ($drawIndex <= 0) {
// throw Exception.
print_r("輸入牌數必須大於 0" . PHP_EOL);
exit;
}

$player->setHands(
$this->deck->drawCard($drawIndex - 1)
);

if ($playerIndex === count($this->playerList) - 1) {
$playerIndex = 0;
} else {
$playerIndex += 1;
}

$cardAmount -= 1;
}
return $this;
}

/**
* Game Start.
*
* @return CardGameInterface
*/
public function turnStart(): CardGameInterface
{
while ($this->IsGameTurnOver()) {
// Players show the card.
$this->eachPlayerShow();
}

return $this;
}

/**
* Get the game winner.
*
* @return Player
*/
abstract public function getWinner(): Player;

/**
* Overrided by sub class.
*
* @param integer $cardAmount
* @return boolean
*/
abstract protected function IsOverDrawCardAmount(int $cardAmount): bool;

/**
* Check the card amount.
*
* @param integer $cardAmount
* @return boolean
*/
abstract protected function IsGameTurnOver(): bool;

/**
* Action of each player show the card.
*
* @return void
*/
abstract protected function eachPlayerShow(): void;

/**
* Set each players game.
*
* @return CardGameInterface
*/
abstract public function setPlayerGame(): CardGameInterface;
}
31 changes: 31 additions & 0 deletions CardFramework/CardTemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace SoftwareDesign\CardFramework;

require_once __DIR__ . DIRECTORY_SEPARATOR . "Autoload.php";

class CardTemplate
{
/**
* Getter.
*
* @param string $name
* @return string
*/
public function __get(string $name): string
{
return $this->{$name};
}

/**
* Setter.
*
* @param string $name
* @param string $value
* @return void
*/
public function __set(string $name, string $value): void
{
$this->{$name} = $value;
}
}
Loading