Skip to content

Instantly share code, notes, and snippets.

@Judrummer
Last active September 23, 2018 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Judrummer/d477785f1e2b73e911e8d83d7055ad5b to your computer and use it in GitHub Desktop.
Save Judrummer/d477785f1e2b73e911e8d83d7055ad5b to your computer and use it in GitHub Desktop.
package io.bigbear.judrummer
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun CoroutineScope.hangman(secretWord: String, letterStream: ReceiveChannel<Char>) = produce {
var result = Result(
secretWordLength = secretWord.length,
knownSecretWord = List(secretWord.length) { '_' }.joinToString("")
)
val secretWordIndex = secretWord.withIndex()
send(result)
for (letter in letterStream) {
val containIndexs = secretWordIndex.filter { it.value == letter }.map { it.index }
val lifeLeft = if (containIndexs.isEmpty()) result.lifeLeft - 1 else result.lifeLeft
val knownSecretWord = result.knownSecretWord.mapIndexed { index, char -> if (containIndexs.contains(index)) letter else char }.joinToString("")
val status = if (knownSecretWord == secretWord) Status.WON else if (lifeLeft == 0) Status.LOSE else Status.IN_PROGRESS
result = result.copy(
status = status,
selectedLetter = result.selectedLetter.toMutableList().apply { add(letter) },
lifeLeft = lifeLeft,
knownSecretWord = knownSecretWord)
send(result)
if (result.status != Status.IN_PROGRESS) close()
}
close()
}
enum class Status {
IN_PROGRESS,
WON,
LOSE
}
data class Result(
val status: Status = Status.IN_PROGRESS,
val selectedLetter: List<Char> = emptyList(),
val lifeLeft: Int = 7,
val secretWordLength: Int = 0,
val knownSecretWord: String = ""
)
package io.bigbear.judrummer
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.runBlocking
import org.junit.*
class HangManTest {
@Test
fun testA() {
val testList = listOf(
'b' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b'),
lifeLeft = 7,
secretWordLength = 7,
knownSecretWord = "b__b___"),
'o' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "b__b___"),
'i' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'i'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "bi_b___"),
'g' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'i', 'g'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "bigb___"),
'a' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'i', 'g', 'a'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "bigb_a_"),
'e' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'i', 'g', 'a', 'e'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "bigbea_"),
'y' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'i', 'g', 'a', 'e', 'y'),
lifeLeft = 5,
secretWordLength = 7,
knownSecretWord = "bigbea_"
),
'r' to Result(
status = Status.WON,
selectedLetter = listOf('b', 'o', 'i', 'g', 'a', 'e', 'y', 'r'),
lifeLeft = 5,
secretWordLength = 7,
knownSecretWord = "bigbear"
)
)
runHangmanTest("bigbear", testList)
}
@Test
fun testB() {
val testList = listOf(
'b' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b'),
lifeLeft = 7,
secretWordLength = 7,
knownSecretWord = "b__b___"),
'o' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "b__b___"),
'a' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "b__b_a_"),
'e' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e'),
lifeLeft = 6,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
'n' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n'),
lifeLeft = 5,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
'u' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n', 'u'),
lifeLeft = 4,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
't' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n', 'u', 't'),
lifeLeft = 3,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
'z' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n', 'u', 't', 'z'),
lifeLeft = 2,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
'x' to Result(
status = Status.IN_PROGRESS,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n', 'u', 't', 'z', 'x'),
lifeLeft = 1,
secretWordLength = 7,
knownSecretWord = "b__bea_"),
'v' to Result(
status = Status.LOSE,
selectedLetter = listOf('b', 'o', 'a', 'e', 'n', 'u', 't', 'z', 'x', 'v'),
lifeLeft = 0,
secretWordLength = 7,
knownSecretWord = "b__bea_"
)
)
runHangmanTest("bigbear", testList)
}
fun runHangmanTest(secretWord: String, testList: List<Pair<Char, Result>>) = runBlocking<Unit> {
val inputChannel = Channel<Char>()
val resultChannel = hangman(secretWord, inputChannel)
resultChannel.receive() shouldEqual Result(
status = Status.IN_PROGRESS,
selectedLetter = emptyList(),
lifeLeft = 7,
secretWordLength = 7,
knownSecretWord = "_______"
)
testList.forEach { (input, result) ->
inputChannel.send(input)
resultChannel.receive() shouldEqual result
}
inputChannel.cancel()
}
}
infix fun Any?.shouldEqual(other: Any?) = Assert.assertEquals(other, this)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment