Класс системы челленджей
class ChallengeSystem { constructor() { this.challenges = [];
this.activeDaily = []; this.activeWeekly = []; this.playerProgress =
{}; this.challengeTemplates = this.initializeTemplates(); }
initializeTemplates() { return { daily: [ { id: 'daily_wins', title:
'Мастер угадывания', description: 'Выиграй {target} игр', icon: '🎯',
target: 3, reward: { xp: 100, coins: 50 }, type: 'wins' }, { id:
'daily_speed', title: 'Скоростной гений', description: 'Выиграй игру
за {target} секунд', icon: '⚡', target: 30, reward: { xp: 150, coins:
75 }, type: 'time' }, { id: 'daily_attempts', title: 'Точность',
description: 'Угадай число с {target} попыток', icon: '🎪', target: 3,
reward: { xp: 200, coins: 100 }, type: 'attempts' } ], weekly: [ { id:
'weekly_streak', title: 'Недельный чемпион', description: 'Играй
{target} дней подряд', icon: '🔥', target: 7, reward: { xp: 1000,
coins: 500, badge: 'weekly_champion' }, type: 'streak' }, { id:
'weekly_score', title: 'Охотник за очками', description: 'Набери
{target} очков за неделю', icon: '💎', target: 2000, reward: { xp:
800, coins: 400 }, type: 'score' } ], seasonal: [ { id:
'seasonal_master', title: 'Мастер сезона', description: 'Выиграй
{target} игр в этом сезоне', icon: '👑', target: 100, reward: { xp:
5000, coins: 2500, badge: 'season_master' }, type: 'seasonal_wins' } ]
}; } // Генерация новых ежедневных челленджей
generateDailyChallenges() { this.activeDaily = []; // Выбираем 3
случайных челленджа const shuffled =
this.shuffleArray([...this.challengeTemplates.daily]); for (let i = 0;
i < 3; i++) { const template = shuffled[i]; const challenge = {
...template, id: `${template.id}_${Date.now()}_${i}`, progress: 0,
completed: false, expiresAt: this.getTomorrowMidnight(), createdAt:
Date.now() }; this.activeDaily.push(challenge); }
this.saveToStorage(); } // Проверка выполнения челленджа
checkProgress(actionType, actionData) { const allChallenges =
[...this.activeDaily, ...this.activeWeekly];
allChallenges.forEach(challenge => { if (challenge.completed) return;
switch (challenge.type) { case 'wins': if (actionType === 'game_won')
{ challenge.progress++; } break; case 'time': if (actionType ===
'game_won' && actionData.time <= challenge.target) {
challenge.progress = 1; } break; case 'attempts': if (actionType ===
'game_won' && actionData.attempts <= challenge.target) {
challenge.progress = 1; } break; case 'score': if (actionType ===
'score_gained') { challenge.progress += actionData.amount; } break;
case 'streak': if (actionType === 'daily_play') { challenge.progress =
this.getCurrentStreak(); } break; } // Проверяем завершение if
(challenge.progress >= challenge.target) {
this.completeChallenge(challenge); } }); this.saveToStorage(); } //
Завершение челленджа completeChallenge(challenge) {
challenge.completed = true; challenge.completedAt = Date.now(); //
Начисляем награды this.giveReward(challenge.reward); // Показываем
уведомление this.showCompletionNotification(challenge); // Записываем
в статистику this.recordChallengeCompletion(challenge); } // Выдача
наград giveReward(reward) { if (reward.xp) { // Добавляем опыт
this.addExperience(reward.xp); } if (reward.coins) { // Добавляем
монеты this.addCoins(reward.coins); } if (reward.badge) { // Выдаем
значок this.unlockBadge(reward.badge); } } // Получение прогресса
челленджа в процентах getChallengeProgress(challenge) { return
Math.min((challenge.progress / challenge.target) * 100, 100); } //
Проверка истечения челленджей checkExpiredChallenges() { const now =
Date.now(); this.activeDaily = this.activeDaily.filter(challenge => {
if (challenge.expiresAt <= now && !challenge.completed) {
this.onChallengeExpired(challenge); return false; } return true; });
// Если нет активных ежедневных челленджей, генерируем новые if
(this.activeDaily.length === 0) { this.generateDailyChallenges(); } }
// Сохранение в localStorage saveToStorage() { const data = {
activeDaily: this.activeDaily, activeWeekly: this.activeWeekly,
playerProgress: this.playerProgress, lastUpdate: Date.now() };
localStorage.setItem('challengeSystem', JSON.stringify(data)); } //
Загрузка из localStorage loadFromStorage() { const saved =
localStorage.getItem('challengeSystem'); if (saved) { const data =
JSON.parse(saved); this.activeDaily = data.activeDaily || [];
this.activeWeekly = data.activeWeekly || []; this.playerProgress =
data.playerProgress || {}; // Проверяем истекшие челленджи
this.checkExpiredChallenges(); } else {
this.generateDailyChallenges(); } } // Вспомогательные функции
shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] =
[array[j], array[i]]; } return array; } getTomorrowMidnight() { const
tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(0, 0, 0, 0); return tomorrow.getTime(); }
getCurrentStreak() { // Здесь должна быть логика подсчета текущей
серии return this.playerProgress.currentStreak || 0; } }