Bowling
This commit is contained in:
parent
7887455c41
commit
ae5f58c8c7
3 changed files with 223 additions and 0 deletions
88
src/BowlingGame.php
Normal file
88
src/BowlingGame.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Assert\Assert;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
final class BowlingGame
|
||||
{
|
||||
private const MAX_PINS_PER_FRAME = 10;
|
||||
private const NUMBER_OF_FRAMES = 10;
|
||||
|
||||
private Collection $rolls;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->rolls = new Collection();
|
||||
}
|
||||
|
||||
public function roll(int $pins): void
|
||||
{
|
||||
Assert::that($pins)
|
||||
->greaterOrEqualThan(0,
|
||||
'You cannot knock down a negative number of pins. Knocked down %d.')
|
||||
->lessOrEqualThan(self::MAX_PINS_PER_FRAME,
|
||||
'You can only knock down a maximum of 10 pins in a roll. Knocked down 12.');
|
||||
|
||||
$this->rolls->push($pins);
|
||||
}
|
||||
|
||||
public function getScore(): int
|
||||
{
|
||||
$score = 0;
|
||||
$roll = 0;
|
||||
|
||||
foreach (range(1, self::NUMBER_OF_FRAMES) as $frame) {
|
||||
if ($this->isStrike($roll)) {
|
||||
$score += $this->rolls[$roll];
|
||||
$score += $this->bonusForStrike($roll);
|
||||
|
||||
$roll += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isSpare($roll)) {
|
||||
$score += $this->defaultFrameScore($roll);
|
||||
$score += $this->bonusForSpare($roll);
|
||||
|
||||
$roll += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
$score += $this->defaultFrameScore($roll);
|
||||
|
||||
$roll += 2;
|
||||
}
|
||||
|
||||
return $score;
|
||||
}
|
||||
|
||||
private function bonusForSpare(int $roll): int
|
||||
{
|
||||
return $this->rolls->get($roll + 2);
|
||||
}
|
||||
|
||||
private function bonusForStrike(int $roll): int
|
||||
{
|
||||
return $this->rolls[$roll + 1] + $this->rolls[$roll + 2];
|
||||
}
|
||||
|
||||
private function defaultFrameScore(int $roll): int
|
||||
{
|
||||
return $this->rolls[$roll] + $this->rolls[$roll + 1];
|
||||
}
|
||||
|
||||
private function isSpare(int $roll): bool
|
||||
{
|
||||
return $this->defaultFrameScore($roll)
|
||||
== self::MAX_PINS_PER_FRAME;
|
||||
}
|
||||
|
||||
private function isStrike(int $roll): bool
|
||||
{
|
||||
return $this->rolls[$roll] == self::MAX_PINS_PER_FRAME;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue