public Bowling() { // standard rules game // This section of code is generated manually from the diagram // Go change the diagram first where you can reason about the logic, then come here and make it match the diagram // Note following code uses the fluent pattern - every method returns the this reference of the object it is called on. scorerEngine = new Frame("game") .setIsFrameCompleteLambda((gameNumber, frames, score) => frames == 10) .WireTo(new Bonuses("bonus") .setIsBonusesCompleteLambda((plays, score) => score < 10 || plays == 3) .WireTo(new Frame("frame") .setIsFrameCompleteLambda((frameNumber, balls, pins) => frameNumber < 9 && (balls == 2 || pins[0] == 10) || (balls == 2 && pins[0] < 10 || balls == 3)) .WireTo(new SinglePlay("SinglePlay") ))); consolerunner = new ConsoleGameRunner("Enter number pins:", (pins, scorer) => scorer.Ball(0, pins)) .WireTo(scorerEngine) .WireTo(new Scorecard( "-------------------------------------------------------------------------------------\n" + "|F00|F01|F10|F11|F20|F21|F30|F31|F40|F41|F50|F51|F60|F61|F70|F71|F80|F81|F90|F91|F92|\n" + "| ---+ ---+ ---+ ---+ ---+ ---+ ---+ ---+ ---+ ---+----\n" + "| T0- | T1- | T2- | T3- | T4- | T5- | T6- | T7- | T8- | T9- |\n" + "-------------------------------------------------------------------------------------\n") .WireTo(new ScoreBinding <List <List <string> > >("F", () => TranslateFrameScores( scorerEngine.GetSubFrames().Select(f => f.GetSubFrames().Select(b => b.GetScore()[0]).ToList()).ToList()))) .WireTo(new ScoreBinding <List <int> >("T", () => scorerEngine.GetSubFrames().Select(sf => sf.GetScore()[0]).Accumulate().ToList())) ); }
/// <summary> /// Gets the current game score e.g. "30","love", "deuce","" or "adv","". If it's in a tie break, returns like "5","4" /// </summary> private string[] GetLastGameScore(IConsistsOf match) { // refer to the diagram to see how each GetSubFrames goes one deeper into the scoring tree if (match.GetSubFrames().Count == 0) { return new string[] { "", "" } } ; // no play yet var set = match.GetSubFrames().Last() // WinnerGetsPoint of last set .GetSubFrames().First() // switch .GetSubFrames().First(); // either set or WinnerGetsPoint of tiebreak if (set.GetType() == typeof(Frame)) // its a set { return (TranslateGameScore( set.GetSubFrames().Last() // WinnerGetsPoint of last game .GetSubFrames().First() // last game .GetScore())); } else // it was a tiebreak { return (set.GetSubFrames().First() // tiebreak .GetScore() .Select(n => n.ToString()).ToArray()); } }
// uncomment to run Bowling /* * static void Main(string[] args) * { * new Tennis().Run(); * } */ // Following two functions know how to get scores from the tree structure /// <summary> /// Gets all the set scores as a List e.g. int[] { 6, 4}, {5, 7}, {6, 2}, {8, 6} /// </summary> /// <param name="match"></param> /// <returns></returns> private List <int[]> GetSetScores(IConsistsOf match) { // note: to understand following code, see wiring diagram of the application - you are reaching in through the match and the first WinnerGetsOnePoint objects using GetSubFrames to get the Sets return(match.GetSubFrames() // list of WinnerGetsOnePoint for sets (this just gives the winner of the set e.g. 1,0 .Select(sf => sf.GetSubFrames().First()) // map to actual set Frames so we can get the set scores .Select(s => s.GetScore()) // get the scores from the sets .ToList()); }
public void TestCompleteMethodScore() { this.frame.setIsFrameCompleteLambda((frameNumber, nPlays, score) => score[0] == 10); IConsistsOf frame = this.frame; Assert.IsFalse(frame.IsComplete()); frame.Ball(0, 9); Assert.IsFalse(frame.IsComplete()); frame.Ball(0, 1); Assert.IsTrue(frame.IsComplete()); }
public void TestCompleteMethodPlays() { this.frame.setIsFrameCompleteLambda((frameNumber, nPlays, score) => nPlays == 2); IConsistsOf frame = this.frame; // make a new reference to the frame under test with the type of the interface Assert.IsFalse(frame.IsComplete()); frame.Ball(0, 8); Assert.IsFalse(frame.IsComplete()); frame.Ball(0, 1); Assert.IsTrue(frame.IsComplete()); }
public void TestGetSubFrames() { this.frame.setIsFrameCompleteLambda((frameNumber, nPlays, score) => nPlays == 2); IConsistsOf frame = this.frame; List <IConsistsOf> L = frame.GetSubFrames(); Assert.AreEqual(1, L.Count); frame.Ball(0, 3); L = frame.GetSubFrames(); Assert.AreEqual(2, L.Count); }
public void TestCompleteMethodframeNumber() { // This test also tests GetCopy // set the completion lambda function for the frame object under test to complete only if it is the 2nd frame of its parent this.frame.setIsFrameCompleteLambda((frameNumber, nPlays, score) => frameNumber == 1); IConsistsOf frame = this.frame; frame.Ball(0, 1); Assert.IsFalse(frame.IsComplete()); frame = frame.GetCopy(1); // makes a Copy of the Frame with the passed in frameNumber Assert.IsFalse(frame.IsComplete()); frame.Ball(0, 1); // The child (SinglePlay) must be complete as well as the lambda expression Assert.IsTrue(frame.IsComplete()); }
public void TestGetnPlays() { this.frame.setIsFrameCompleteLambda((frameNumber, nPlays, score) => nPlays == 3); IConsistsOf frame = this.frame; Assert.AreEqual(0, frame.GetnPlays()); frame.Ball(0, 3); Assert.AreEqual(1, frame.GetnPlays()); frame.Ball(0, 2); Assert.AreEqual(2, frame.GetnPlays()); frame.Ball(1, 6); Assert.AreEqual(3, frame.GetnPlays()); frame.Ball(1, 6); Assert.AreEqual(3, frame.GetnPlays()); }
public Tennis() { // This code is hand written from the diagram. Go change the diagram first where you can reason about the logic, then come here and make it match the diagram // Note following code uses the fluent pattern - every method returns the this reference of the object it is called on. match = new Frame("match") // (note the string is just used to identify instances during debugging, but also helps reading this code to know what they are for) .setIsFrameCompleteLambda((matchNumber, nSets, score) => score.Max() == 3) // best of 5 sets is first to win 3 sets .WireTo(new WinnerTakesPoint("winnerOfSet") .WireTo(new Switch("switch") .setSwitchLambda((setNumber, nGames, score) => (setNumber < 4 && score[0] == 6 && score[1] == 6)) .WireTo(new Frame("set") .setIsFrameCompleteLambda((setNumber, nGames, score) => score.Max() >= 6 && Math.Abs(score[0] - score[1]) >= 2) .WireTo(new WinnerTakesPoint("winnerOfGame") .WireTo(new Frame("game") .setIsFrameCompleteLambda((gameNumber, nBalls, score) => score.Max() >= 4 && Math.Abs(score[0] - score[1]) >= 2) .WireTo(new SinglePlay("singlePlayGame")) ) ) ) .WireTo(new WinnerTakesPoint("winnerOfTieBreak") .WireTo(new Frame("tiebreak") .setIsFrameCompleteLambda((setNumber, nBalls, score) => score.Max() == 7) .WireTo(new SinglePlay("singlePlayTiebreak")) ) ) ) ); consolerunner = new ConsoleGameRunner("Enter winner 0 or 1", (winner, scorer) => scorer.Ball(winner, 1)) .WireTo(match) .WireTo(new Scorecard( "--------------------------------------------\n" + "| M0 |S00|S10|S20|S30|S40|S50|S60| G0--- |\n" + "| M1 |S01|S11|S21|S31|S41|S51|S61| G1--- |\n" + "--------------------------------------------\n") .WireTo(new ScoreBinding <int[]>("M", () => match.GetScore())) .WireTo(new ScoreBinding <List <int[]> >("S", () => GetSetScores(match))) .WireTo(new ScoreBinding <string[]>("G", () => GetLastGameScore(match))) ); }