ScoreSystem.java
package com.skloch.game;
import java.util.*;
public class ScoreSystem {
private static ScoreSystem instance;
private final Map<String, Float> activityCounts;
private final Map<String, Float> activityTotalScores;
private final Map<String, Map<Integer, Integer>> activityHistory;
private ScoreSystem() {
activityCounts = new HashMap<>();
activityTotalScores = new HashMap<>();
activityHistory = new HashMap<>();
// Initialize activity histories with counts set to 0
activityHistory.put("Eat", new HashMap<>());
activityHistory.put("Sleep", new HashMap<>());
activityHistory.put("Study", new HashMap<>());
activityHistory.put("Fun", new HashMap<>());
// Initialize activity types with counts set to 0
activityCounts.put("Eat", 0f);
activityCounts.put("Sleep", 0f);
activityCounts.put("Study", 0f);
activityCounts.put("Fun", 0f);
// Initialize activity types with total scores set to 0
activityTotalScores.put("Eat", 0f);
activityTotalScores.put("Sleep", 0f);
activityTotalScores.put("Study", 0f);
activityTotalScores.put("Fun", 0f);
}
public static ScoreSystem getInstance() {
if (instance == null) {
instance = new ScoreSystem();
}
return instance;
}
public void incrementActivity(String activityType, float currentEnergy, String achievementBadge, int activityTime, int currentDay) {
activityCounts.put(activityType, activityCounts.get(activityType) + 1);
// Random score from 100-current energy to 100
float randomScore = (float) (Math.random() * (100 - currentEnergy + 1)) + currentEnergy;
// update the history
Map<Integer, Integer> history = activityHistory.get(activityType);
history.put(currentDay, history.getOrDefault(currentDay, 0) + 1);
// Check for consecutive days and calculate streak multiplier
int streakCount = getStreakCount(history, currentDay);
float streakMultiplier = getStreakMultiplier(history, currentDay);
// Apply streak multiplier
float streakMultipliedScore = randomScore * streakMultiplier;
// Apply diminishing returns for consecutive activities on the same day
int consecutiveCount = history.get(currentDay);
float diminishingMultiplier = (float) Math.pow(0.9, consecutiveCount - 1);
float diminishedScore = streakMultipliedScore * diminishingMultiplier;
// Apply activity time multiplier
float hoursMultiplier = getHoursMultiplier(activityTime);
float hoursMultipliedScore = hoursMultiplier * diminishedScore;
// Apply the multiplier based on the achievement tier
float badgeMultiplier = getBadgeMultiplier(achievementBadge);
float badgeMultipliedScore = hoursMultipliedScore * badgeMultiplier;
// Clamp the final score between 0 and 100
float finalScore = Math.max(0, Math.min(badgeMultipliedScore, 100));
// Add the clamped score to the activity total score
activityTotalScores.put(activityType, activityTotalScores.get(activityType) + finalScore);
System.out.println(activityType + " was done " + activityCounts.get(activityType) + " times and has a total score of " + activityTotalScores.get(activityType) + ".");
System.out.println("Current " + activityType + " streak: " + streakCount + " days in a row.");
System.out.println(activityType + " performed " + consecutiveCount + " times on day " + currentDay + ".");
}
private float getBadgeMultiplier(String achievementTier) {
switch (achievementTier) {
case "Bronze":
return 1.05f;
case "Silver":
return 1.1f;
case "Gold":
return 1.15f;
case "Diamond":
return 1.2f;
default:
return 1.0f;
}
}
private float getHoursMultiplier(int activityTime) {
switch (activityTime) {
case 3:
return 1.12f;
case 4:
return 1.25f;
case 5:
return 1.35f;
case 6:
return 1.40f;
default:
return 1.0f;
}
}
private float getStreakMultiplier(Map<Integer, Integer> history, int currentDay) {
int streakCount = getStreakCount(history, currentDay);
// Streak multipliers based on the number of consecutive days
switch (streakCount) {
case 3:
return 1.02f;
case 4:
return 1.05f;
case 5:
return 1.08f;
case 6:
return 1.12f;
case 7:
return 1.15f;
default:
return 1.0f;
}
}
private int getStreakCount(Map<Integer, Integer> history, int currentDay) {
int streakCount = 0;
while (history.containsKey(currentDay - streakCount)) {
streakCount++;
}
return streakCount;
}
private String getStreakName(String activityType, int streakCount) {
Map<String, String[]> streakNames = new HashMap<>();
streakNames.put("Eat", new String[] {"Nibbler", "Foodie", "Gourmet"});
streakNames.put("Sleep", new String[] {"Napper", "Sleeper", "Dreamer"});
streakNames.put("Study", new String[] {"Reader", "Scholar", "Bookworm"});
streakNames.put("Fun", new String[] {"Adventurer", "Enthusiast", "Joy Seeker"});
if (!streakNames.containsKey(activityType) || streakCount < 3) {
return ""; // No streak name for counts less than 3
}
String[] names = streakNames.get(activityType);
switch (streakCount) {
case 3:
case 4:
return names[0];
case 5:
case 6:
return names[1];
case 7:
return names[2];
default:
return "";
}
}
/* to prevent getting a really high score for sleeping without even sleeping
for percentage calculations check if the player slept at least 6 times to divide total score by sleep count
else divide it by 6. this way if the player slept 4 times, it will be 400/6 instead of 400/4. */
public float calculatePercentage(String activityType) {
float totalScore = activityTotalScores.getOrDefault(activityType, 0f);
float count = activityCounts.getOrDefault(activityType, 0f);
float divisor = Math.max(count, 6); // Ensures we divide by either the count or 6, whichever is greater
if (divisor == 0) {
return 0; // To avoid division by zero
}
return (totalScore / divisor) * 100; // Multiplied by 100 to get a percentage
}
public Map<String, Float> getActivityTotalScores() {
return activityTotalScores;
}
public Map<String, Float> getActivityCounts() {
return activityCounts;
}
public Map<String, Map<Integer, Integer>> getHistory() {
return activityHistory;
}
}