Skip to content

Instantly share code, notes, and snippets.

@Grepsy
Created April 30, 2014 11:29
Show Gist options
  • Save Grepsy/3f4ae1e3f55e2155ef1b to your computer and use it in GitHub Desktop.
Save Grepsy/3f4ae1e3f55e2155ef1b to your computer and use it in GitHub Desktop.
Bowling Kata - C#, try 1
using System;
using System.Collections.Generic;
using System.Linq;
namespace Katas {
class Frame(int index) {
public List<int> Rolls = new List<int>();
public int FrameIndex { get; } = index;
public bool Completed {
get {
return (!IsLastFrame && (IsStrike || Rolls.Count == 2)) ||
(IsLastFrame && (IsSpare || IsStrike) && Rolls.Count == 3) ||
(IsLastFrame && !(IsSpare || IsStrike) && Rolls.Count == 2);
}
}
public bool IsSpare {
get {
return Rolls.Count == 2 && Rolls.Sum() == 10;
}
}
public bool IsStrike {
get {
return (Rolls[0] == 10 && (Rolls.Count == 1 || IsLastFrame));
}
}
public bool IsLastFrame {
get {
return FrameIndex == 10;
}
}
public void AddRoll(int roll) {
Rolls.Add(roll);
}
}
class Bowling {
List<int> rolls = new List<int>();
public void Roll(int pins) {
rolls.Add(pins);
}
public int Score() {
var frames = Frames(rolls).ToArray();
int scores = frames.Sum(frame => frame.Rolls.Take(2).Sum());
int spareBonus = frames.Skip(1).Where((_, i) => frames[i].IsSpare).Sum((frame) => frame.Rolls[0]);
int strikeBonus = frames.Where(frame => frame.IsStrike)
.SelectMany(frame =>
frames.Skip(frame.FrameIndex)
.SelectMany(nextFrame => nextFrame.Rolls)
.Take(2))
.Sum();
spareBonus += frames.Where(frame => frame.IsLastFrame && frame.IsSpare && frame.Completed).Sum(frame => frame.Rolls[2]);
strikeBonus += frames.Where(frame => frame.IsLastFrame && frame.IsStrike && frame.Completed).Sum(frame => frame.Rolls[2]);
return scores + spareBonus + strikeBonus;
}
private static IEnumerable<Frame> Frames(IEnumerable<int> rolls) {
var currentFrameIndex = 1;
var currentFrame = new Frame(currentFrameIndex);
foreach (var roll in rolls) {
currentFrame.AddRoll(roll);
if (currentFrame.Completed) {
yield return currentFrame;
currentFrameIndex++;
currentFrame = new Frame(currentFrameIndex);
}
}
}
static void Main() {
Action<int[], int> test = (rolls, expectedScore) => {
var bowling = new Bowling();
foreach (int roll in rolls)
bowling.Roll(roll);
bool success = bowling.Score() == expectedScore;
Console.WriteLine("{0, 5} {1, 3} {2, 3} Rolls: {3}", success, bowling.Score(), expectedScore, String.Join(",", rolls));
};
test(new int[] { 0, 0 }, 0);
test(new int[] { 0, 5 }, 5);
test(new int[] { 5, 5, 0, 0 }, 10); // Spare w/o bonus points
test(new int[] { 5, 5, 5, 0 }, 20); // Spare with bonus points
test(new int[] { 10, 0, 0 }, 10); // Strike w/o bonus in both rolls
test(new int[] { 10, 5, 0 }, 20); // Strike with bonus in first roll
test(new int[] { 10, 0, 5 }, 20); // Strike with bonus in second roll
test(new int[] { 10, 5, 5 }, 30); // Strike with bonus in both rolls
test(new int[] { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }, 300); // Perfect game
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment