← Назад к курсу

🧠 Урок 4: Умные алгоритмы

Создаём интеллектуальную игру с помощником и подсказками

🎯 Цель урока

В этом уроке мы превратим простую игру в интеллектуальную систему. Изучим бинарный поиск, создадим ИИ-помощника, систему подсказок и адаптивную сложность.

Ты узнаешь, как алгоритмы могут сделать игру умнее, как анализировать поведение игрока и предоставлять персонализированную помощь.

🔍 Демонстрация бинарного поиска

Посмотри, как ИИ угадывает число за минимальное количество попыток:

Загадай число от 1 до 15:
ИИ думает: Готов угадывать!
Попытка: 0 | ИИ предполагает: -

🔍 Алгоритм бинарного поиска

Бинарный поиск - это умный алгоритм, который находит число за минимальное количество попыток, каждый раз исключая половину возможных вариантов.

🔍 Реализация бинарного поиска
// Класс ИИ-помощника с бинарным поиском
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).

📊 Система уровней сложности

Адаптивные уровни делают игру интересной для всех:

🟢 Лёгкий

1 - 50
Попыток: 7

Отличный старт для новичков

🟡 Средний

1 - 100
Попыток: 8

Классическая игра

🟠 Сложный

1 - 500
Попыток: 10

Для опытных игроков

🔴 Экстрим

1 - 1000
Попыток: 12

Максимальный вызов!

📊 Система сложности
// Конфигурация уровней сложности
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;
    }
}

💡 Умная система подсказок

Контекстные подсказки помогают игроку учиться и улучшать стратегию:

🎯 Математические

Подсказки о диапазоне и оптимальной стратегии поиска

"Попробуй число 50 - это середина диапазона 1-100"

🧠 Стратегические

Советы по улучшению подхода к решению

"Используй метод деления пополам для быстрого поиска"

📊 Статистические

Анализ предыдущих попыток и паттернов

"Твои числа слишком близко. Попробуй больший шаг"

🏆 Мотивационные

Поддержка и вдохновение для продолжения игры

"Отлично! Ещё 2 попытки и ты найдёшь число!"
💡 Система умных подсказок
// Генератор контекстных подсказок
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';
    }
}

⚡ Сравнение эффективности алгоритмов

Посмотри, насколько бинарный поиск быстрее линейного:

🐌 Линейный поиск

В худшем случае: все числа подряд

100 попыток

Средне: 50 попыток

🚀 Бинарный поиск

Гарантированно оптимально

7 попыток

Всегда: ≤ 7 попыток

Бинарный поиск в 14 раз быстрее!

🧠 Твоё задание

Создай интеллектуальную систему для игры "Угадай число":

  1. Реализуй класс AIHelper с бинарным поиском
  2. Добавь систему уровней сложности с адаптацией
  3. Создай умную систему подсказок
  4. Реализуй анализ поведения игрока
  5. Добавь ИИ-помощника с объяснениями
  6. Создай систему достижений за эффективность
  7. Реализуй статистику и аналитику
  8. Добавь обучающий режим с пошаговыми объяснениями
  9. Протестируй все алгоритмы на разных диапазонах

💡 Помни: умная игра учит игрока быть лучше!

Следующий урок: Система достижений →