feat: types de questions et générateur (tables 1..maxTable)
This commit is contained in:
4 files changed
+119
No files matched your search
@@ -0,0 +1,10 @@
|
||||
package com.livrets.game
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class GameConfig(
|
||||
val questionCount: Int, // 5..50
|
||||
val secondsPerQuestion: Int, // 3..30
|
||||
val maxTable: Int, // 1..12 : les deux facteurs sont tirés dans 1..maxTable
|
||||
)
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.livrets.game
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface Question {
|
||||
val table: Int
|
||||
|
||||
@Serializable
|
||||
@SerialName("direct")
|
||||
data class Direct(val a: Int, val b: Int) : Question {
|
||||
override val table: Int get() = maxOf(a, b)
|
||||
override fun toString(): String = "$a × $b = ?"
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@SerialName("missing_factor")
|
||||
data class MissingFactor(val a: Int, val b: Int) : Question {
|
||||
override val table: Int get() = maxOf(a, b)
|
||||
override fun toString(): String = "$a × ? = ${a * b}"
|
||||
}
|
||||
}
|
||||
|
||||
val Question.correctAnswer: Int
|
||||
get() = when (this) {
|
||||
is Question.Direct -> a * b
|
||||
is Question.MissingFactor -> b
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.livrets.game
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
fun interface QuestionSource {
|
||||
fun next(previous: Question?, maxTable: Int): Question
|
||||
}
|
||||
|
||||
class QuestionGenerator(private val random: Random = Random.Default) : QuestionSource {
|
||||
override fun next(previous: Question?, maxTable: Int): Question {
|
||||
while (true) {
|
||||
val a = random.nextInt(1, maxTable + 1)
|
||||
val b = random.nextInt(1, maxTable + 1)
|
||||
val question =
|
||||
if (random.nextBoolean()) Question.Direct(a, b) else Question.MissingFactor(a, b)
|
||||
if (question != previous) return question
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.livrets.game
|
||||
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class QuestionGeneratorTest {
|
||||
|
||||
@Test
|
||||
fun `tous les facteurs restent dans 1 a maxTable`() {
|
||||
val generator = QuestionGenerator(Random(42))
|
||||
repeat(500) {
|
||||
val q = generator.next(previous = null, maxTable = 6)
|
||||
val (a, b) = when (q) {
|
||||
is Question.Direct -> q.a to q.b
|
||||
is Question.MissingFactor -> q.a to q.b
|
||||
}
|
||||
assertTrue(a in 1..6, "a=$a hors bornes")
|
||||
assertTrue(b in 1..6, "b=$b hors bornes")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `les deux formes de question sont produites`() {
|
||||
val generator = QuestionGenerator(Random(7))
|
||||
val questions = List(200) { generator.next(previous = null, maxTable = 12) }
|
||||
assertTrue(questions.any { it is Question.Direct })
|
||||
assertTrue(questions.any { it is Question.MissingFactor })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pas de doublon consecutif`() {
|
||||
val generator = QuestionGenerator(Random(123))
|
||||
var previous: Question? = null
|
||||
repeat(300) {
|
||||
val q = generator.next(previous, 12)
|
||||
assertNotEquals(previous, q)
|
||||
previous = q
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `table vaut le plus grand facteur`() {
|
||||
assertEquals(8, Question.Direct(3, 8).table)
|
||||
assertEquals(9, Question.MissingFactor(9, 4).table)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bonne reponse selon la forme`() {
|
||||
assertEquals(56, Question.Direct(7, 8).correctAnswer)
|
||||
assertEquals(8, Question.MissingFactor(7, 8).correctAnswer)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `affichage des deux formes`() {
|
||||
assertEquals("7 × 8 = ?", Question.Direct(7, 8).toString())
|
||||
assertEquals("7 × ? = 56", Question.MissingFactor(7, 8).toString())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user