wip: play
This commit is contained in:
parent
4566efc7f7
commit
f75d844633
6 changed files with 143 additions and 4 deletions
|
@ -114,7 +114,7 @@ fun HomeScreen(
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
enabled = currentSelection != null,
|
enabled = currentSelection != null,
|
||||||
onClick = { navController.navigate(PLAY) }) {
|
onClick = { navController.navigate("$PLAY/${currentSelection?.idSet}") }) {
|
||||||
Text(text = context.getString(R.string.main_button_start), fontSize = 30.sp)
|
Text(text = context.getString(R.string.main_button_start), fontSize = 30.sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,15 @@ fun MainScreen() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable(PLAY) { PlayScreen(padding, navController) }
|
composable("$PLAY/{$PLAY_SET_ARG}") {
|
||||||
|
it.arguments?.getString(PLAY_SET_ARG)?.let { idSet ->
|
||||||
|
PlayScreen(
|
||||||
|
padding,
|
||||||
|
navController,
|
||||||
|
idSet.toInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,78 @@
|
||||||
package fr.uparis.diamantkennel.memorisationapplication
|
package fr.uparis.diamantkennel.memorisationapplication
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.util.Log
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import fr.uparis.diamantkennel.memorisationapplication.ui.AnswerType
|
||||||
import fr.uparis.diamantkennel.memorisationapplication.ui.PlayViewModel
|
import fr.uparis.diamantkennel.memorisationapplication.ui.PlayViewModel
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayScreen(
|
fun PlayScreen(
|
||||||
padding: PaddingValues,
|
padding: PaddingValues,
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
|
idSet: Int,
|
||||||
model: PlayViewModel = viewModel()
|
model: PlayViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
|
// First update the list and set ID
|
||||||
|
model.setId.value = idSet
|
||||||
|
model.updateQuestionList(idSet)
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
Toast.makeText(context, "Start", Toast.LENGTH_SHORT).show()
|
val question by model.currentQuestion
|
||||||
|
if (question == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val reponse by model.proposedAnswer
|
||||||
|
val correction by model.evaluatedAnswer
|
||||||
|
|
||||||
|
if (correction == AnswerType.GOOD) {
|
||||||
|
Log.d("1312", "Bonne réponse !")
|
||||||
|
model.newQuestion()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (correction == AnswerType.BAD) {
|
||||||
|
Log.d("1312", "Mauvaise réponse !")
|
||||||
|
model.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(padding),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(text = question!!.enonce)
|
||||||
|
OutlinedTextField(
|
||||||
|
value = reponse,
|
||||||
|
label = { Text(text = "Réponse") },
|
||||||
|
onValueChange = model::updateAnswer
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
Button(onClick = model::checkAnswer) {
|
||||||
|
Text(text = "Répondre")
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
enabled = false /* TODO: s'activer au bout de 3 secondes */,
|
||||||
|
onClick = { /*TODO*/ }) {
|
||||||
|
Text(text = "Voir réponse")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,4 @@ const val HOME = "home"
|
||||||
const val MODIFY_SET = "modify_set"
|
const val MODIFY_SET = "modify_set"
|
||||||
const val MODIFY_SET_ARGS = "id_set"
|
const val MODIFY_SET_ARGS = "id_set"
|
||||||
const val PLAY = "play"
|
const val PLAY = "play"
|
||||||
|
const val PLAY_SET_ARG = "id_set"
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package fr.uparis.diamantkennel.memorisationapplication.ui
|
||||||
|
|
||||||
|
enum class AnswerType {
|
||||||
|
NONE, GOOD, BAD
|
||||||
|
}
|
|
@ -1,10 +1,77 @@
|
||||||
package fr.uparis.diamantkennel.memorisationapplication.ui
|
package fr.uparis.diamantkennel.memorisationapplication.ui
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import fr.uparis.diamantkennel.memorisationapplication.MemoApplication
|
import fr.uparis.diamantkennel.memorisationapplication.MemoApplication
|
||||||
|
import fr.uparis.diamantkennel.memorisationapplication.data.Question
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class PlayViewModel(application: Application) : AndroidViewModel(application) {
|
class PlayViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private val dao = (application as MemoApplication).database.memoDao()
|
private val dao = (application as MemoApplication).database.memoDao()
|
||||||
|
private val initialId = -1 // invalid ID, mean that we don't have the ID yet
|
||||||
|
|
||||||
|
var setId = mutableStateOf(initialId)
|
||||||
|
private var questions = dao.loadQuestions(setId.value)
|
||||||
|
|
||||||
|
var currentQuestion = mutableStateOf<Question?>(null)
|
||||||
|
private var index = mutableStateOf(0)
|
||||||
|
|
||||||
|
var proposedAnswer = mutableStateOf("")
|
||||||
|
var evaluatedAnswer = mutableStateOf(AnswerType.NONE)
|
||||||
|
|
||||||
|
fun updateQuestionList(setId: Int) {
|
||||||
|
if (setId != initialId) {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
questions = dao.loadQuestions(setId)
|
||||||
|
updateQuestion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateQuestion() {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
questions.collect { questionList ->
|
||||||
|
if (index.value >= questionList.size) {
|
||||||
|
index.value = 0
|
||||||
|
}
|
||||||
|
currentQuestion.value = questionList[index.value]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
proposedAnswer.value = ""
|
||||||
|
evaluatedAnswer.value = AnswerType.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newQuestion() {
|
||||||
|
reset()
|
||||||
|
index.value += 1
|
||||||
|
updateQuestion()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateAnswer(text: String) {
|
||||||
|
proposedAnswer.value = text
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calcSimilarite(str1: String, str2: String): Float {
|
||||||
|
val set1 = str1.lowercase().toSet()
|
||||||
|
val set2 = str2.lowercase().toSet()
|
||||||
|
|
||||||
|
return set1.intersect(set2).size.toFloat() / set1.union(set2).size.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkAnswer() {
|
||||||
|
val probaReponse = calcSimilarite(currentQuestion.value!!.reponse, proposedAnswer.value)
|
||||||
|
if (probaReponse >= .60f) {
|
||||||
|
evaluatedAnswer.value = AnswerType.GOOD
|
||||||
|
} else {
|
||||||
|
evaluatedAnswer.value = AnswerType.BAD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue