From 5237cad9a4722ece186e55b81462ef6fa15381a1 Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 22 Oct 2020 19:57:27 +0200 Subject: [PATCH] Polish and reordering --- src/main/kotlin/rps/Game.kt | 59 +++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/rps/Game.kt b/src/main/kotlin/rps/Game.kt index 91924a1..2f2f281 100644 --- a/src/main/kotlin/rps/Game.kt +++ b/src/main/kotlin/rps/Game.kt @@ -2,10 +2,43 @@ package rps import kotlin.random.Random +const val TURNS = 100 +val PLAYER_TWO_CHOICE = Move.ROCK + fun main() { - println(playGame(100)) + println("Outcome from Player 1’s perspective: ${playGame(TURNS)}") } +/** Determine the [Outcome] of [first] vs [second] from the perspective of [first]. */ +fun determineOutcome(first: Move, second: Move): Outcome = when { + first.strongAgainst() == second -> Outcome.WIN + first == second -> Outcome.DRAW + else -> Outcome.LOSS +} + +// Note: This could be slightly more efficiently and directly on the Sequence +// (but a lot less elegantly) with an imperative loop and three mutable integers. +fun List.calculateGameSummary() = GameSummary( + wins = count { it == Outcome.WIN }, + draws = count { it == Outcome.DRAW }, + losses = count { it == Outcome.LOSS }, +) + +fun playGame(turns: Int): GameSummary = generateSequence { randomMove() } + .take(turns) + .map { determineOutcome(it, PLAYER_TWO_CHOICE) } + .toList() + .calculateGameSummary() + +fun randomMove(): Move = Move.values().let { allMoves -> + allMoves[Random.nextInt(allMoves.size)] +} + +/* + * Classes and named tuples below this point. + * (All in the same file for easier reviewability in a web UI on Github/Gitea). + */ + /** * A possible move in a game of rock-paper-scissors. * @@ -28,27 +61,3 @@ enum class Outcome { // Named Triple for readability data class GameSummary(val wins: Int, val draws: Int, val losses: Int) - -/** Determine the [Outcome] of [first] vs [second] from the perspective of [first]. */ -fun determineOutcome(first: Move, second: Move): Outcome = when { - first.strongAgainst() == second -> Outcome.WIN - first == second -> Outcome.DRAW - else -> Outcome.LOSS -} - -// Note: This would be slightly more efficient (but a lot less elegant) with an imperative loop and three mutable integers. -fun List.calculateGameSummary() = GameSummary( - wins = count { it == Outcome.WIN }, - draws = count { it == Outcome.DRAW }, - losses = count { it == Outcome.LOSS }, -) - -fun playGame(turns: Int): GameSummary = generateSequence { randomMove() } - .take(turns) - .map { determineOutcome(it, Move.ROCK) } - .toList() - .calculateGameSummary() - -fun randomMove(): Move = Move.values().let { allMoves -> - allMoves[Random.nextInt(allMoves.size)] -} \ No newline at end of file