For the previous video’s challenge, when I did most of the testing cases, the code was starting to become enormous, so I ended up refactoring the whole thing, and it became a completely different approach from that of Ben’s code.
Here’s the code, what do you think?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ActionMaster // We don't need to inherit functions from Monobehaviour here
{
public enum Action {Tidy, Reset, EndTurn, EndGame};
private int frame = 1; // To count the frames from 1-10
private int bowl = 1; // For each bowl inside frames
private int pinHitsInFrame = 0; // For adding up last frame 1st and 2nd bawl
public Action Bowl(int pins)
{
if (pins < 0 || pins > 10) { throw new UnityException("Invalid pin count!"); }
else if (frame < 10) { return HandleFrameOneToNine(pins); }
else if (frame == 10) { return HandleLastFrame(pins); }
throw new UnityException("Not sure what action to return!");
}
private Action HandleFrameOneToNine(int pins)
{
// First bowl will only return EndTurn, if it's a strike.
// Second bowl will always return EndTurn.
if (bowl == 1 && pins < 10)
{
bowl++;
return Action.Tidy;
}
frame++;
bowl = 1;
return Action.EndTurn;
}
private Action HandleLastFrame (int pins)
{
// We only Reset if 1st bawl is a strike.
// We also have to store the pins we hit in the 1st bawl.
if (bowl == 1)
{
if (pins < 10)
{
pinHitsInFrame = pins;
bowl++;
return Action.Tidy;
}
pinHitsInFrame = pins;
bowl++;
return Action.Reset;
} else if (bowl == 2) {
// If the sum of the 1st and 2nd bawl is less than 10,
// then it's an EndGame.
if (pinHitsInFrame + pins < 10) { return Action.EndGame; }
// If it's a gutter ball or the sum of the 1st and 2nd
// bawl is in between 10 and 20, we Tidy.
// With the second condition, the 1st bawl is always a strike.
// Otherwise it can only be a spare, so we Reset.
else if (pins == 0 || (pinHitsInFrame + pins > 10 && pinHitsInFrame + pins < 20))
{
bowl++;
return Action.Tidy;
}
bowl++;
return Action.Reset;
}
// Third bawl will always return EndGame.
return Action.EndGame;
}
}