Bowling Game: State Machine: Std::Variant: Step 31
Adding that missing code is easy:
struct WaitingForFirstRollWith1Bonus : FirstRollUtils
{
State Update(int pins, int& score, int& frame) const
{
score += pins*2;
if (IsStrike(pins)) {
++frame;
return WaitingForFirstRollWith2Bonuses{};
}
return WaitingForSecondRollWith0Bonuses{pins};
}
};
Now, looking at all the first rolls states, something doesn’t look right to me:
struct WaitingForFirstRollWith0Bonuses : FirstRollUtils
{
State Update(int pins, int& score, int& frame) const
{
score += pins;
if (IsStrike(pins)) {
++frame;
return WaitingForFirstRollWith2Bonuses{};
}
return WaitingForSecondRollWith0Bonuses{pins};
}
};
struct WaitingForFirstRollWith1Bonus : FirstRollUtils
{
State Update(int pins, int& score, int& frame) const
{
score += pins*2;
if (IsStrike(pins)) {
++frame;
return WaitingForFirstRollWith2Bonuses{};
}
return WaitingForSecondRollWith0Bonuses{pins};
}
};
struct WaitingForFirstRollWith2Bonuses : FirstRollUtils
{
State Update(int pins, int& score, int& frame) const
{
score += pins*2;
if (IsStrike(pins)) {
++frame;
return WaitingForFirstRollWith3Bonuses{};
}
return WaitingForSecondRollWith1Bonus{pins};
}
};
struct WaitingForFirstRollWith3Bonuses : FirstRollUtils
{
State Update(int pins, int& score, int& frame) const
{
score += pins*3;
if (IsStrike(pins)) {
++frame;
if (frame == 10)
return LastFrameWith2Bonuses{};
return WaitingForFirstRollWith3Bonuses{};
}
return WaitingForSecondRollWith1Bonus{pins};
}
};
Only the last one is checking to see if we’re in the last frame, which needs to be handled specially. And that means that we’re missing (at least) 3 tests.
Let’s add a test for a strike in the last frame and then for the two bonus rolls, a strike and a 1:
{"18 gutterballs, then two strikes and a bonus roll of 1 means score is 21", []() {
Game game;
RollMany(game, 18, 0);
game.Roll(10); // strike
game.Roll(10); // strike
game.Roll(1);
Assert::AreEqual(21, game.Score()); // game is over here
Assert::ExpectingException<std::invalid_argument>([&game]() { game.Roll(0); });
}},
Get all the tests to pass and then click next.