diff --git a/src/Domain/BasicStrategy.php b/src/Domain/BasicStrategy.php index 6f6658e..7d0f2e9 100644 --- a/src/Domain/BasicStrategy.php +++ b/src/Domain/BasicStrategy.php @@ -9,11 +9,28 @@ public function decide(Hand $hand, Card $dealerCard): Decision $value = $hand->value(); $dealerValue = $dealerCard->numericValue(); - if ($hand->isSoft() && $value === 18 && $dealerValue >= 3 && $dealerValue <= 6) { + if ($hand->isSoft() && $value === 18) { + if ($dealerValue >= 3 && $dealerValue <= 6) { + return Decision::Double; + } + if ($dealerValue === 2 || $dealerValue === 7 || $dealerValue === 8) { + return Decision::Stand; + } + return Decision::Hit; + } + + if ($hand->isSoft() && $value === 17) { + if ($dealerValue >= 3 && $dealerValue <= 6) { + return Decision::Double; + } + return Decision::Hit; + } + + if ($hand->isSoft() && $value >= 15 && $value <= 16 && $dealerValue >= 4 && $dealerValue <= 6) { return Decision::Double; } - if ($hand->isSoft() && $value === 17 && $dealerValue >= 3 && $dealerValue <= 6) { + if ($hand->isSoft() && $value >= 13 && $value <= 14 && $dealerValue >= 5 && $dealerValue <= 6) { return Decision::Double; } @@ -21,11 +38,19 @@ public function decide(Hand $hand, Card $dealerCard): Decision return Decision::Stand; } - if ($value >= 13 && $value <= 16 && $dealerValue >= 2 && $dealerValue <= 6) { + if (!$hand->isSoft() && $value === 16 && ($dealerValue === 9 || $dealerValue === 10 || $dealerValue === 11)) { + return Decision::Surrender; + } + + if (!$hand->isSoft() && $value === 15 && $dealerValue === 10) { + return Decision::Surrender; + } + + if (!$hand->isSoft() && $value >= 13 && $value <= 16 && $dealerValue >= 2 && $dealerValue <= 6) { return Decision::Stand; } - if ($value === 12 && $dealerValue >= 4 && $dealerValue <= 6) { + if (!$hand->isSoft() && $value === 12 && $dealerValue >= 4 && $dealerValue <= 6) { return Decision::Stand; } @@ -43,4 +68,4 @@ public function decide(Hand $hand, Card $dealerCard): Decision return Decision::Hit; } -} \ No newline at end of file +} diff --git a/src/Domain/Decision.php b/src/Domain/Decision.php index 048bb31..8983bba 100644 --- a/src/Domain/Decision.php +++ b/src/Domain/Decision.php @@ -8,4 +8,5 @@ enum Decision case Stand; case Double; case Split; + case Surrender; } \ No newline at end of file diff --git a/tests/Domain/BasicStrategyTest.php b/tests/Domain/BasicStrategyTest.php index d908571..eeaa732 100644 --- a/tests/Domain/BasicStrategyTest.php +++ b/tests/Domain/BasicStrategyTest.php @@ -10,7 +10,7 @@ final class BasicStrategyTest extends TestCase { - public function testHard16AgainstDealerTenShouldHit(): void + public function testHard16AgainstDealerTenShouldSurrender(): void { $strategy = new BasicStrategy(); @@ -20,7 +20,7 @@ public function testHard16AgainstDealerTenShouldHit(): void $dealerCard = new Card('10', 'Diamonds'); - $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + $this->assertSame(Decision::Surrender, $strategy->decide($hand, $dealerCard)); } public function testHard17ShouldStand(): void @@ -35,6 +35,7 @@ public function testHard17ShouldStand(): void $this->assertSame(Decision::Stand, $strategy->decide($hand, $dealerCard)); } + public function testHard12AgainstDealer4ShouldStand(): void { $strategy = new BasicStrategy(); @@ -151,4 +152,238 @@ public function testSoft19ShouldAlwaysStand(): void $this->assertSame(Decision::Stand, $strategy->decide($hand, $dealerCard)); } + + public function testSoft18AgainstDealer9ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('7', 'Spades')); + + $dealerCard = new Card('9', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft15AgainstDealer4ShouldDouble(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('4', 'Diamonds'); + + $this->assertSame(Decision::Double, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft13AgainstDealer5ShouldDouble(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('2', 'Spades')); + + $dealerCard = new Card('5', 'Diamonds'); + + $this->assertSame(Decision::Double, $strategy->decide($hand, $dealerCard)); + } + + public function testHard12AgainstDealer2ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('7', 'Hearts')); + $hand->addCard(new Card('5', 'Spades')); + + $dealerCard = new Card('2', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard12AgainstDealer3ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('7', 'Hearts')); + $hand->addCard(new Card('5', 'Spades')); + + $dealerCard = new Card('3', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft17AgainstDealer7ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('6', 'Spades')); + + $dealerCard = new Card('7', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft13AgainstDealer7ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('2', 'Spades')); + + $dealerCard = new Card('7', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft13AgainstDealer4ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('2', 'Spades')); + + $dealerCard = new Card('4', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testSoft16AgainstDealer7ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('Ace', 'Hearts')); + $hand->addCard(new Card('5', 'Spades')); + + $dealerCard = new Card('7', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard11AgainstDealerAceShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('7', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('Ace', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard10AgainstDealerAceShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('6', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('Ace', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard16AgainstDealer9ShouldSurrender(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('9', 'Hearts')); + $hand->addCard(new Card('7', 'Spades')); + + $dealerCard = new Card('9', 'Diamonds'); + + $this->assertSame(Decision::Surrender, $strategy->decide($hand, $dealerCard)); + } + + public function testHard15AgainstDealerTenShouldSurrender(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('9', 'Hearts')); + $hand->addCard(new Card('6', 'Spades')); + + $dealerCard = new Card('10', 'Diamonds'); + + $this->assertSame(Decision::Surrender, $strategy->decide($hand, $dealerCard)); + } + + public function testHard16AgainstDealerAceShouldSurrender(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('9', 'Hearts')); + $hand->addCard(new Card('7', 'Spades')); + + $dealerCard = new Card('Ace', 'Diamonds'); + + $this->assertSame(Decision::Surrender, $strategy->decide($hand, $dealerCard)); + } + + public function testHard8ShouldAlwaysHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('4', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('6', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard9AgainstDealer2ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('5', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('2', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard9AgainstDealer7ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('5', 'Hearts')); + $hand->addCard(new Card('4', 'Spades')); + + $dealerCard = new Card('7', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } + + public function testHard16AgainstDealer7ShouldHit(): void + { + $strategy = new BasicStrategy(); + + $hand = new Hand(); + $hand->addCard(new Card('9', 'Hearts')); + $hand->addCard(new Card('7', 'Spades')); + + $dealerCard = new Card('7', 'Diamonds'); + + $this->assertSame(Decision::Hit, $strategy->decide($hand, $dealerCard)); + } } \ No newline at end of file