Add perfect clear tracking to StatsManager and fix XP calculation

This commit is contained in:
cmclark00 2025-04-01 05:12:04 -04:00
parent 22fd887037
commit df9957580e
7 changed files with 50 additions and 14 deletions

View file

@ -301,7 +301,14 @@ class MainActivity : AppCompatActivity(),
statsManager.updateSessionStats(finalScore, gameBoard.lines, piecesPlaced, timePlayedMs, currentLevel) statsManager.updateSessionStats(finalScore, gameBoard.lines, piecesPlaced, timePlayedMs, currentLevel)
// Handle progression - XP earned, potential level up // Handle progression - XP earned, potential level up
val xpGained = progressionManager.calculateGameXP(finalScore, gameBoard.lines, currentLevel, timePlayedMs, statsManager.getSessionQuads(), 0) val xpGained = progressionManager.calculateGameXP(
score = finalScore,
lines = gameBoard.lines,
level = currentLevel,
timePlayedMs = timePlayedMs,
quadCount = statsManager.getSessionQuads(),
perfectClearCount = statsManager.getSessionPerfectClears()
)
val newRewards = progressionManager.addXP(xpGained) val newRewards = progressionManager.addXP(xpGained)
// Show progression screen if player earned XP // Show progression screen if player earned XP
@ -471,9 +478,9 @@ class MainActivity : AppCompatActivity(),
score = score, score = score,
lines = gameBoard.lines, lines = gameBoard.lines,
level = currentLevel, level = currentLevel,
gameTime = gameTime, timePlayedMs = gameTime,
quadCount = statsManager.getSessionQuads(), quadCount = statsManager.getSessionQuads(),
perfectClearCount = 0 // Implement perfect clear tracking if needed perfectClearCount = statsManager.getSessionPerfectClears()
) )
// Add XP and check for rewards // Add XP and check for rewards
@ -911,7 +918,14 @@ class MainActivity : AppCompatActivity(),
statsManager.updateSessionStats(finalScore, gameBoard.lines, piecesPlaced, timePlayedMs, currentLevel) statsManager.updateSessionStats(finalScore, gameBoard.lines, piecesPlaced, timePlayedMs, currentLevel)
// Handle progression - XP earned, potential level up // Handle progression - XP earned, potential level up
val xpGained = progressionManager.calculateGameXP(finalScore, gameBoard.lines, currentLevel, timePlayedMs, statsManager.getSessionQuads(), 0) val xpGained = progressionManager.calculateGameXP(
score = finalScore,
lines = gameBoard.lines,
level = currentLevel,
timePlayedMs = timePlayedMs,
quadCount = statsManager.getSessionQuads(),
perfectClearCount = statsManager.getSessionPerfectClears()
)
val newRewards = progressionManager.addXP(xpGained) val newRewards = progressionManager.addXP(xpGained)
// Show progression screen if player earned XP // Show progression screen if player earned XP

View file

@ -95,13 +95,13 @@ class PlayerProgressionManager(context: Context) {
*/ */
fun calculateGameXP(score: Int, lines: Int, level: Int, timePlayedMs: Long, fun calculateGameXP(score: Int, lines: Int, level: Int, timePlayedMs: Long,
quadCount: Int, perfectClearCount: Int): Long { quadCount: Int, perfectClearCount: Int): Long {
val scoreXP = score * SCORE_XP_MULTIPLIER val scoreXP = (score * SCORE_XP_MULTIPLIER).toLong()
val linesXP = lines * LINES_XP_MULTIPLIER * level val linesXP = (lines * LINES_XP_MULTIPLIER).toLong()
val quadBonus = quadCount * QUAD_XP_BONUS * (1 - (level - 1) * 0.05).coerceAtLeast(0.5) val quadBonus = (quadCount * QUAD_XP_BONUS).toLong()
val perfectClearBonus = perfectClearCount * PERFECT_CLEAR_XP_BONUS val perfectClearBonus = (perfectClearCount * 100).toLong()
val timeBonus = (timePlayedMs / 1000) * TIME_XP_MULTIPLIER val timeBonus = (timePlayedMs * TIME_XP_MULTIPLIER).toLong()
return (scoreXP + linesXP + quadBonus + perfectClearBonus + timeBonus).toLong() return scoreXP + linesXP + quadBonus + perfectClearBonus + timeBonus
} }
/** /**
@ -318,6 +318,11 @@ class PlayerProgressionManager(context: Context) {
THEME_MINIMALIST to 20, THEME_MINIMALIST to 20,
THEME_GALAXY to 25 THEME_GALAXY to 25
) )
private const val SCORE_XP_MULTIPLIER = 0.1
private const val LINES_XP_MULTIPLIER = 5
private const val QUAD_XP_BONUS = 50
private const val TIME_XP_MULTIPLIER = 0.01
} }
/** /**

View file

@ -35,6 +35,10 @@ class StatsManager(context: Context) {
private var sessionTriples: Int = 0 private var sessionTriples: Int = 0
private var sessionQuads: Int = 0 private var sessionQuads: Int = 0
// Perfect clear stats
private var sessionPerfectClears: Int = 0
private var totalPerfectClears: Int = 0
init { init {
loadStats() loadStats()
} }
@ -54,6 +58,9 @@ class StatsManager(context: Context) {
totalDoubles = prefs.getInt(KEY_TOTAL_DOUBLES, 0) totalDoubles = prefs.getInt(KEY_TOTAL_DOUBLES, 0)
totalTriples = prefs.getInt(KEY_TOTAL_TRIPLES, 0) totalTriples = prefs.getInt(KEY_TOTAL_TRIPLES, 0)
totalQuads = prefs.getInt(KEY_TOTAL_QUADS, 0) totalQuads = prefs.getInt(KEY_TOTAL_QUADS, 0)
// Load perfect clear stats
totalPerfectClears = prefs.getInt(KEY_TOTAL_PERFECT_CLEARS, 0)
} }
private fun saveStats() { private fun saveStats() {
@ -70,6 +77,7 @@ class StatsManager(context: Context) {
.putInt(KEY_TOTAL_DOUBLES, totalDoubles) .putInt(KEY_TOTAL_DOUBLES, totalDoubles)
.putInt(KEY_TOTAL_TRIPLES, totalTriples) .putInt(KEY_TOTAL_TRIPLES, totalTriples)
.putInt(KEY_TOTAL_QUADS, totalQuads) .putInt(KEY_TOTAL_QUADS, totalQuads)
.putInt(KEY_TOTAL_PERFECT_CLEARS, totalPerfectClears)
.apply() .apply()
} }
@ -83,6 +91,7 @@ class StatsManager(context: Context) {
sessionDoubles = 0 sessionDoubles = 0
sessionTriples = 0 sessionTriples = 0
sessionQuads = 0 sessionQuads = 0
sessionPerfectClears = 0
} }
fun updateSessionStats(score: Int, lines: Int, pieces: Int, time: Long, level: Int) { fun updateSessionStats(score: Int, lines: Int, pieces: Int, time: Long, level: Int) {
@ -157,6 +166,10 @@ class StatsManager(context: Context) {
fun getSessionTriples(): Int = sessionTriples fun getSessionTriples(): Int = sessionTriples
fun getSessionQuads(): Int = sessionQuads fun getSessionQuads(): Int = sessionQuads
// Getters for perfect clear stats
fun getSessionPerfectClears(): Int = sessionPerfectClears
fun getTotalPerfectClears(): Int = totalPerfectClears
fun resetStats() { fun resetStats() {
// Reset all lifetime stats // Reset all lifetime stats
totalGames = 0 totalGames = 0
@ -174,6 +187,9 @@ class StatsManager(context: Context) {
totalTriples = 0 totalTriples = 0
totalQuads = 0 totalQuads = 0
// Reset perfect clear stats
totalPerfectClears = 0
// Save the reset stats // Save the reset stats
saveStats() saveStats()
} }
@ -192,5 +208,6 @@ class StatsManager(context: Context) {
private const val KEY_TOTAL_DOUBLES = "total_doubles" private const val KEY_TOTAL_DOUBLES = "total_doubles"
private const val KEY_TOTAL_TRIPLES = "total_triples" private const val KEY_TOTAL_TRIPLES = "total_triples"
private const val KEY_TOTAL_QUADS = "total_quads" private const val KEY_TOTAL_QUADS = "total_quads"
private const val KEY_TOTAL_PERFECT_CLEARS = "total_perfect_clears"
} }
} }

View file

@ -592,7 +592,7 @@
android:fontFamily="sans-serif" /> android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionTetrisesText" android:id="@+id/sessionQuadsText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"

View file

@ -117,7 +117,7 @@
android:layout_marginBottom="4dp"/> android:layout_marginBottom="4dp"/>
<TextView <TextView
android:id="@+id/totalTetrisesText" android:id="@+id/totalQuadsText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"

View file

@ -266,7 +266,7 @@
android:fontFamily="sans-serif" /> android:fontFamily="sans-serif" />
<TextView <TextView
android:id="@+id/sessionTetrisesText" android:id="@+id/sessionQuadsText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"

View file

@ -101,7 +101,7 @@
android:layout_marginBottom="4dp"/> android:layout_marginBottom="4dp"/>
<TextView <TextView
android:id="@+id/totalTetrisesText" android:id="@+id/totalQuadsText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/white" android:textColor="@color/white"