-
-
Save yeradis/f28f0f87f62c6dcb7d5da1992b2cc943 to your computer and use it in GitHub Desktop.
Bowling Kata Dart vs Kotlin
This file contains hidden or 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
int _sum(sum, pins) => sum + pins; | |
int score([Iterable<int> list = const []]) => | |
toFrames(list).take(10).fold(0, _sum); | |
bool isStrike(Iterable<int> list) => list.first == 10; | |
bool isSpare(Iterable<int> list) => | |
!isStrike(list) && list.take(2).reduce(_sum) == 10; | |
Iterable<int> rollsForFrame(Iterable<int> list) => | |
list.take(isStrike(list) || isSpare(list) ? 3 : 2); | |
Iterable<int> remainingRolls(Iterable<int> rolls) => | |
rolls.skip(isStrike(rolls) ? 1 : 2); | |
Iterable<int> toFrames( | |
Iterable<int> rolls, [ | |
Iterable<int> frames = const [], | |
]) => | |
rolls.isEmpty | |
? frames | |
: toFrames(remainingRolls(rolls), | |
frames.toList()..add(rollsForFrame(rolls).reduce(_sum))); |
This file contains hidden or 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
fun List<Int>.score(): Int = | |
toFrames().take(10).sum() | |
fun List<Int>.toFrames(frames: List<Int> = emptyList()): List<Int> = | |
if (isEmpty()) frames else remainingRolls().toFrames(frames + rollsForFrame().sum()) | |
fun List<Int>.remainingRolls(): List<Int> = | |
if (isStrike()) drop(1) else drop(2) | |
fun List<Int>.rollsForFrame(): List<Int> = | |
if (isStrike() or isSpare()) take(3) else take(2) | |
fun List<Int>.isStrike(): Boolean = | |
firstOrNull()?.equals(10) ?: false | |
fun List<Int>.isSpare(): Boolean = | |
if (isStrike()) false else take(2).sum() == 10 |
This file contains hidden or 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
library blowling_test; | |
import 'package:Lets_Dart/bowling/bowling.dart'; | |
import 'package:test/test.dart'; | |
main() { | |
test("score is 0 when the player did not knock down any pins", () { | |
expect(score(), equals(0)); | |
}); | |
test("score should be 20 if all rolls knocked down a single pin", () { | |
expect(score(new List.filled(20, 1)), equals(20)); | |
}); | |
test("should identify a strike if the first roll in a frame was 10", () { | |
expect(isStrike([10, 5, 1]), equals(true)); | |
expect(isStrike([9, 1]), equals(false)); | |
}); | |
test("should identify a spare from two rolls adding up to 10, if the first roll was not a 10", () { | |
expect(isSpare([10]), equals(false)); | |
expect(isSpare([10, 0]), equals(false)); | |
expect(isSpare([1, 0]), equals(false)); | |
expect(isSpare([1, 9]), equals(true)); | |
expect(isSpare([0, 10]), equals(true)); | |
}); | |
test("should only score two rolls if a frame is less than ten", () { | |
expect(rollsForFrame([4, 5, 6, 7]), equals([4, 5])); | |
}); | |
test("should add the next roll to the score after a spare", () { | |
expect(rollsForFrame([1, 9, 6, 7]), equals([1, 9, 6])); | |
}); | |
test("should add the next two rolls to the score after a strike", () { | |
expect(rollsForFrame([10, 9, 6, 7]), equals([10, 9, 6])); | |
}); | |
test("should correctly produce frame totals for <10 frames", () { | |
expect(toFrames([3]), equals([3])); | |
expect(toFrames([1, 2, 3, 4, 5]), equals([3, 7, 5])); | |
expect(toFrames([1, 2, 3, 4, 5, 3]), equals([3, 7, 8])); | |
}); | |
test("should correctly product frame totals that include spares", () { | |
expect(toFrames([3, 7]), equals([10])); | |
expect(toFrames([3, 7, 6]), equals([16, 6])); | |
expect(toFrames([3, 7, 6, 4, 2]), equals([16, 12, 2])); | |
}); | |
test("should correctly product frame totals that include strike", () { | |
expect(toFrames([10]), equals([10])); | |
expect(toFrames([10, 3]), equals([13, 3])); | |
expect(toFrames([10, 10, 2]), equals([22, 12, 2])); | |
}); | |
test("should add and extra roll if the tenth frame was a spare", () { | |
expect(score(new List.from(new List.filled(18, 1))..addAll([4, 6])), equals(28)); | |
expect(score(new List.from(new List.filled(18, 1))..addAll([4, 6, 1])), equals(29)); | |
}); | |
test("should be 150 if all rolls knocked down 5 pins (including 1 bonus roll for ending on a spare)", () { | |
expect(score(new List.filled(21, 5)), equals(150)); | |
}); | |
test("should be 300 when bowling all strikes (including 2 bonus rolls for ending with a strike)", () { | |
expect(score(new List.filled(22, 10)), equals(300)); | |
}); | |
} | |
This file contains hidden or 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
import org.junit.jupiter.api.Assertions.* | |
import org.junit.jupiter.api.Test | |
internal class BowlingKtTest { | |
@Test | |
fun `score is 0 when the player did not knock down any pins`() { | |
assertEquals(0, Array(20, { 0 }).toList().score()) | |
} | |
@Test | |
fun `score is 0 when the player did not play`() { | |
assertEquals(0, emptyList<Int>().score()) | |
} | |
@Test | |
fun `should identify a strike if the first roll in a frame was 10`() { | |
assertEquals(true, listOf(10, 5, 1).isStrike()) | |
assertEquals(false, listOf(9, 1).isStrike()) | |
} | |
@Test | |
fun `should identify a spare from two rolls adding up to 10, if the first roll was not a 10`() { | |
assertEquals(false, listOf(10).isSpare()) | |
assertEquals(false, listOf(10, 0).isSpare()) | |
assertEquals(false, listOf(1, 0).isSpare()) | |
assertEquals(true, listOf(1, 9).isSpare()) | |
assertEquals(true, listOf(0, 10).isSpare()) | |
} | |
@Test | |
fun `should only score two rolls if a frame is less than ten`() { | |
assertEquals(listOf(4, 5), listOf(4, 5, 6, 7).rollsForFrame()) | |
} | |
@Test | |
fun `should add the next roll to the score after a spare`() { | |
assertEquals(listOf(1, 9, 6), listOf(1, 9, 6, 7).rollsForFrame()) | |
} | |
@Test | |
fun `should add the next two rolls to the score after a strike`() { | |
assertEquals(listOf(10, 9, 6), listOf(10, 9, 6, 7).rollsForFrame()) | |
} | |
@Test | |
fun `should correctly produce frame totals for less 10 frames`() { | |
assertEquals(listOf(3), listOf(3).toFrames()) | |
assertEquals(listOf(3, 7, 5), listOf(1, 2, 3, 4, 5).toFrames()) | |
assertEquals(listOf(3, 7, 8), listOf(1, 2, 3, 4, 5, 3).toFrames()) | |
} | |
@Test | |
fun `should correctly product frame totals that include spares`() { | |
assertEquals(listOf(10), listOf(3, 7).toFrames()) | |
assertEquals(listOf(16, 6), listOf(3, 7, 6).toFrames()) | |
assertEquals(listOf(16, 12, 2), listOf(3, 7, 6, 4, 2).toFrames()) | |
} | |
@Test | |
fun `should correctly product frame totals that include strike`() { | |
assertEquals(listOf(10), listOf(10).toFrames()) | |
assertEquals(listOf(13, 3), listOf(10, 3).toFrames()) | |
assertEquals(listOf(22, 12, 2), listOf(10, 10, 2).toFrames()) | |
} | |
@Test | |
fun `should be 150 if all rolls knocked down 5 pins (including 1 bonus roll for ending on spare)`() { | |
assertEquals(150, Array(21, { 5 }).toList().score()) | |
} | |
@Test | |
fun `should be 300 when bowling all strikes (including 2 bonus rolls for ending with a strike`() { | |
assertEquals(300, Array(22, { 10 }).toList().score()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment