🎯 Цель урока
В этом уроке мы превратим простую игру в интеллектуальную систему. Изучим бинарный поиск, создадим ИИ-помощника, систему подсказок и адаптивную сложность.
Ты узнаешь, как алгоритмы могут сделать игру умнее, как анализировать поведение игрока и предоставлять персонализированную помощь.
🔍 Демонстрация бинарного поиска
Посмотри, как ИИ угадывает число за минимальное количество попыток:
🔍 Алгоритм бинарного поиска
Бинарный поиск - это умный алгоритм, который находит число за минимальное количество попыток, каждый раз исключая половину возможных вариантов.
// Класс ИИ-помощника с бинарным поиском class AIHelper { constructor(minRange, maxRange) { this.originalMin = minRange; this.originalMax = maxRange; this.reset(); } // Сброс для новой игры reset() { this.minRange = this.originalMin; this.maxRange = this.originalMax; this.attempts = 0; this.suggestions = []; } // Получить следующее предположение ИИ getNextGuess() { this.attempts++; // Бинарный поиск: выбираем середину диапазона const guess = Math.floor((this.minRange + this.maxRange) / 2); this.suggestions.push({ attempt: this.attempts, guess: guess, range: [this.minRange, this.maxRange], reasoning: this.getReasoningText(guess) }); return guess; } // Обновить диапазон поиска на основе результата updateRange(guess, result) { if (result === 'high') { // Загаданное число меньше - убираем верхнюю половину this.maxRange = guess - 1; } else if (result === 'low') { // Загаданное число больше - убираем нижнюю половину this.minRange = guess + 1; } // Проверяем, что диапазон ещё валиден if (this.minRange > this.maxRange) { throw new Error('Невозможный диапазон! Проверь правильность ответов.'); } } // Генерируем текст объяснения логики ИИ getReasoningText(guess) { const rangeSize = this.maxRange - this.minRange + 1; const maxSteps = Math.ceil(Math.log2(rangeSize)); return `Выбираю середину диапазона ${this.minRange}-${this.maxRange}. Это исключит ~${Math.floor(rangeSize/2)} чисел. Максимум попыток: ${maxSteps}`; } // Получить подсказку для игрока getPlayerHint(playerAttempts, playerGuesses) { if (playerAttempts < 3) { return "Пробуй разные числа, чтобы понять диапазон!"; } // Анализируем паттерн поведения игрока const lastGuesses = playerGuesses.slice(-3); const isRandomGuessing = this.detectRandomPattern(lastGuesses); if (isRandomGuessing) { return "💡 Совет: попробуй метод 'деления пополам' - всегда выбирай середину!"; } // Предлагаем оптимальную следующую попытку const optimalGuess = this.getNextGuess(); return `🤖 Я бы попробовал число ${optimalGuess}. Хочешь увидеть почему?`; } // Определяем, угадывает ли игрок случайно detectRandomPattern(guesses) { if (guesses.length < 3) return false; // Проверяем, есть ли логика в последовательности const differences = []; for (let i = 1; i < guesses.length; i++) { differences.push(Math.abs(guesses[i] - guesses[i-1])); } // Если различия слишком случайны, предлагаем стратегию const avgDifference = differences.reduce((a, b) => a + b, 0) / differences.length; return avgDifference > (this.originalMax - this.originalMin) * 0.3; } }
Бинарный поиск гарантирует нахождение любого числа в диапазоне 1-100 максимум за 7 попыток (⌈log₂(100)⌉ = 7).
📊 Система уровней сложности
Адаптивные уровни делают игру интересной для всех:
🟢 Лёгкий
Отличный старт для новичков
🟡 Средний
Классическая игра
🟠 Сложный
Для опытных игроков
🔴 Экстрим
Максимальный вызов!
// Конфигурация уровней сложности const DIFFICULTY_LEVELS = { easy: { name: 'Лёгкий', range: [1, 50], maxAttempts: 7, hints: true, aiHelperEnabled: true, description: 'Идеально для начинающих' }, medium: { name: 'Средний', range: [1, 100], maxAttempts: 8, hints: true, aiHelperEnabled: false, description: 'Классическая игра' }, hard: { name: 'Сложный', range: [1, 500], maxAttempts: 10, hints: false, aiHelperEnabled: false, description: 'Для опытных игроков' }, extreme: { name: 'Экстрим', range: [1, 1000], maxAttempts: 12, hints: false, aiHelperEnabled: false, description: 'Максимальный вызов!' } }; // Адаптивная система сложности class DifficultyManager { constructor() { this.currentLevel = 'easy'; this.playerStats = { gamesWon: 0, totalGames: 0, averageAttempts: 0 }; } // Получить текущую конфигурацию getCurrentConfig() { return DIFFICULTY_LEVELS[this.currentLevel]; } // Предложить повышение уровня suggestLevelUp() { const winRate = this.playerStats.gamesWon / this.playerStats.totalGames; const isGoodPlayer = winRate > 0.7 && this.playerStats.averageAttempts < 5; if (isGoodPlayer && this.playerStats.totalGames >= 3) { return this.getNextLevel(); } return null; } // Получить следующий уровень getNextLevel() { const levels = ['easy', 'medium', 'hard', 'extreme']; const currentIndex = levels.indexOf(this.currentLevel); return currentIndex < levels.length - 1 ? levels[currentIndex + 1] : null; } }
💡 Умная система подсказок
Контекстные подсказки помогают игроку учиться и улучшать стратегию:
🎯 Математические
Подсказки о диапазоне и оптимальной стратегии поиска
🧠 Стратегические
Советы по улучшению подхода к решению
📊 Статистические
Анализ предыдущих попыток и паттернов
🏆 Мотивационные
Поддержка и вдохновение для продолжения игры
// Генератор контекстных подсказок class HintSystem { constructor(gameConfig) { this.config = gameConfig; this.usedHints = new Set(); } // Получить подходящую подсказку getHint(gameState) { const { attempts, guesses, maxAttempts, range } = gameState; const remainingAttempts = maxAttempts - attempts; // Раннняя стадия игры if (attempts <= 2) { return this.getEarlyGameHint(range); } // Середина игры if (remainingAttempts > 2) { return this.getMidGameHint(guesses, range); } // Критическая ситуация return this.getCriticalHint(guesses, range, remainingAttempts); } // Подсказки для начала игры getEarlyGameHint(range) { const [min, max] = range; const middle = Math.floor((min + max) / 2); const hints = [ `🎯 Попробуй начать с середины: ${middle}`, `💡 Начни с числа ${middle} - это оптимально!`, `🧠 Стратегия: всегда выбирай середину доступного диапазона` ]; return this.getUnusedHint(hints); } // Подсказки для середины игры getMidGameHint(guesses, range) { const lastGuess = guesses[guesses.length - 1]; const pattern = this.analyzePattern(guesses); if (pattern === 'random') { return '🔄 Попробуй систематический подход вместо случайных чисел'; } if (pattern === 'sequential') { return '⚡ Переходи к большим шагам - метод деления пополам быстрее!'; } // Предлагаем оптимальный следующий ход const optimalNext = this.calculateOptimalGuess(guesses, range); return `🤖 Оптимальный выбор: попробуй ${optimalNext}`; } // Критические подсказки getCriticalHint(guesses, range, remaining) { if (remaining === 1) { const bestGuess = this.calculateOptimalGuess(guesses, range); return `🎯 ПОСЛЕДНЯЯ ПОПЫТКА! Попробуй ${bestGuess}`; } return '🔥 Осталось мало попыток! Думай логически!'; } // Анализ паттерна игрока analyzePattern(guesses) { if (guesses.length < 3) return 'unknown'; const differences = []; for (let i = 1; i < guesses.length; i++) { differences.push(guesses[i] - guesses[i-1]); } // Проверяем на последовательность const avgDifference = Math.abs(differences.reduce((a, b) => a + b) / differences.length); if (avgDifference <= 5) return 'sequential'; if (avgDifference > 20) return 'random'; return 'strategic'; } }
⚡ Сравнение эффективности алгоритмов
Посмотри, насколько бинарный поиск быстрее линейного:
🐌 Линейный поиск
В худшем случае: все числа подряд
Средне: 50 попыток
🚀 Бинарный поиск
Гарантированно оптимально
Всегда: ≤ 7 попыток
Бинарный поиск в 14 раз быстрее!
🧠 Твоё задание
Создай интеллектуальную систему для игры "Угадай число":
- Реализуй класс AIHelper с бинарным поиском
- Добавь систему уровней сложности с адаптацией
- Создай умную систему подсказок
- Реализуй анализ поведения игрока
- Добавь ИИ-помощника с объяснениями
- Создай систему достижений за эффективность
- Реализуй статистику и аналитику
- Добавь обучающий режим с пошаговыми объяснениями
- Протестируй все алгоритмы на разных диапазонах
💡 Помни: умная игра учит игрока быть лучше!