Putting it all together: the number decomposition quiz
Okay, so we did our first maths challenge, but multiplication is pretty easy. Let’s try something a bit more advanced: decomposing a number into factors; this will put into practice some things we saw previously.
Make sure to add this code below the previous QiChat, not to replace it - so that now, if you say “challenge me”, pepper will ask you one or another of the questions.
u:(challenge me) %DECOMPOSE_CHALLENGE
Can you decompose 28 as the product of two numbers?
u1:({it's} 7 times 4)
Right!
u1:(*)
Wrong!
Now, if we were to try to randomize this the same way we did before, but we’ll have the issue that there are a lot of ways of giving this answer, such as: * 4 x 7 * 2 x 14 * 1 x 28 … we could enumerate all these possibilities, but this would make our code needlessly complicated.
Instead let’s use a ^execute statement, by passing parameters:
concept:(small_number) [2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
concept:(times) [times ×]
u:(challenge me) %DECOMPOSE_CHALLENGE
Can you decompose, $result as the product of two numbers? $show="? × ? ≟ $result"
u1:({it's} _~small_number _~times _~small_number)
$1 $2 $3 $factorA=$1 $factorB=$3 $show="$factorA × $factorB ≟ $result" let's see ...
^execute(evaluateDecomposition, $factorA , $factorB )
proposal: %RESULT_RIGHT
$show="right!" Yes, you're right %RERANDOMIZE $show=" "
proposal: %RESULT_WRONG
$show="$factorA × $factorB ≠ $result" No, $factorA times $factorB equals $wrongResult %RERANDOMIZE $show=" "
To keep things simple, use the same randomize function as before. Previously, the multiplication result was a local variable, now save it as a member variable so you can access it later on:
var multiplicationResult = -1
private fun randomize() {
val numberA = Random.nextInt(3, 9)
val numberB = Random.nextInt(3, 9)
multiplicationResult = numberA * numberB
// ...
}
And in onRobotFocusGained, two changes:
* Add a new evaluateDecomposition executor
* At start, go to the DECOMPOSE_CHALLENGE bookmark
override fun onRobotFocusGained(qiContext: QiContext) {
// ...
// Executors
val executors : Map<String, QiChatExecutor> = hashMapOf(
"drumRoll" to DrumRollExecutor(qiContext),
"evaluateDecomposition" to EvaluateDecompositionExecutor(qiContext)
)
qiChatbot.executors = executors
// Start the dialogue
chat.addOnStartedListener { goToBookmark("DECOMPOSE_CHALLENGE") }
chat.run()
}
Create the executor as an inner class:
private inner class EvaluateDecompositionExecutor(qiContext: QiContext) :
BaseQiChatExecutor(qiContext) {
override fun runWith(params: List<String>) {
Log.i(TAG, "Running with: $params")
if (params.size >= 2) {
val firstFactor = params[0].toInt()
val secondFactor = params[1].toInt()
if (firstFactor * secondFactor == multiplicationResult) {
goToBookmark("RESULT_RIGHT")
} else {
goToBookmark("RESULT_WRONG")
qiChatbot?.variable("wrongResult")?.value = (firstFactor * secondFactor).toString()
}
}
}
override fun stop() {}
}
... and now your pepper will ask you slightly more difficult question, putting together bookmarks, variables and ^execute.