Last active
October 8, 2018 09:10
-
-
Save ralfw/991b1bf473e178fed6f9 to your computer and use it in GitHub Desktop.
IODA Architecture for Bowling Game Kata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Game { | |
private int[] rolls = new int[21]; | |
private int currentRoll = 0; | |
public void roll(int pins) { | |
rolls[currentRoll++] = pins; | |
} | |
public int score() { | |
var frames = Detect_frames (rolls); | |
var scores = Score_frames (frames, rolls); | |
return scores.Sum (); | |
} | |
IEnumerable<Frame> Detect_frames(int[] rolls) { | |
const int MAX_FRAMES = 10; | |
var fc = new FrameClassifier (rolls); | |
return Enumerable.Range (1, MAX_FRAMES) | |
.Select (fc.Classify); | |
} | |
IEnumerable<int> Score_frames(IEnumerable<Frame> frames, int[] rolls) { | |
return frames.Select (f => Score_frame(f, rolls)); | |
} | |
int Score_frame(Frame frame, int[] rolls) { | |
switch ((Frame.KindsOfFrame)frame.Kind) { | |
case Frame.KindsOfFrame.Strike: | |
case Frame.KindsOfFrame.Spare: | |
return rolls [frame.RollIndex] + rolls [frame.RollIndex + 1] + rolls [frame.RollIndex + 2]; | |
default: | |
return rolls [frame.RollIndex] + rolls [frame.RollIndex + 1]; | |
} | |
} | |
class Frame { | |
public enum KindsOfFrame { | |
Regular, | |
Spare, | |
Strike | |
} | |
public int FrameNr; | |
public KindsOfFrame Kind; | |
public int RollIndex; | |
} | |
class FrameClassifier { | |
int[] rolls; | |
int rollIndex = 0; | |
public FrameClassifier(int[] rolls) { | |
this.rolls = rolls; | |
} | |
public Frame Classify(int frameNumber) { | |
const int MAX_FRAME_PINS = 10; | |
dynamic frame = new Frame{ FrameNr = frameNumber, Kind = Frame.KindsOfFrame.Regular, RollIndex = rollIndex}; | |
if (rolls [rollIndex] == MAX_FRAME_PINS) { | |
frame.Kind = Frame.KindsOfFrame.Strike; | |
rollIndex += 1; | |
} else { | |
if (rolls [rollIndex] + rolls [rollIndex + 1] == MAX_FRAME_PINS) | |
frame.Kind = Frame.KindsOfFrame.Spare; | |
rollIndex += 2; | |
} | |
return frame; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Game { | |
private int[] rolls = new int[21]; | |
private int currentRoll = 0; | |
public void roll(int pins) { | |
rolls[currentRoll++] = pins; | |
} | |
public int score() { | |
var frames = Detect_frames (rolls); | |
var scores = Score_frames (frames, rolls); | |
return scores.Sum (); | |
} | |
IEnumerable<Frame> Detect_frames(int[] rolls) { | |
const int MAX_FRAMES = 10; | |
return Classify_frames (new List<Frame>(), rolls, MAX_FRAMES).Frames; | |
} | |
dynamic Classify_frames(List<Frame> frames, int[] rolls, int frameNumber) { | |
dynamic classifications = null; | |
if (frameNumber > 1) classifications = Classify_frames (frames, rolls, frameNumber - 1); | |
dynamic classification = Classify_frame (frameNumber, rolls, classifications == null ? 0 : classifications.NextRollIndex); | |
frames.Add (classification.Frame); | |
return new { Frames = frames, NextRollIndex = classification.NextRollIndex }; | |
} | |
dynamic Classify_frame(int frameNumber, int[] rolls, int rollIndex) { | |
const int MAX_FRAME_PINS = 10; | |
dynamic frame = new Frame{ FrameNr = frameNumber, Kind = Frame.KindsOfFrame.Regular, RollIndex = rollIndex}; | |
if (rolls [rollIndex] == MAX_FRAME_PINS) { | |
frame.Kind = Frame.KindsOfFrame.Strike; | |
rollIndex += 1; | |
} else { | |
if (rolls [rollIndex] + rolls [rollIndex + 1] == MAX_FRAME_PINS) | |
frame.Kind = Frame.KindsOfFrame.Spare; | |
rollIndex += 2; | |
} | |
return new {Frame = frame, NextRollIndex = rollIndex}; | |
} | |
IEnumerable<int> Score_frames(IEnumerable<Frame> frames, int[] rolls) { | |
return frames.Select (f => Score_frame(f, rolls)); | |
} | |
int Score_frame(Frame frame, int[] rolls) { | |
switch ((Frame.KindsOfFrame)frame.Kind) { | |
case Frame.KindsOfFrame.Strike: | |
case Frame.KindsOfFrame.Spare: | |
return rolls [frame.RollIndex] + rolls [frame.RollIndex + 1] + rolls [frame.RollIndex + 2]; | |
default: | |
return rolls [frame.RollIndex] + rolls [frame.RollIndex + 1]; | |
} | |
} | |
class Frame { | |
public enum KindsOfFrame { | |
Regular, | |
Spare, | |
Strike | |
} | |
public int FrameNr; | |
public KindsOfFrame Kind; | |
public int RollIndex; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// adapted from: http://butunclebob.com/files/downloads/Bowling%20Game%20Kata.ppt | |
public class Game { | |
private int[] rolls = new int[21]; | |
private int currentRoll = 0; | |
public void roll(int pins) { | |
rolls[currentRoll++] = pins; | |
} | |
public int score() { | |
int score = 0; | |
int frameIndex = 0; | |
for (int frame = 0; frame < 10; frame++) { | |
if (isStrike(frameIndex)) { | |
score += 10 + strikeBonus(frameIndex); | |
frameIndex++; | |
} else if (isSpare(frameIndex)) { | |
score += 10 + spareBonus(frameIndex); | |
frameIndex += 2; | |
} else { | |
score += sumOfBallsInFrame(frameIndex); | |
frameIndex += 2; | |
} | |
} | |
return score; | |
} | |
private bool isStrike(int frameIndex) { | |
return rolls[frameIndex] == 10; | |
} | |
private int sumOfBallsInFrame(int frameIndex) { | |
return rolls[frameIndex] + rolls[frameIndex+1]; | |
} | |
private int spareBonus(int frameIndex) { | |
return rolls[frameIndex+2]; | |
} | |
private int strikeBonus(int frameIndex) { | |
return rolls[frameIndex+1] + rolls[frameIndex+2]; | |
} | |
private bool isSpare(int frameIndex) { | |
return rolls[frameIndex]+rolls[frameIndex+1] == 10; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment