• Я зарабатываю 100 000 RUB / месяц на этом сайте!

    А знаешь как? Я всего-лишь публикую (создаю темы), а админ мне платит. Трачу деньги на мороженое, робуксы и сервера в Minecraft. А ещё на паль из Китая. 

    Хочешь так же? Пиши и узнавай условия: https://t.me/alex_redact
    Реклама: https://t.me/yougame_official

Исходник Advanced Random System

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
18 Июн 2022
Сообщения
323
Реакции
14
Выберите загрузчик игры
  1. OptiFine
  2. ForgeOptiFine
Нашёл в своём старом проекте, есть как простые stealth-генераторы для int, double, float, так и интересные с разными паттернами. Сам использовал в киллауре для ротаций.

AdvancedRandUtil:
Expand Collapse Copy
package minecraft.system;

import lombok.experimental.UtilityClass;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@UtilityClass
public class AdvancedRandUtil{
    private final SecureRandom baseRandom = new SecureRandom();
    private static final int LAYERS = 9;
    private static final int[] PRIMES = {0x9E3779B1, 0x85EBCA77, 0xC2B2AE3D};
    private static double lastValue = Double.NaN;
    private static int counter = 0;

    private static double lastVelocity = 0.0; // Добавлено для инерции
    private static int fatigueCounter = 0;    // Отдельный счетчик для усталости
    public int stealthInt(int minLimit, int maxLimit) {
        if (minLimit >= maxLimit) return minLimit;

        // Инициализация каскада
        int[] layers = new int[7];
        layers[0] = minLimit + baseRandom.nextInt(maxLimit - minLimit + 1);

        // Главный каскад случайности
        for (int i = 1; i < layers.length; i++) {
            int range = maxLimit - minLimit + 1;

            // Динамические параметры для текущего слоя
            int noiseFactor = 1 + baseRandom.nextInt(3);
            int shiftBits = baseRandom.nextInt(8);
            int directionFlag = baseRandom.nextInt(2);

            // Генерация шума с расширением диапазона
            int expandedRange = range * (2 + noiseFactor);
            int noise = baseRandom.nextInt(expandedRange) - (expandedRange / 2);

            // Нелинейные преобразования
            layers[i] = applyNonLinearTransform(
                    layers[i - 1],
                    minLimit,
                    maxLimit,
                    noise,
                    shiftBits,
                    directionFlag
            );
        }

        // Финальная стабилизация в целевом диапазоне
        return stabilize(layers[layers.length - 1], minLimit, maxLimit);
    }

    private int applyNonLinearTransform(int value, int min, int max, int noise, int shift, int direction) {
        // Динамическое изменение значения
        int transformed = (value ^ (value << shift)) + noise;

        // Обратная связь с предыдущими значениями
        transformed = (transformed & 0x5555_5555) | ((transformed & 0xAAAA_AAAA) >>> 1);

        // Направленное смещение
        if (direction == 0) {
            transformed = Integer.rotateLeft(transformed, shift);
        } else {
            transformed = Integer.rotateRight(transformed, shift);
        }

        // Псевдо-стабилизация
        return (transformed % (max - min + 1)) + min;
    }

    private int stabilize(int value, int min, int max) {
        // Многоэтапная стабилизация
        for (int i = 0; i < 3; i++) {
            int range = max - min + 1;
            int mid = min + range / 2;

            // Квадратичное сжатие к центру
            int offset = (value - mid) * (value - mid) / range;
            value = mid + (value > mid ? -offset : offset);

            // Коррекция границ
            if (value < min) value += range;
            if (value > max) value -= range;
        }

        // Гарантированное возвращение в диапазон
        return Math.min(Math.max(value, min), max);
    }

    public static double stealthDouble(double min, double max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        double value = entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = fractalDistortion(value, min, max, i);
        }

        return constrain(value, min, max);
    }

    public static float stealthFloat(float min, float max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        float value = (float) entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = (float) fractalDistortion(value, min, max, i);
        }

        return (float) constrain(value, min, max);
    }

    private static double entropyWave(long seed) {
        long state = seed ^ 0xDEADBEEFFACADE00L;
        state = (state ^ (state >>> 30)) * PRIMES[0];
        state = (state ^ (state >>> 27)) * PRIMES[1];
        state = (state ^ (state >>> 31)) | PRIMES[2];
        return Double.longBitsToDouble(state);
    }

    private static double fractalDistortion(double input, double min, double max, int layer) {
        double range = max - min;
        long bits = Double.doubleToRawLongBits(input);

        // Хаотические преобразования
        Random rand = ThreadLocalRandom.current();
        bits ^= (bits << (layer * 9 + 5)) | (bits >>> (layer * 7 + 11));
        bits = Long.rotateLeft(bits, rand.nextInt(64));
        bits += rand.nextLong() ^ PRIMES[layer % PRIMES.length];
        bits *= rand.nextBoolean() ? 1.6180339887 : 3.1415926535;

        // Фрактальное зашумление
        double noise = rand.nextDouble() * range / Math.pow(2, layer);
        double result = Double.longBitsToDouble(bits) * noise;

        // Нелинейное сжатие
        return Math.sin(result * Math.PI) * range * 0.5 + (min + max) * 0.5;
    }

    private static double constrain(double value, double min, double max) {
        // Квантовое ограничение с хаотической коррекцией
        if (value >= min && value <= max) return value;

        double scaled = Math.abs(value) % (max - min);
        return scaled + min - ((int)(scaled / (max - min)) * (max - min));
    }

    public enum PatternMode {
        LINEAR_SMOOTH,      // Плавные линейные изменения
        GAUSSIAN_CENTERED,  // Концентрация в центре диапазона
        EDGE_BIASED,        // Смещение к краям диапазона
        STEPPED,            // Ступенчатое изменение значений
        CHAOTIC_SMOOTH,      // Хаотичные но плавные переходы
        //humanaized:
        HUMAN_TREMOR,       // Мелкая дрожь как у человека
        SACCADIC_MOVEMENT,  // Скачкообразные движения глаз
        MICRO_CORRECTIONS,  // Микрокоррекции с возвратом
        INERTIA_SMOOTH,     // Движение с инерцией
        FATIGUE_DRIFT,       // Дрейф при усталости
        TREMOR_PREDICT,
        FATIGURE_ADVANCE,
        INTERIA_DECREATE
    }

    // Double генератор
    public static double LegitDouble(double min, double max, PatternMode mode) {
        if (min >= max) return min;

        double value;
        switch (mode) {
            case LINEAR_SMOOTH:
                value = linearSmooth(min, max);
                break;
            case GAUSSIAN_CENTERED:
                value = gaussianCentered(min, max);
                break;
            case EDGE_BIASED:
                value = edgeBiased(min, max);
                break;
            case STEPPED:
                value = stepped(min, max);
                break;
            case CHAOTIC_SMOOTH:
                value = chaoticSmooth(min, max);
                break;
            case HUMAN_TREMOR:
                value = humanTremor(min, max);
                break;
            case SACCADIC_MOVEMENT:
                value = saccadicMovement(min, max);
                break;
            case MICRO_CORRECTIONS:
                value =  microCorrections(min, max);
                break;
            case INERTIA_SMOOTH:
                value = inertiaSmooth(min, max);
                break;
            case FATIGUE_DRIFT:
                value = fatigueDrift(min, max);
                break;
            case TREMOR_PREDICT:
                value = Pred_Tremor(min, max);
                break;
            case INTERIA_DECREATE:
                value = interia2(min, max);
                break;
            case FATIGURE_ADVANCE:
                value = ADVfatigueDrift(min, max);
                break;
            default:
                value = baseRandom.nextDouble() * (max - min) + min;
        }

        lastValue = value;
        counter++;
        return value;
    }

    // Float генератор
    public static float LegitFloat(float min, float max, PatternMode mode) {
        return (float) LegitDouble(min, max, mode);
    }

    private static double Pred_Tremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор (8-12 Гц)
        double timeFactor = counter * 0.3;
        double tremorX = Math.sin(timeFactor * 25.3) * 0.4;
        double tremorY = Math.cos(timeFactor * 22.7) * 0.3;
        double tremorZ = Math.sin(timeFactor * 18.9) * 0.3;

        double tremor = (tremorX + tremorY + tremorZ) / 3.0;
        tremor *= 0.03 * (max - min); // Амплитуда 3% от диапазона

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.02 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    // Режимы работы
    private static double linearSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Плавное изменение с небольшой случайной дельтой
        double range = max - min;
        double step = range * 0.05 * (baseRandom.nextGaussian() + 0.3);
        double newValue = lastValue + step;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double target = min + range * (0.2 + 0.6 * baseRandom.nextDouble());
            return target;
        }

        return newValue;
    }

    private static double gaussianCentered(double min, double max) {
        double center = (min + max) / 2.0;
        double range = max - min;

        // Генерация с нормальным распределением
        double value = center + baseRandom.nextGaussian() * (range / 6.0);

        // Периодическая коррекция к центру
        if (counter % 5 == 0) {
            double offset = (value - center) * 0.7;
            value = center + offset;
        }

        // Гарантия в диапазоне
        return Math.max(min, Math.min(max, value));
    }

    private static double edgeBiased(double min, double max) {
        // Случайный выбор края
        double targetEdge = baseRandom.nextBoolean() ? min : max;

        // Генерация со смещением к краю
        double biasStrength = 0.7 + baseRandom.nextDouble() * 0.25;
        double value;

        if (targetEdge == min) {
            value = min + Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        } else {
            value = max - Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        }

        // Периодические "проверки" центра
        if (counter % 7 == 0) {
            double center = (min + max) / 2.0;
            value = center + (value - center) * 0.4;
        }

        return value;
    }

    private static double stepped(double min, double max) {
        double range = max - min;
        int steps = 5 + baseRandom.nextInt(6); // 5-10 ступеней

        // Определение текущей ступени
        int currentStep = (int) (steps * baseRandom.nextDouble());

        // Периодическое изменение ступеней
        if (counter % 4 == 0) {
            currentStep = (currentStep + 1 + baseRandom.nextInt(2)) % steps;
        }

        // Генерация значения в пределах ступени
        double stepSize = range / steps;
        double stepMin = min + currentStep * stepSize;
        double stepMax = stepMin + stepSize;

        return stepMin + baseRandom.nextDouble() * (stepMax - stepMin);
    }

    private static double chaoticSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Хаотичное но плавное изменение
        double range = max - min;
        double chaosFactor = 0.2 + baseRandom.nextDouble() * 0.5;
        double direction = baseRandom.nextBoolean() ? 1 : -1;

        // Нелинейное изменение
        double delta = range * chaosFactor * direction * Math.sin(counter * 0.5);
        double newValue = lastValue + delta;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double anchor = min + range * (0.1 + 0.8 * baseRandom.nextDouble());
            return anchor;
        }

        return newValue;
    }

    private static double humanTremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор
        double tremorIntensity = 0.02 + Math.sin(counter * 0.3) * 0.01;
        double tremor = Math.sin(counter * 12.7) * tremorIntensity * (max - min);

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.04 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    private static double saccadicMovement(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Длительность фиксации (200-500мс)
        int fixationDuration = 10 + baseRandom.nextInt(15);

        if(counter % fixationDuration == 0) {
            // Саккадический скачок
            double jumpSize = (max - min) * (0.1 + baseRandom.nextDouble() * 0.15);
            int direction = baseRandom.nextBoolean() ? 1 : -1;
            return constrain(lastValue + jumpSize * direction, min, max);
        }

        // Микродвижения во время фиксации
        return lastValue + baseRandom.nextGaussian() * 0.015 * (max - min);
    }

    private static double microCorrections(double min, double max) {
        double target = Double.isNaN(lastValue)
                ? min + (max - min) * (0.3 + baseRandom.nextDouble() * 0.4)
                : lastValue;

        // Периодические коррекции
        if(counter % (8 + baseRandom.nextInt(5)) == 0) {
            double overshoot = (max - min) * 0.08 * (baseRandom.nextGaussian() + 0.5);
            target += baseRandom.nextBoolean() ? overshoot : -overshoot;
        }

        // Постоянные микрокоррекции
        double correction = (target - lastValue) * 0.15 + baseRandom.nextGaussian() * 0.01;
        return constrain(lastValue + correction, min, max);
    }

    private static double inertiaSmooth(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        double velocity = Double.isNaN(lastVelocity)
                ? (max - min) * 0.005 * (baseRandom.nextGaussian() + 0.3)
                : lastVelocity * 0.85;

        // Случайное изменение направления
        if(baseRandom.nextDouble() < 0.07) {
            velocity *= -0.5 + baseRandom.nextDouble();
        }

        double newValue = lastValue + velocity;
        lastVelocity = velocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.7;
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double interia2(double min, double max){
        if(Double.isNaN(lastValue)) {
            // Инициализация
            lastVelocity = (baseRandom.nextGaussian() * 0.5 + 0.3) * (max - min) * 0.01;
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        lastVelocity *= 0.82;

        // Случайное ускорение
        if(baseRandom.nextDouble() < 0.12) {
            lastVelocity += (baseRandom.nextGaussian() * 0.7) * (max - min) * 0.005;
        }

        double newValue = lastValue + lastVelocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.65; // Отскок с потерей энергии
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double fatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + (max - min) * 0.5;
        }

        // Накопленная усталость
        double fatigueFactor = Math.min(1.0, counter / 300.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.4) * fatigueFactor * 0.08 * (max - min);

        // Периодические осознанные коррекции
        if(counter % (30 - (int)(fatigueFactor * 15)) == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.3 + baseRandom.nextDouble() * 0.4);
            drift += correction;
        }

        return constrain(lastValue + drift, min, max);
    }

    private static double ADVfatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            fatigueCounter = 0;
            return min + (max - min) * 0.5;
        }

        fatigueCounter++;

        // Накопленная усталость (0-100%)
        double fatigueFactor = Math.min(1.0, fatigueCounter / 250.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.42) * fatigueFactor * 0.06 * (max - min);

        // Периодические коррекции (реже при усталости)
        int correctionInterval = 35 - (int)(fatigueFactor * 20);
        if(correctionInterval < 8) correctionInterval = 8;

        if(fatigueCounter % correctionInterval == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.25 + baseRandom.nextDouble() * 0.35);
            drift += correction;

            // Сброс усталости после коррекции
            fatigueCounter = (int)(fatigueCounter * 0.6);
        }

        return constrain(lastValue + drift, min, max);
    }



    // Сброс состояния генератора
    public static void resetState() {
        lastValue = Double.NaN;
        counter = 0;
    }
}
 
Нашёл в своём старом проекте, есть как простые stealth-генераторы для int, double, float, так и интересные с разными паттернами. Сам использовал в киллауре для ротаций.

AdvancedRandUtil:
Expand Collapse Copy
package minecraft.system;

import lombok.experimental.UtilityClass;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@UtilityClass
public class AdvancedRandUtil{
    private final SecureRandom baseRandom = new SecureRandom();
    private static final int LAYERS = 9;
    private static final int[] PRIMES = {0x9E3779B1, 0x85EBCA77, 0xC2B2AE3D};
    private static double lastValue = Double.NaN;
    private static int counter = 0;

    private static double lastVelocity = 0.0; // Добавлено для инерции
    private static int fatigueCounter = 0;    // Отдельный счетчик для усталости
    public int stealthInt(int minLimit, int maxLimit) {
        if (minLimit >= maxLimit) return minLimit;

        // Инициализация каскада
        int[] layers = new int[7];
        layers[0] = minLimit + baseRandom.nextInt(maxLimit - minLimit + 1);

        // Главный каскад случайности
        for (int i = 1; i < layers.length; i++) {
            int range = maxLimit - minLimit + 1;

            // Динамические параметры для текущего слоя
            int noiseFactor = 1 + baseRandom.nextInt(3);
            int shiftBits = baseRandom.nextInt(8);
            int directionFlag = baseRandom.nextInt(2);

            // Генерация шума с расширением диапазона
            int expandedRange = range * (2 + noiseFactor);
            int noise = baseRandom.nextInt(expandedRange) - (expandedRange / 2);

            // Нелинейные преобразования
            layers[i] = applyNonLinearTransform(
                    layers[i - 1],
                    minLimit,
                    maxLimit,
                    noise,
                    shiftBits,
                    directionFlag
            );
        }

        // Финальная стабилизация в целевом диапазоне
        return stabilize(layers[layers.length - 1], minLimit, maxLimit);
    }

    private int applyNonLinearTransform(int value, int min, int max, int noise, int shift, int direction) {
        // Динамическое изменение значения
        int transformed = (value ^ (value << shift)) + noise;

        // Обратная связь с предыдущими значениями
        transformed = (transformed & 0x5555_5555) | ((transformed & 0xAAAA_AAAA) >>> 1);

        // Направленное смещение
        if (direction == 0) {
            transformed = Integer.rotateLeft(transformed, shift);
        } else {
            transformed = Integer.rotateRight(transformed, shift);
        }

        // Псевдо-стабилизация
        return (transformed % (max - min + 1)) + min;
    }

    private int stabilize(int value, int min, int max) {
        // Многоэтапная стабилизация
        for (int i = 0; i < 3; i++) {
            int range = max - min + 1;
            int mid = min + range / 2;

            // Квадратичное сжатие к центру
            int offset = (value - mid) * (value - mid) / range;
            value = mid + (value > mid ? -offset : offset);

            // Коррекция границ
            if (value < min) value += range;
            if (value > max) value -= range;
        }

        // Гарантированное возвращение в диапазон
        return Math.min(Math.max(value, min), max);
    }

    public static double stealthDouble(double min, double max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        double value = entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = fractalDistortion(value, min, max, i);
        }

        return constrain(value, min, max);
    }

    public static float stealthFloat(float min, float max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        float value = (float) entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = (float) fractalDistortion(value, min, max, i);
        }

        return (float) constrain(value, min, max);
    }

    private static double entropyWave(long seed) {
        long state = seed ^ 0xDEADBEEFFACADE00L;
        state = (state ^ (state >>> 30)) * PRIMES[0];
        state = (state ^ (state >>> 27)) * PRIMES[1];
        state = (state ^ (state >>> 31)) | PRIMES[2];
        return Double.longBitsToDouble(state);
    }

    private static double fractalDistortion(double input, double min, double max, int layer) {
        double range = max - min;
        long bits = Double.doubleToRawLongBits(input);

        // Хаотические преобразования
        Random rand = ThreadLocalRandom.current();
        bits ^= (bits << (layer * 9 + 5)) | (bits >>> (layer * 7 + 11));
        bits = Long.rotateLeft(bits, rand.nextInt(64));
        bits += rand.nextLong() ^ PRIMES[layer % PRIMES.length];
        bits *= rand.nextBoolean() ? 1.6180339887 : 3.1415926535;

        // Фрактальное зашумление
        double noise = rand.nextDouble() * range / Math.pow(2, layer);
        double result = Double.longBitsToDouble(bits) * noise;

        // Нелинейное сжатие
        return Math.sin(result * Math.PI) * range * 0.5 + (min + max) * 0.5;
    }

    private static double constrain(double value, double min, double max) {
        // Квантовое ограничение с хаотической коррекцией
        if (value >= min && value <= max) return value;

        double scaled = Math.abs(value) % (max - min);
        return scaled + min - ((int)(scaled / (max - min)) * (max - min));
    }

    public enum PatternMode {
        LINEAR_SMOOTH,      // Плавные линейные изменения
        GAUSSIAN_CENTERED,  // Концентрация в центре диапазона
        EDGE_BIASED,        // Смещение к краям диапазона
        STEPPED,            // Ступенчатое изменение значений
        CHAOTIC_SMOOTH,      // Хаотичные но плавные переходы
        //humanaized:
        HUMAN_TREMOR,       // Мелкая дрожь как у человека
        SACCADIC_MOVEMENT,  // Скачкообразные движения глаз
        MICRO_CORRECTIONS,  // Микрокоррекции с возвратом
        INERTIA_SMOOTH,     // Движение с инерцией
        FATIGUE_DRIFT,       // Дрейф при усталости
        TREMOR_PREDICT,
        FATIGURE_ADVANCE,
        INTERIA_DECREATE
    }

    // Double генератор
    public static double LegitDouble(double min, double max, PatternMode mode) {
        if (min >= max) return min;

        double value;
        switch (mode) {
            case LINEAR_SMOOTH:
                value = linearSmooth(min, max);
                break;
            case GAUSSIAN_CENTERED:
                value = gaussianCentered(min, max);
                break;
            case EDGE_BIASED:
                value = edgeBiased(min, max);
                break;
            case STEPPED:
                value = stepped(min, max);
                break;
            case CHAOTIC_SMOOTH:
                value = chaoticSmooth(min, max);
                break;
            case HUMAN_TREMOR:
                value = humanTremor(min, max);
                break;
            case SACCADIC_MOVEMENT:
                value = saccadicMovement(min, max);
                break;
            case MICRO_CORRECTIONS:
                value =  microCorrections(min, max);
                break;
            case INERTIA_SMOOTH:
                value = inertiaSmooth(min, max);
                break;
            case FATIGUE_DRIFT:
                value = fatigueDrift(min, max);
                break;
            case TREMOR_PREDICT:
                value = Pred_Tremor(min, max);
                break;
            case INTERIA_DECREATE:
                value = interia2(min, max);
                break;
            case FATIGURE_ADVANCE:
                value = ADVfatigueDrift(min, max);
                break;
            default:
                value = baseRandom.nextDouble() * (max - min) + min;
        }

        lastValue = value;
        counter++;
        return value;
    }

    // Float генератор
    public static float LegitFloat(float min, float max, PatternMode mode) {
        return (float) LegitDouble(min, max, mode);
    }

    private static double Pred_Tremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор (8-12 Гц)
        double timeFactor = counter * 0.3;
        double tremorX = Math.sin(timeFactor * 25.3) * 0.4;
        double tremorY = Math.cos(timeFactor * 22.7) * 0.3;
        double tremorZ = Math.sin(timeFactor * 18.9) * 0.3;

        double tremor = (tremorX + tremorY + tremorZ) / 3.0;
        tremor *= 0.03 * (max - min); // Амплитуда 3% от диапазона

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.02 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    // Режимы работы
    private static double linearSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Плавное изменение с небольшой случайной дельтой
        double range = max - min;
        double step = range * 0.05 * (baseRandom.nextGaussian() + 0.3);
        double newValue = lastValue + step;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double target = min + range * (0.2 + 0.6 * baseRandom.nextDouble());
            return target;
        }

        return newValue;
    }

    private static double gaussianCentered(double min, double max) {
        double center = (min + max) / 2.0;
        double range = max - min;

        // Генерация с нормальным распределением
        double value = center + baseRandom.nextGaussian() * (range / 6.0);

        // Периодическая коррекция к центру
        if (counter % 5 == 0) {
            double offset = (value - center) * 0.7;
            value = center + offset;
        }

        // Гарантия в диапазоне
        return Math.max(min, Math.min(max, value));
    }

    private static double edgeBiased(double min, double max) {
        // Случайный выбор края
        double targetEdge = baseRandom.nextBoolean() ? min : max;

        // Генерация со смещением к краю
        double biasStrength = 0.7 + baseRandom.nextDouble() * 0.25;
        double value;

        if (targetEdge == min) {
            value = min + Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        } else {
            value = max - Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        }

        // Периодические "проверки" центра
        if (counter % 7 == 0) {
            double center = (min + max) / 2.0;
            value = center + (value - center) * 0.4;
        }

        return value;
    }

    private static double stepped(double min, double max) {
        double range = max - min;
        int steps = 5 + baseRandom.nextInt(6); // 5-10 ступеней

        // Определение текущей ступени
        int currentStep = (int) (steps * baseRandom.nextDouble());

        // Периодическое изменение ступеней
        if (counter % 4 == 0) {
            currentStep = (currentStep + 1 + baseRandom.nextInt(2)) % steps;
        }

        // Генерация значения в пределах ступени
        double stepSize = range / steps;
        double stepMin = min + currentStep * stepSize;
        double stepMax = stepMin + stepSize;

        return stepMin + baseRandom.nextDouble() * (stepMax - stepMin);
    }

    private static double chaoticSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Хаотичное но плавное изменение
        double range = max - min;
        double chaosFactor = 0.2 + baseRandom.nextDouble() * 0.5;
        double direction = baseRandom.nextBoolean() ? 1 : -1;

        // Нелинейное изменение
        double delta = range * chaosFactor * direction * Math.sin(counter * 0.5);
        double newValue = lastValue + delta;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double anchor = min + range * (0.1 + 0.8 * baseRandom.nextDouble());
            return anchor;
        }

        return newValue;
    }

    private static double humanTremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор
        double tremorIntensity = 0.02 + Math.sin(counter * 0.3) * 0.01;
        double tremor = Math.sin(counter * 12.7) * tremorIntensity * (max - min);

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.04 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    private static double saccadicMovement(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Длительность фиксации (200-500мс)
        int fixationDuration = 10 + baseRandom.nextInt(15);

        if(counter % fixationDuration == 0) {
            // Саккадический скачок
            double jumpSize = (max - min) * (0.1 + baseRandom.nextDouble() * 0.15);
            int direction = baseRandom.nextBoolean() ? 1 : -1;
            return constrain(lastValue + jumpSize * direction, min, max);
        }

        // Микродвижения во время фиксации
        return lastValue + baseRandom.nextGaussian() * 0.015 * (max - min);
    }

    private static double microCorrections(double min, double max) {
        double target = Double.isNaN(lastValue)
                ? min + (max - min) * (0.3 + baseRandom.nextDouble() * 0.4)
                : lastValue;

        // Периодические коррекции
        if(counter % (8 + baseRandom.nextInt(5)) == 0) {
            double overshoot = (max - min) * 0.08 * (baseRandom.nextGaussian() + 0.5);
            target += baseRandom.nextBoolean() ? overshoot : -overshoot;
        }

        // Постоянные микрокоррекции
        double correction = (target - lastValue) * 0.15 + baseRandom.nextGaussian() * 0.01;
        return constrain(lastValue + correction, min, max);
    }

    private static double inertiaSmooth(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        double velocity = Double.isNaN(lastVelocity)
                ? (max - min) * 0.005 * (baseRandom.nextGaussian() + 0.3)
                : lastVelocity * 0.85;

        // Случайное изменение направления
        if(baseRandom.nextDouble() < 0.07) {
            velocity *= -0.5 + baseRandom.nextDouble();
        }

        double newValue = lastValue + velocity;
        lastVelocity = velocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.7;
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double interia2(double min, double max){
        if(Double.isNaN(lastValue)) {
            // Инициализация
            lastVelocity = (baseRandom.nextGaussian() * 0.5 + 0.3) * (max - min) * 0.01;
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        lastVelocity *= 0.82;

        // Случайное ускорение
        if(baseRandom.nextDouble() < 0.12) {
            lastVelocity += (baseRandom.nextGaussian() * 0.7) * (max - min) * 0.005;
        }

        double newValue = lastValue + lastVelocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.65; // Отскок с потерей энергии
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double fatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + (max - min) * 0.5;
        }

        // Накопленная усталость
        double fatigueFactor = Math.min(1.0, counter / 300.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.4) * fatigueFactor * 0.08 * (max - min);

        // Периодические осознанные коррекции
        if(counter % (30 - (int)(fatigueFactor * 15)) == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.3 + baseRandom.nextDouble() * 0.4);
            drift += correction;
        }

        return constrain(lastValue + drift, min, max);
    }

    private static double ADVfatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            fatigueCounter = 0;
            return min + (max - min) * 0.5;
        }

        fatigueCounter++;

        // Накопленная усталость (0-100%)
        double fatigueFactor = Math.min(1.0, fatigueCounter / 250.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.42) * fatigueFactor * 0.06 * (max - min);

        // Периодические коррекции (реже при усталости)
        int correctionInterval = 35 - (int)(fatigueFactor * 20);
        if(correctionInterval < 8) correctionInterval = 8;

        if(fatigueCounter % correctionInterval == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.25 + baseRandom.nextDouble() * 0.35);
            drift += correction;

            // Сброс усталости после коррекции
            fatigueCounter = (int)(fatigueCounter * 0.6);
        }

        return constrain(lastValue + drift, min, max);
    }



    // Сброс состояния генератора
    public static void resetState() {
        lastValue = Double.NaN;
        counter = 0;
    }
}
чем он лучше обычного рандома?
 
Нашёл в своём старом проекте, есть как простые stealth-генераторы для int, double, float, так и интересные с разными паттернами. Сам использовал в киллауре для ротаций.

AdvancedRandUtil:
Expand Collapse Copy
package minecraft.system;

import lombok.experimental.UtilityClass;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@UtilityClass
public class AdvancedRandUtil{
    private final SecureRandom baseRandom = new SecureRandom();
    private static final int LAYERS = 9;
    private static final int[] PRIMES = {0x9E3779B1, 0x85EBCA77, 0xC2B2AE3D};
    private static double lastValue = Double.NaN;
    private static int counter = 0;

    private static double lastVelocity = 0.0; // Добавлено для инерции
    private static int fatigueCounter = 0;    // Отдельный счетчик для усталости
    public int stealthInt(int minLimit, int maxLimit) {
        if (minLimit >= maxLimit) return minLimit;

        // Инициализация каскада
        int[] layers = new int[7];
        layers[0] = minLimit + baseRandom.nextInt(maxLimit - minLimit + 1);

        // Главный каскад случайности
        for (int i = 1; i < layers.length; i++) {
            int range = maxLimit - minLimit + 1;

            // Динамические параметры для текущего слоя
            int noiseFactor = 1 + baseRandom.nextInt(3);
            int shiftBits = baseRandom.nextInt(8);
            int directionFlag = baseRandom.nextInt(2);

            // Генерация шума с расширением диапазона
            int expandedRange = range * (2 + noiseFactor);
            int noise = baseRandom.nextInt(expandedRange) - (expandedRange / 2);

            // Нелинейные преобразования
            layers[i] = applyNonLinearTransform(
                    layers[i - 1],
                    minLimit,
                    maxLimit,
                    noise,
                    shiftBits,
                    directionFlag
            );
        }

        // Финальная стабилизация в целевом диапазоне
        return stabilize(layers[layers.length - 1], minLimit, maxLimit);
    }

