From 00d9b12f56d4073ab8c17fd91b2a5ef88fb16906 Mon Sep 17 00:00:00 2001 From: tomivt Date: Fri, 28 Mar 2025 09:29:51 +0100 Subject: [PATCH] feat: Add Random Quiz --- .../data/local/QuestionStub.kt | 4 + .../ui/navigations/AppNavigator.kt | 20 ++- .../ui/screens/QuizEndPage.kt | 11 +- .../what_the_fantasy/ui/screens/QuizMenu.kt | 74 +++++++- .../what_the_fantasy/ui/screens/QuizRandom.kt | 159 ++++++++++++++++++ 5 files changed, 259 insertions(+), 9 deletions(-) create mode 100644 What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/QuestionStub.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/QuestionStub.kt index 19833ec..317518c 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/QuestionStub.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/data/local/QuestionStub.kt @@ -97,4 +97,8 @@ object QuestionStub { val allQuestions: List = listOf( question1, question2, question3, question4, question5, question6, question7, question8, question9, question10 ) + + val allQuestionsShuffled: List = listOf( + question1, question2, question3, question4, question5, question6, question7, question8, question9, question10 + ).shuffled() } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt index 7af2928..1e50e85 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/navigations/AppNavigator.kt @@ -37,6 +37,9 @@ data class Quiz(val userIndex: Int, val idQuiz: Int) @Serializable data class QuizEnd(val userIndex: Int, val idQuiz: Int, val pts: Int) +@Serializable +data class QuizRandom(val userIndex: Int) + @Serializable data class OneQuote(val quoteId: Int, val userIndex: Int) @@ -199,7 +202,8 @@ fun AppNavigator() { navSearch = { navController.navigate(Search(quizMenu.userIndex))}, navControllerQuiz = { idQuiz -> navController.navigate(Quiz(quizMenu.userIndex, idQuiz)) - } + }, + navControllerRandomQuiz = { navController.navigate(QuizRandom(quizMenu.userIndex)) } ) } composable { @@ -228,6 +232,20 @@ fun AppNavigator() { navSearch = { navController.navigate(Search(quizEnd.userIndex))} ) } + + composable { + val quizRandom: QuizRandom = it.toRoute() + QuizRandom( + navAccueil = { navController.navigate(Accueil(quizRandom.userIndex)) }, + navFavorite = { navController.navigate(Favorite(quizRandom.userIndex)) }, + navProfil = { navController.navigate(Profil(quizRandom.userIndex)) }, + navQuiz = { navController.navigate(QuizMenu(quizRandom.userIndex)) }, + navSearch = { navController.navigate(Search(quizRandom.userIndex)) }, + navControllerQuizEnd = { idQuiz, pts -> + navController.navigate(QuizEnd(quizRandom.userIndex, idQuiz, pts)) + }, + ) + } } } } diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt index 6b4bcf9..cbd6c6d 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizEndPage.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset +import androidx.compose.material3.MaterialTheme import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle @@ -15,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.example.what_the_fantasy.data.local.QuestionStub import com.example.what_the_fantasy.data.local.QuizStub import com.example.what_the_fantasy.ui.components.NavBar @@ -65,16 +67,16 @@ fun QuizEndPage( Spacer(modifier = Modifier.height(16.dp)) Column( modifier = Modifier - .background(brush = gradient, shape = RoundedCornerShape(20.dp)) + .background(color = MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp)) .padding(30.dp) .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceEvenly ) { - val quiz = QuizStub.getQuizById(idQuiz) - val nbQuestions = quiz?.questions?.size + val quizName = if (idQuiz == -1) "Random Quiz" else QuizStub.getQuizById(idQuiz)?.name ?: "Quiz Inconnu" + Text( - text = "${quiz?.name}", + text = quizName, color = Color.White, style = TextStyle( fontSize = 25.sp, @@ -82,6 +84,7 @@ fun QuizEndPage( textAlign = TextAlign.Center ) ) + val nbQuestions = QuestionStub.allQuestionsShuffled.size Text( text = "Nombres de Questions : $nbQuestions", color = Color.White, diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt index 1131b43..5fb37bf 100644 --- a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizMenu.kt @@ -3,6 +3,7 @@ package com.example.what_the_fantasy.ui.screens import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -12,6 +13,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll @@ -38,7 +40,8 @@ fun QuizMenu( navAccueil: () -> Unit, navProfil:() -> Unit, navSearch: () -> Unit, - navControllerQuiz: (Int) -> Unit + navControllerQuiz: (Int) -> Unit, + navControllerRandomQuiz:() -> Unit ) { NavBar(onQuiz = true, navControllerFavorite = navFavorite, @@ -47,13 +50,16 @@ fun QuizMenu( navControllerSearch = navSearch ) { - Column( - modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background) + Row( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .horizontalScroll(state = rememberScrollState()) ) { // Contenu princiapl Column( modifier = Modifier - .weight(0.9f) + .width(400.dp) .fillMaxSize() .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally @@ -119,6 +125,66 @@ fun QuizMenu( } } } + + Column( + modifier = Modifier + .width(400.dp) + .fillMaxSize() + .padding(20.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "▶ Mini-Jeux ◀", + color = MaterialTheme.colorScheme.onBackground, + style = TextStyle( + fontSize = 25.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + ) + Spacer(Modifier.height(20.dp)) + Column( + modifier = Modifier + .background(MaterialTheme.colorScheme.onPrimary, shape = RoundedCornerShape(20.dp)) + .fillMaxSize() + .padding(vertical = 30.dp) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val context = LocalContext.current + val imageResId = context.resources.getIdentifier( + "quiz", + "drawable", + context.packageName + ) + Column( + modifier = Modifier + .size(width = 150.dp, height = 145.dp) + .clickable { navControllerRandomQuiz() }, + ) { + Image( + painter = painterResource(id = imageResId), + contentDescription = "Random Quiz", + modifier = Modifier + .size(width = 150.dp, height = 100.dp) + .clip(shape = RoundedCornerShape(20.dp)), + contentScale = ContentScale.Crop + ) + Spacer(Modifier.height(10.dp)) + Text( + text = "Random Quiz", + style = TextStyle( + fontSize = 17.sp, + fontWeight = FontWeight.Medium, + textAlign = TextAlign.Center, + color = MaterialTheme.colorScheme.primary + ) + ) + } + } + } } + + } } \ No newline at end of file diff --git a/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt new file mode 100644 index 0000000..b038774 --- /dev/null +++ b/What_The_Fantasy/app/src/main/java/com/example/what_the_fantasy/ui/screens/QuizRandom.kt @@ -0,0 +1,159 @@ +package com.example.what_the_fantasy.ui.screens + +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.what_the_fantasy.data.local.QuestionStub +import com.example.what_the_fantasy.ui.components.NavBar + +@Composable +fun QuizRandom( + navFavorite: () -> Unit, + navAccueil: () -> Unit, + navProfil:() -> Unit, + navQuiz: () -> Unit, + navSearch: () -> Unit, + navControllerQuizEnd: (Int, Int) -> Unit, +) { + val questions = QuestionStub.allQuestionsShuffled + var idCurrentQuestion by remember { mutableIntStateOf(0) } + var pts by remember { mutableIntStateOf(0) } + var lifes by remember { mutableIntStateOf(3) } + + val gradient = Brush.linearGradient( + colors = listOf(MaterialTheme.colorScheme.onPrimary, MaterialTheme.colorScheme.onPrimary), + start = Offset(0f, 1000f), + end = Offset(1000f, 0f) + ) + + fun onAnswerSelected(answer: String) { + val currentQuestion = questions[idCurrentQuestion] + val correctAnswer = mapOf( + "A" to currentQuestion.ansA, + "B" to currentQuestion.ansB, + "C" to currentQuestion.ansC, + "D" to currentQuestion.ansD + )[currentQuestion.correctAns] + + if (answer == correctAnswer) pts++ + else { + lifes -= 1 + Log.d("Quiz Debug", "Lifes -1 :, $lifes") + } + if (idCurrentQuestion < questions.size - 1 && lifes > 0) idCurrentQuestion++ + else { + navControllerQuizEnd(-1, pts) + Log.d("Quiz Debug", "Game over lifes : $lifes") + } // Retour menu + } + NavBar( + navControllerFavorite = navFavorite, + navControllerAccueil = navAccueil, + navControllerProfil = navProfil, + navControllerQuiz = navQuiz, + navControllerSearch = navSearch + ){ + Column ( + modifier = Modifier.fillMaxSize().background(Color(0xFF100C1B)) + ) { + // Contenu princiapl + Column( + modifier = Modifier + .weight(0.8f) + .fillMaxWidth() + .padding(horizontal = 50.dp, vertical = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + val question = questions[idCurrentQuestion] + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + if (questions != null) { + Text( + text = "▶ Random Quiz ◀", + color = Color.White, + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + ) + } + Spacer(Modifier.height(20.dp)) + Column( + modifier = Modifier + .background(brush = gradient, shape = RoundedCornerShape(20.dp)) + .height(800.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + "Question ${idCurrentQuestion + 1}", + color = Color.White, + fontSize = 18.sp, + modifier = Modifier + .padding(top = 20.dp) + .weight(0.1f), + style = TextStyle( + fontSize = 25.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + ) + Text( + question.question, + color = Color.White, + fontSize = 15.sp, + modifier = Modifier + .padding(horizontal = 25.dp) + .weight(0.1f), + textAlign = TextAlign.Center + ) + Column( + modifier = Modifier + .weight(0.7f) + .fillMaxHeight() + .padding(vertical = 30.dp), + verticalArrangement = Arrangement.SpaceBetween + + ) { + listOf( + question.ansA, + question.ansB, + question.ansC, + question.ansD + ).forEach { answer -> + Box( + modifier = Modifier + .width(220.dp) + .height(50.dp) + .background(Color.White, shape = RoundedCornerShape(16.dp)) + .clickable { onAnswerSelected(answer) } + .padding(horizontal = 8.dp), + contentAlignment = Alignment.Center + ) { + Text(answer, color = Color.Black, fontSize = 18.sp) + } + } + } + } + } + } + } + } +} \ No newline at end of file