Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import com.thechance.qurio.domain.repository.AchievementsRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton

class AchievementsRepositoryImpl @Inject constructor(private val context: Context) : AchievementsRepository {
class AchievementsRepositoryImpl @Inject constructor(private val context: Context) :
AchievementsRepository {
private val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)

override suspend fun getAllAchievements(): List<Achievement> = withContext(Dispatchers.IO) {
Expand All @@ -29,12 +29,18 @@ class AchievementsRepositoryImpl @Inject constructor(private val context: Contex
(prefs.getStringSet(KEY_UNLOCKED, emptySet())?.toMutableSet() ?: mutableSetOf())
currentAchievementsSet.add(id.toString())
prefs.edit { putStringSet(KEY_UNLOCKED, currentAchievementsSet) }

}

override suspend fun isAchievementUnlocked(id: Int): Boolean = withContext(Dispatchers.IO) {
(prefs.getStringSet(KEY_UNLOCKED, emptySet()) ?: emptySet()).contains(id.toString())
}

override suspend fun getUnlockedAchievementsCount(): Int {
val unlockedAchievements = prefs.getStringSet(KEY_UNLOCKED, emptySet()) ?: emptySet()
return unlockedAchievements.size
}

companion object {
private const val PREFS_NAME = "achievements_prefs"
private const val KEY_UNLOCKED = "unlocked_ids"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.thechance.qurio.data.repository

import android.content.Context
import androidx.core.content.edit
import com.thechance.qurio.domain.repository.game.GameProgressRepository
import javax.inject.Inject
import javax.inject.Singleton

class GameProgressRepositoryImpl @Inject constructor(private val context: Context) :
GameProgressRepository {
private val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)

override suspend fun getQuizzesCompleted(): Int = prefs.getInt(KEY_QUIZZES_COMPLETED, 0)

override suspend fun incrementQuizzesCompleted() {
val currentQuizzesCompleted = getQuizzesCompleted() + 1
prefs.edit { putInt(KEY_QUIZZES_COMPLETED, currentQuizzesCompleted) }
}

override suspend fun getCategoriesPlayed(): Int = prefs.getInt(KEY_CATEGORIES_PLAYED, 0)

override suspend fun incrementCategoriesPlayed() {
val currentCategoriesPlayed = getCategoriesPlayed() + 1
prefs.edit { putInt(KEY_CATEGORIES_PLAYED, currentCategoriesPlayed) }
}

override suspend fun getQuestionsAnswered(): Int = prefs.getInt(KEY_QUESTIONS_ANSWERED, 0)

override suspend fun incrementQuestionsAnswered(){
val currentQuestionsAnswered = getQuestionsAnswered() + 1
prefs.edit { putInt(KEY_QUESTIONS_ANSWERED, currentQuestionsAnswered) }
}

companion object {
private const val KEY_QUESTIONS_ANSWERED = "questions_answered"
private const val KEY_QUIZZES_COMPLETED = "quizzes_completed"
private const val KEY_CATEGORIES_PLAYED = "categories_played"
private const val PREFS_NAME = "game_progress_prefs"
}
}
6 changes: 0 additions & 6 deletions app/src/main/java/com/thechance/qurio/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,7 @@ import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.room.Room
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.thechance.qurio.data.ApiService
import com.thechance.qurio.data.local.UserDataSource
import com.thechance.qurio.data.local.dao.GameSessionDao
import com.thechance.qurio.data.util.LoggingInterceptor
import com.thechance.qurio.presentation.main.QurioApp
import com.thechance.qurio.data.remote.service.GameService
import com.thechance.qurio.data.repository.GameRepositoryImpl
import com.thechance.qurio.domain.repository.game.GameRepository
import com.thechance.qurio.data.local.dao.PlayedGameDao
import com.thechance.qurio.data.local.database.QurioDatabase
import com.thechance.qurio.data.remote.service.GameService
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/com/thechance/qurio/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.thechance.qurio.di
import com.thechance.qurio.data.repository.AchievementsRepositoryImpl
import com.thechance.qurio.data.repository.CharactersRepositoryImpl
import com.thechance.qurio.data.repository.ExampleRepositoryImpl
import com.thechance.qurio.data.repository.GameProgressRepositoryImpl
import com.thechance.qurio.data.repository.TGameRepository
import com.thechance.qurio.data.repository.TGameRepositoryImpl
import com.thechance.qurio.data.repository.GameSessionRepository
Expand All @@ -12,10 +13,10 @@ import com.thechance.qurio.data.repository.UserPreferencesRepositoryImpl
import com.thechance.qurio.data.repository.GameRepositoryImpl
import com.thechance.qurio.data.repository.UserRepositoryImpl
import com.thechance.qurio.domain.repository.AchievementsRepository
import com.thechance.qurio.domain.repository.CharactersRepository
import com.thechance.qurio.domain.repository.ExampleRepository
import com.thechance.qurio.domain.repository.ResultsRepository
import com.thechance.qurio.domain.repository.UserPreferencesRepository
import com.thechance.qurio.domain.repository.game.GameProgressRepository
import com.thechance.qurio.domain.repository.game.GameRepository
import com.thechance.qurio.domain.repository.user.UserRepository
import dagger.Binds
Expand Down Expand Up @@ -68,4 +69,9 @@ abstract class RepositoryModule {
abstract fun bindCharacterRepository(
impl: CharactersRepositoryImpl
): CharactersRepository

@Binds
abstract fun bindGameProgressRepository(
impl: GameProgressRepositoryImpl
): GameProgressRepository
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ interface AchievementsRepository {
suspend fun getAchievementById(id: Int): Achievement?
suspend fun unlockAchievement(id: Int)
suspend fun isAchievementUnlocked(id: Int): Boolean
suspend fun getUnlockedAchievementsCount(): Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.thechance.qurio.domain.repository.game

interface GameProgressRepository {
suspend fun incrementQuizzesCompleted()
suspend fun getQuizzesCompleted(): Int
suspend fun incrementCategoriesPlayed()
suspend fun getCategoriesPlayed(): Int
suspend fun incrementQuestionsAnswered()
suspend fun getQuestionsAnswered(): Int
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.thechance.qurio.presentation.main

import android.graphics.Color
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.thechance.qurio.presentation.screen.achievements

import com.thechance.qurio.domain.entity.Achievement
import com.thechance.qurio.domain.repository.AchievementsRepository
import com.thechance.qurio.domain.repository.game.GameProgressRepository
import jakarta.inject.Inject

class AchievementsManager @Inject constructor(
private val gameProgressRepository: GameProgressRepository,
private val achievementsRepository: AchievementsRepository
) {

suspend fun checkAndUnlockAchievements(
maxCorrectStreak: Int,
firstAnswerCorrect: Boolean,
scorePercent: Int,
totalQuestions: Int,
correctAnswers: Int,
fastestCorrectAnswerTime: Long
): List<Achievement> {
val unlocked = mutableListOf<Achievement>()

checkQuizzesCompleted(unlocked)
checkCategoriesPlayed(unlocked)
checkStreaks(maxCorrectStreak, unlocked)
checkLuckyGuess(firstAnswerCorrect, unlocked)
checkTriviaChamp(scorePercent, unlocked)
checkUntouchable(maxCorrectStreak, unlocked)
checkQuickThinker(fastestCorrectAnswerTime, unlocked)
checkPerfectGame(correctAnswers, totalQuestions, unlocked)
checkKnowledgeSeeker(unlocked)
checkCollector(unlocked)

return unlocked
}

private suspend fun checkQuizzesCompleted(unlocked: MutableList<Achievement>) {
gameProgressRepository.incrementQuizzesCompleted()
val quizzesCompleted = gameProgressRepository.getQuizzesCompleted()

if (quizzesCompleted == 5) unlockAchievement(1, unlocked)
if (quizzesCompleted == 50) unlockAchievement(7, unlocked)
}

private suspend fun checkCategoriesPlayed(unlocked: MutableList<Achievement>) {
gameProgressRepository.incrementCategoriesPlayed()
if (gameProgressRepository.getCategoriesPlayed() >= 4)
unlockAchievement(4, unlocked)
}

private suspend fun checkStreaks(maxCorrectStreak: Int, unlocked: MutableList<Achievement>) {
if (maxCorrectStreak >= 3) unlockAchievement(2, unlocked)
}

private suspend fun checkLuckyGuess(
firstAnswerCorrect: Boolean,
unlocked: MutableList<Achievement>
) {
if (firstAnswerCorrect) unlockAchievement(3, unlocked)
}

private suspend fun checkTriviaChamp(scorePercent: Int, unlocked: MutableList<Achievement>) {
if (scorePercent >= 80) unlockAchievement(5, unlocked)
}

private suspend fun checkUntouchable(
maxCorrectStreak: Int,
unlocked: MutableList<Achievement>
) {
if (maxCorrectStreak >= 10) unlockAchievement(8, unlocked)
}

private suspend fun checkQuickThinker(
fastestCorrectAnswerTime: Long,
unlocked: MutableList<Achievement>
) {
if (fastestCorrectAnswerTime < 3000) unlockAchievement(9, unlocked)
}

private suspend fun checkPerfectGame(
correctAnswers: Int,
totalQuestions: Int,
unlocked: MutableList<Achievement>
) {
if (totalQuestions > 0 && correctAnswers == totalQuestions)
unlockAchievement(10, unlocked)
}

private suspend fun checkKnowledgeSeeker(unlocked: MutableList<Achievement>) {
gameProgressRepository.incrementQuestionsAnswered()
if (gameProgressRepository.getQuestionsAnswered() >= 100)
unlockAchievement(11, unlocked)
}

private suspend fun checkCollector(unlocked: MutableList<Achievement>) {
val unlockedCount = achievementsRepository.getAllAchievements().count { it.isUnlocked }
if (unlockedCount >= 5) unlockAchievement(6, unlocked)
}

private suspend fun unlockAchievement(id: Int, unlocked: MutableList<Achievement>) {
if (!achievementsRepository.isAchievementUnlocked(id)) {
achievementsRepository.unlockAchievement(id)
achievementsRepository.getAchievementById(id)?.let { unlocked.add(it) }
}
}
}
Loading
Loading