PHP:クラスを使ってみたpart3

思ったより時間食った。。。まあ、しゃーなしやな。勉強勉強!そして進化しているのは分かるから良き!!!

今回の成長ポイント:
  • __construct() の新しい使い方。

  • __constrcut()の前に、変数を宣言して使う方法。

    • private array $cards;:class Cards でも、class OpenCards でも $cards は array型と分かっているから、型宣言をしている

    • 一方で、 class OpenCards の private $cardsArr は、new Cards($suit); で、オブジェクトが返ってきているので、int や array などの 型 宣言していない

/*
何枚開けたときに全種類そろったかを出力してください。
ただし、全て開けても全種類そろわないときは、"unlucky" と出力


買ったカードの枚数 $boughtMuch、カードの種類数を示す整数(最大値) $suit

====考察
forループで、値を取得していく。出てくる数字は、バラバラ。
$suitが最大値。
1 ~ $suit以下 の数字の配列$cards を作る。
for ループで数字を取得していって、$cards の中にある数字と一致したら、$cards の中のその数字を消していく。
最終的に、count($cards) === 0 の時、全種類そろうことになる。
*/
    class Cards
    {
        private array $cards;
        public function __construct(private int $suit)
        {
            $this->suit = $suit;
            for ($i = 1; $i <= $this->suit; $i++) {
                $this->cards[] = $i;
            }
        }
        
        public function cards(): array
        {
            return $this->cards;
        }
    }
    

    class OpenCards
    {
        private $cardsArr;
        private array $cards;
        public function __construct(private int $boughtMuch, private int $suit)
        {
            $this->boughtMuch = $boughtMuch;
            $this->suit = $suit;
            $this->cardsArr = new Cards($suit);
            $this->cards = $this->cardsArr->cards();
        }

        public function openCards(): mixed
        {
            for ($i = 1; $i <= $this->boughtMuch; $i++) {

                fscanf(STDIN, "%d", $number);
                $key = array_search($number, $this->cards);

                if ($key !== false) {
                    unset($this->cards[$key]);
                }
                
                if (count($this->cards) === 0) {
                    return $i;
                } elseif ($i === $this->boughtMuch) {
                    return "unlucky";
                }
            }
        }
    }
    fscanf(STDIN, "%d %d", $boughtMuch, $suit);
    $openCards = new openCards($boughtMuch, $suit);
    $result = $openCards->openCards();
    echo $result;
本当は、やりたかったけど、できなかったこと

グローバルスコープでは、以下の3行のコードで終わらしたかった。

$openCards = new openCards();
$result = $openCards->openCards();
echo $result;

以下のようにして、$boughtMuch, $suit を取得して、class Cards$suitを投げて使いたかったけど、そうすると、$suit の扱いにこんがらがって、昨日と同じようにグローバルスコープで取得してから使うことにした。

public function openCards(): mixed
{
   fscanf(STDIN, "%d %d", $boughtMuch, $suit);
   for ($i = 1; $i <= $this->boughtMuch; $i++) { ... }
}

p.s. 次は、ポリモーフィズムとかそういうオブジェクト指向の書き方の原則?を意識して書くようにしていけば、かなり今の段階での完成形に近づくかな〜