review feedback
This commit is contained in:
parent
5237cad9a4
commit
10d70c6f84
@ -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<Outcome>.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<Move> instead.
|
||||
*/
|
||||
enum class Move(val strongAgainst: () -> Move) {
|
||||
ROCK({ SCISSORS }),
|
||||
PAPER({ ROCK }),
|
||||
SCISSORS({ PAPER })
|
||||
enum class Move(val strongAgainst: () -> Set<Move>) {
|
||||
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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user