    private int applyNonLinearTransform(int value, int min, int max, int noise, int shift, int direction) {
        // Динамическое изменение значения
        int transformed = (value ^ (value << shift)) + noise;

        // Обратная связь с предыдущими значениями
        transformed = (transformed & 0x5555_5555) | ((transformed & 0xAAAA_AAAA) >>> 1);

        // Направленное смещение
        if (direction == 0) {
            transformed = Integer.rotateLeft(transformed, shift);
        } else {
            transformed = Integer.rotateRight(transformed, shift);
        }

        // Псевдо-стабилизация
        return (transformed % (max - min + 1)) + min;
    }

    private int stabilize(int value, int min, int max) {
        // Многоэтапная стабилизация
        for (int i = 0; i < 3; i++) {
            int range = max - min + 1;
            int mid = min + range / 2;

            // Квадратичное сжатие к центру
            int offset = (value - mid) * (value - mid) / range;
            value = mid + (value > mid ? -offset : offset);

            // Коррекция границ
            if (value < min) value += range;
            if (value > max) value -= range;
        }

        // Гарантированное возвращение в диапазон
        return Math.min(Math.max(value, min), max);
    }

    public static double stealthDouble(double min, double max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        double value = entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = fractalDistortion(value, min, max, i);
        }

        return constrain(value, min, max);
    }

    public static float stealthFloat(float min, float max) {
        if (min >= max) return min;

        long seed = ThreadLocalRandom.current().nextLong();
        float value = (float) entropyWave(seed);

        for (int i = 0; i < LAYERS; i++) {
            value = (float) fractalDistortion(value, min, max, i);
        }

        return (float) constrain(value, min, max);
    }

    private static double entropyWave(long seed) {
        long state = seed ^ 0xDEADBEEFFACADE00L;
        state = (state ^ (state >>> 30)) * PRIMES[0];
        state = (state ^ (state >>> 27)) * PRIMES[1];
        state = (state ^ (state >>> 31)) | PRIMES[2];
        return Double.longBitsToDouble(state);
    }

    private static double fractalDistortion(double input, double min, double max, int layer) {
        double range = max - min;
        long bits = Double.doubleToRawLongBits(input);

        // Хаотические преобразования
        Random rand = ThreadLocalRandom.current();
        bits ^= (bits << (layer * 9 + 5)) | (bits >>> (layer * 7 + 11));
        bits = Long.rotateLeft(bits, rand.nextInt(64));
        bits += rand.nextLong() ^ PRIMES[layer % PRIMES.length];
        bits *= rand.nextBoolean() ? 1.6180339887 : 3.1415926535;

        // Фрактальное зашумление
        double noise = rand.nextDouble() * range / Math.pow(2, layer);
        double result = Double.longBitsToDouble(bits) * noise;

        // Нелинейное сжатие
        return Math.sin(result * Math.PI) * range * 0.5 + (min + max) * 0.5;
    }

    private static double constrain(double value, double min, double max) {
        // Квантовое ограничение с хаотической коррекцией
        if (value >= min && value <= max) return value;

        double scaled = Math.abs(value) % (max - min);
        return scaled + min - ((int)(scaled / (max - min)) * (max - min));
    }

    public enum PatternMode {
        LINEAR_SMOOTH,      // Плавные линейные изменения
        GAUSSIAN_CENTERED,  // Концентрация в центре диапазона
        EDGE_BIASED,        // Смещение к краям диапазона
        STEPPED,            // Ступенчатое изменение значений
        CHAOTIC_SMOOTH,      // Хаотичные но плавные переходы
        //humanaized:
        HUMAN_TREMOR,       // Мелкая дрожь как у человека
        SACCADIC_MOVEMENT,  // Скачкообразные движения глаз
        MICRO_CORRECTIONS,  // Микрокоррекции с возвратом
        INERTIA_SMOOTH,     // Движение с инерцией
        FATIGUE_DRIFT,       // Дрейф при усталости
        TREMOR_PREDICT,
        FATIGURE_ADVANCE,
        INTERIA_DECREATE
    }

    // Double генератор
    public static double LegitDouble(double min, double max, PatternMode mode) {
        if (min >= max) return min;

        double value;
        switch (mode) {
            case LINEAR_SMOOTH:
                value = linearSmooth(min, max);
                break;
            case GAUSSIAN_CENTERED:
                value = gaussianCentered(min, max);
                break;
            case EDGE_BIASED:
                value = edgeBiased(min, max);
                break;
            case STEPPED:
                value = stepped(min, max);
                break;
            case CHAOTIC_SMOOTH:
                value = chaoticSmooth(min, max);
                break;
            case HUMAN_TREMOR:
                value = humanTremor(min, max);
                break;
            case SACCADIC_MOVEMENT:
                value = saccadicMovement(min, max);
                break;
            case MICRO_CORRECTIONS:
                value =  microCorrections(min, max);
                break;
            case INERTIA_SMOOTH:
                value = inertiaSmooth(min, max);
                break;
            case FATIGUE_DRIFT:
                value = fatigueDrift(min, max);
                break;
            case TREMOR_PREDICT:
                value = Pred_Tremor(min, max);
                break;
            case INTERIA_DECREATE:
                value = interia2(min, max);
                break;
            case FATIGURE_ADVANCE:
                value = ADVfatigueDrift(min, max);
                break;
            default:
                value = baseRandom.nextDouble() * (max - min) + min;
        }

        lastValue = value;
        counter++;
        return value;
    }

    // Float генератор
    public static float LegitFloat(float min, float max, PatternMode mode) {
        return (float) LegitDouble(min, max, mode);
    }

    private static double Pred_Tremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор (8-12 Гц)
        double timeFactor = counter * 0.3;
        double tremorX = Math.sin(timeFactor * 25.3) * 0.4;
        double tremorY = Math.cos(timeFactor * 22.7) * 0.3;
        double tremorZ = Math.sin(timeFactor * 18.9) * 0.3;

        double tremor = (tremorX + tremorY + tremorZ) / 3.0;
        tremor *= 0.03 * (max - min); // Амплитуда 3% от диапазона

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.02 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    // Режимы работы
    private static double linearSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Плавное изменение с небольшой случайной дельтой
        double range = max - min;
        double step = range * 0.05 * (baseRandom.nextGaussian() + 0.3);
        double newValue = lastValue + step;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double target = min + range * (0.2 + 0.6 * baseRandom.nextDouble());
            return target;
        }

        return newValue;
    }

    private static double gaussianCentered(double min, double max) {
        double center = (min + max) / 2.0;
        double range = max - min;

        // Генерация с нормальным распределением
        double value = center + baseRandom.nextGaussian() * (range / 6.0);

        // Периодическая коррекция к центру
        if (counter % 5 == 0) {
            double offset = (value - center) * 0.7;
            value = center + offset;
        }

        // Гарантия в диапазоне
        return Math.max(min, Math.min(max, value));
    }

    private static double edgeBiased(double min, double max) {
        // Случайный выбор края
        double targetEdge = baseRandom.nextBoolean() ? min : max;

        // Генерация со смещением к краю
        double biasStrength = 0.7 + baseRandom.nextDouble() * 0.25;
        double value;

        if (targetEdge == min) {
            value = min + Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        } else {
            value = max - Math.abs(baseRandom.nextGaussian()) * (max - min) * 0.3;
        }

        // Периодические "проверки" центра
        if (counter % 7 == 0) {
            double center = (min + max) / 2.0;
            value = center + (value - center) * 0.4;
        }

        return value;
    }

    private static double stepped(double min, double max) {
        double range = max - min;
        int steps = 5 + baseRandom.nextInt(6); // 5-10 ступеней

        // Определение текущей ступени
        int currentStep = (int) (steps * baseRandom.nextDouble());

        // Периодическое изменение ступеней
        if (counter % 4 == 0) {
            currentStep = (currentStep + 1 + baseRandom.nextInt(2)) % steps;
        }

        // Генерация значения в пределах ступени
        double stepSize = range / steps;
        double stepMin = min + currentStep * stepSize;
        double stepMax = stepMin + stepSize;

        return stepMin + baseRandom.nextDouble() * (stepMax - stepMin);
    }

    private static double chaoticSmooth(double min, double max) {
        if (Double.isNaN(lastValue)) {
            return baseRandom.nextDouble() * (max - min) + min;
        }

        // Хаотичное но плавное изменение
        double range = max - min;
        double chaosFactor = 0.2 + baseRandom.nextDouble() * 0.5;
        double direction = baseRandom.nextBoolean() ? 1 : -1;

        // Нелинейное изменение
        double delta = range * chaosFactor * direction * Math.sin(counter * 0.5);
        double newValue = lastValue + delta;

        // Коррекция при выходе за границы
        if (newValue < min || newValue > max) {
            double anchor = min + range * (0.1 + 0.8 * baseRandom.nextDouble());
            return anchor;
        }

        return newValue;
    }

    private static double humanTremor(double min, double max) {
        double baseValue = Double.isNaN(lastValue)
                ? (min + max) / 2.0
                : lastValue;

        // Псевдо-периодический тремор
        double tremorIntensity = 0.02 + Math.sin(counter * 0.3) * 0.01;
        double tremor = Math.sin(counter * 12.7) * tremorIntensity * (max - min);

        // Случайные микро-скачки
        if(counter % 15 == 0) {
            tremor += baseRandom.nextGaussian() * 0.04 * (max - min);
        }

        return constrain(baseValue + tremor, min, max);
    }

    private static double saccadicMovement(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Длительность фиксации (200-500мс)
        int fixationDuration = 10 + baseRandom.nextInt(15);

        if(counter % fixationDuration == 0) {
            // Саккадический скачок
            double jumpSize = (max - min) * (0.1 + baseRandom.nextDouble() * 0.15);
            int direction = baseRandom.nextBoolean() ? 1 : -1;
            return constrain(lastValue + jumpSize * direction, min, max);
        }

        // Микродвижения во время фиксации
        return lastValue + baseRandom.nextGaussian() * 0.015 * (max - min);
    }

    private static double microCorrections(double min, double max) {
        double target = Double.isNaN(lastValue)
                ? min + (max - min) * (0.3 + baseRandom.nextDouble() * 0.4)
                : lastValue;

        // Периодические коррекции
        if(counter % (8 + baseRandom.nextInt(5)) == 0) {
            double overshoot = (max - min) * 0.08 * (baseRandom.nextGaussian() + 0.5);
            target += baseRandom.nextBoolean() ? overshoot : -overshoot;
        }

        // Постоянные микрокоррекции
        double correction = (target - lastValue) * 0.15 + baseRandom.nextGaussian() * 0.01;
        return constrain(lastValue + correction, min, max);
    }

    private static double inertiaSmooth(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        double velocity = Double.isNaN(lastVelocity)
                ? (max - min) * 0.005 * (baseRandom.nextGaussian() + 0.3)
                : lastVelocity * 0.85;

        // Случайное изменение направления
        if(baseRandom.nextDouble() < 0.07) {
            velocity *= -0.5 + baseRandom.nextDouble();
        }

        double newValue = lastValue + velocity;
        lastVelocity = velocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.7;
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double interia2(double min, double max){
        if(Double.isNaN(lastValue)) {
            // Инициализация
            lastVelocity = (baseRandom.nextGaussian() * 0.5 + 0.3) * (max - min) * 0.01;
            return min + baseRandom.nextDouble() * (max - min);
        }

        // Инерция и плавное замедление
        lastVelocity *= 0.82;

        // Случайное ускорение
        if(baseRandom.nextDouble() < 0.12) {
            lastVelocity += (baseRandom.nextGaussian() * 0.7) * (max - min) * 0.005;
        }

        double newValue = lastValue + lastVelocity;

        // Коррекция у границ
        if(newValue < min || newValue > max) {
            lastVelocity *= -0.65; // Отскок с потерей энергии
            return constrain(lastValue + lastVelocity, min, max);
        }

        return newValue;
    }

    private static double fatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            return min + (max - min) * 0.5;
        }

        // Накопленная усталость
        double fatigueFactor = Math.min(1.0, counter / 300.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.4) * fatigueFactor * 0.08 * (max - min);

        // Периодические осознанные коррекции
        if(counter % (30 - (int)(fatigueFactor * 15)) == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.3 + baseRandom.nextDouble() * 0.4);
            drift += correction;
        }

        return constrain(lastValue + drift, min, max);
    }

    private static double ADVfatigueDrift(double min, double max) {
        if(Double.isNaN(lastValue)) {
            fatigueCounter = 0;
            return min + (max - min) * 0.5;
        }

        fatigueCounter++;

        // Накопленная усталость (0-100%)
        double fatigueFactor = Math.min(1.0, fatigueCounter / 250.0);

        // Дрейф в зависимости от усталости
        double drift = (baseRandom.nextDouble() - 0.42) * fatigueFactor * 0.06 * (max - min);

        // Периодические коррекции (реже при усталости)
        int correctionInterval = 35 - (int)(fatigueFactor * 20);
        if(correctionInterval < 8) correctionInterval = 8;

        if(fatigueCounter % correctionInterval == 0) {
            double correction = ((min + max)/2 - lastValue) * (0.25 + baseRandom.nextDouble() * 0.35);
            drift += correction;

            // Сброс усталости после коррекции
            fatigueCounter = (int)(fatigueCounter * 0.6);
        }

        return constrain(lastValue + drift, min, max);
    }



    // Сброс состояния генератора
    public static void resetState() {
        lastValue = Double.NaN;
        counter = 0;
    }
}
Годно
 
Держу в кусре что с @UtilityClass static не нужен пастеры
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Назад
Сверху Снизу