From 10d70c6f84cd481a37b1106e8a396920e6fc58b3 Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 29 Oct 2020 16:41:24 +0100 Subject: [PATCH] review feedback --- src/main/kotlin/rps/Game.kt | 29 ++++++++++++----------------- src/test/kotlin/rps/GameTest.kt | 3 +++ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/rps/Game.kt b/src/main/kotlin/rps/Game.kt index 2f2f281..4520ed1 100644 --- a/src/main/kotlin/rps/Game.kt +++ b/src/main/kotlin/rps/Game.kt @@ -1,18 +1,15 @@ package rps -import kotlin.random.Random - const val TURNS = 100 -val PLAYER_TWO_CHOICE = Move.ROCK fun main() { 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 +fun determineOutcome(first: Move, second: Move): Outcome = when(second) { + in first.strongAgainst() -> Outcome.WIN + first -> Outcome.DRAW else -> Outcome.LOSS } @@ -24,15 +21,13 @@ fun List.calculateGameSummary() = GameSummary( losses = count { it == Outcome.LOSS }, ) -fun playGame(turns: Int): GameSummary = generateSequence { randomMove() } +fun playGame(turns: Int): GameSummary = generateSequence { randomMove() to randomMove() } .take(turns) - .map { determineOutcome(it, PLAYER_TWO_CHOICE) } + .map { (p1, p2) -> determineOutcome(p1, p2) } .toList() .calculateGameSummary() -fun randomMove(): Move = Move.values().let { allMoves -> - allMoves[Random.nextInt(allMoves.size)] -} +fun randomMove(): Move = Move.values().random() /* * Classes and named tuples below this point. @@ -43,13 +38,13 @@ fun randomMove(): Move = Move.values().let { allMoves -> * A possible move in a game of rock-paper-scissors. * * [strongAgainst] is a function for lazy evaluation because otherwise we can’t access SCISSORS before it’s been defined. - * If the game needs to be expanded (e.g. the somewhat common “rock, paper, scissors, salamander, spock”), - * this argument could be a List instead. */ -enum class Move(val strongAgainst: () -> Move) { - ROCK({ SCISSORS }), - PAPER({ ROCK }), - SCISSORS({ PAPER }) +enum class Move(val strongAgainst: () -> Set) { + ROCK({ setOf(SCISSORS, LIZARD) }), + PAPER({ setOf(ROCK, SPOCK) }), + SCISSORS({ setOf(PAPER, LIZARD) }), + LIZARD({ setOf(SPOCK, PAPER) }), + SPOCK({ setOf(SCISSORS, ROCK) }), } // purposely not calling this Result to avoid confusion with kotlin.Result and similar diff --git a/src/test/kotlin/rps/GameTest.kt b/src/test/kotlin/rps/GameTest.kt index c5eb5a3..2447261 100644 --- a/src/test/kotlin/rps/GameTest.kt +++ b/src/test/kotlin/rps/GameTest.kt @@ -13,6 +13,9 @@ class GameTest { Triple(ROCK, PAPER, LOSS), Triple(PAPER, SCISSORS, LOSS), Triple(ROCK, ROCK, DRAW), + Triple(ROCK, LIZARD, WIN), + Triple(LIZARD, SPOCK, WIN), + Triple(SPOCK, PAPER, LOSS), ) for ((first, second, expected) in games) { assertEquals(determineOutcome(first, second), expected)