game = new BowlingGame(); }); it('counts an empty game', function (): void { foreach (range(1, 20) as $roll) { $this->game->roll(0); } assertSame(0, $this->game->getScore()); }); it('counts all single pins', function (): void { foreach (range(1, 20) as $roll) { $this->game->roll(1); } assertSame(20, $this->game->getScore()); }); it('adds a roll one bonus for a spare', function (): void { $this->game->roll(5); $this->game->roll(5); // Spare $this->game->roll(2); foreach (range(1, 17) as $roll) { $this->game->roll(0); } assertSame(14, $this->game->getScore()); }); it('adds a two roll bonus for a strike', function (): void { $this->game->roll(10); // Strike $this->game->roll(3); $this->game->roll(6); foreach (range(1, 16) as $roll) { $this->game->roll(0); } assertSame(28, $this->game->getScore()); }); it('adds an extra ball for a spare on the final frame', function (): void { foreach (range(1, 18) as $roll) { $this->game->roll(0); } $this->game->roll(7); $this->game->roll(3); // Spare $this->game->roll(5); assertSame(15, $this->game->getScore()); }); it('adds an two extra balls for a strike on the final frame', function (): void { foreach (range(1, 18) as $roll) { $this->game->roll(0); } $this->game->roll(10); // Strike $this->game->roll(4); $this->game->roll(2); assertSame(16, $this->game->getScore()); }); it('scores a perfect game', function (): void { foreach (range(1, 12) as $roll) { $this->game->roll(10); } assertSame(300, $this->game->getScore()); }); it('scores a normal game', function (): void { $this->game->roll(4); $this->game->roll(3); $this->game->roll(10); $this->game->roll(4); $this->game->roll(1); $this->game->roll(0); $this->game->roll(2); $this->game->roll(3); $this->game->roll(7); $this->game->roll(8); $this->game->roll(1); $this->game->roll(10); $this->game->roll(0); $this->game->roll(7); $this->game->roll(1); $this->game->roll(5); $this->game->roll(10); $this->game->roll(6); $this->game->roll(1); assertSame(103, $this->game->getScore()); }); it('cannot knock down a negative pins', function (): void { $this->game->roll(-1); })->throws( AssertionFailedException::class, 'You cannot knock down a negative number of pins. Knocked down -1.' ); it('cannot knock down more than 10 pins in a roll', function (): void { $this->game->roll(12); })->throws( AssertionFailedException::class, 'You can only knock down a maximum of 10 pins in a roll. Knocked down 12.' );