<commit_before>"use strict";

function PitfallAgent(atariConsole) {
    var self = this;


    /********************************************************************************
     * Settings
     ********************************************************************************/

    // This section defines the various settings used by the algorithm to determine
    // the limits and odds of random behaviors.

    // The times are based off of thousands of clock ticks.   There are roughly a million
    // ticks per second when running at normal speed.  It is generally close enough to think
    // of the durations as being in something close to milliseconds.

    // Settings only have an effect when training.  When playing back recorded commands,
    // the states are used as recorded.

    var settings = {
        // Allow command variations to be repeated this many times without progressing
        // to a further position.
        numResetsWithoutProgress: 20,

        // How long to hold down a single press button or control before releasing.
        // Used for the jump and down buttons.
        buttonHoldDuration: 50,

        // After a reset, we wait a random number between 0 and resetNextCommandDelay cycles
        // before executing our next command.
        resetNextCommandDelay: 800,

        // ** Behavior Times **

        // When choosing a new behavior, these time values define the limits
        // For behavior 'Type' the minTypeDuration is the minimum wait before another behavior.
        // The randomTypeDuration is the random number of extra cycles waited. (0 to n - 1)
        //
        // For example, if min is 100 and random is 1000, that means the wait will be
        // between 100 and 1099 thousand cycles.  (100 + Math.random() * 1000)
        // Used numbers are truncated.
        minRightDuration: 100, // The delay after starting to move right
        randomRightDuration: 700,
        minStopDuration: 200, // Stop means hold the controller in the center (stop moving right)
        randomStopDuration: 1000,
        minDownDuration: 200, // Down is the amount of wait after releasing a vine
        randomDownDuration: 300,
        minJumpDuration: 554, // The wait for a Jump. (Jumps take about 554000 cycles.  This must be higher.)
        randomJumpDuration: 200,
        minNOOPDuration: 100,  // NOOP means extending the current state with no changes
        randomNOOPDuration: 2000,
        minReleaseVineDuration: 600, // This is the amount of wait when on a vine before releasing
        randomReleaseVineDuration: 5000,

        // ** Odds of Behaviors (as percentages) **

        chanceOfNoChange: 0.15, // The chance of not altering the current controls
        // Otherwise, if we are on a vine we automatically schedule our releaseVineDuration
        chanceOfRight: 0.7, // Otherwise, if stopped, the chance of starting to move right
        chanceOfStop: 0.15 // Otherwise, if going right, the chance of stopping
        // Otherwise, we jump.  When stationary, the jump is straight up, otherwise it is to the right.
    };


    /********************************************************************************
     * Agent Logic and Controls
     ********************************************************************************/

    this.scheduleCommand = function(cpuCycle, commandName, commandGroup, nextCommandCycle) {
        // commandGroup provides a unique identifier for a group of commands that occur together
        // nextCommandCycle determines the next cycle that a command will be scheduled for
        var offset;

        commandGroup = commandGroup || this.nextCommandGroup++;

        this.commands.push({
            cycle: parseInt(cpuCycle),
            commandName: commandName,
            worldPosition: undefined, // The world position when first executed
            execCounter: 0, // Number of executions
            checkPoint: false,
            commandGroup: commandGroup
        });

        // Add any extra actions needed by the command
        if (commandName == 'right') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minRightDuration + Math.random() * settings.randomRightDuration) * 1000;
        }
        else if (commandName == 'stop') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minStopDuration + Math.random() * settings.randomStopDuration) * 1000;
        }
        else if (commandName == 'down') { // Release vine
            this.scheduleCommand(cpuCycle + settings.buttonHoldDuration * 1000, 'downRelease', commandGroup);
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minDownDuration + Math.random() * settings.randomDownDuration) * 1000;
        }
        else if (commandName == 'jump') {
            this.scheduleCommand(cpuCycle + settings.buttonHoldDuration * 1000, 'jumpRelease', commandGroup);
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minJumpDuration + Math.random() * settings.randomJumpDuration) * 1000;
        }
        else if (commandName == 'noop') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minNOOPDuration + Math.random() * settings.randomNOOPDuration) * 1000;
        }

        return this.commands[this.commands.length - 1];
    };


    this.chooseNextCommand = function(cpuCycle) {
        // Randomly pick the next command to run

        if (Math.random() <= settings.chanceOfNoChange) { // Stay unchanged for a little longer
            this.scheduleCommand(cpuCycle, 'noop');
        }
        else if (this.isPlayerOnVine()) {
            this.scheduleCommand(cpuCycle +
                                 (settings.minReleaseVineDuration +
                                  Math.random() * settings.randomReleaseVineDuration) * 1000, 'down');
        }
        else if (! this.controlStates.right && Math.random() <= settings.chanceOfRight) {
            // If we aren't going right, go right
            this.scheduleCommand(cpuCycle, 'right');
        }
        else if (this.controlStates.right && Math.random() <= settings.chanceOfStop) {
            // If we are going right, stop
            this.scheduleCommand(cpuCycle, 'stop');
        }
        else {
            this.scheduleCommand(cpuCycle, 'jump');
        }
    };


    this.updateAndCheckState = function() {<commit_msg>Adjust algorithm to train faster (shortRight)<commit_after>"use strict";

function PitfallAgent(atariConsole) {
    var self = this;


    /********************************************************************************
     * Settings
     ********************************************************************************/

    // This section defines the various settings used by the algorithm to determine
    // the limits and odds of random behaviors.

    // The times are based off of thousands of clock ticks.   There are roughly a million
    // ticks per second when running at normal speed.  It is generally close enough to think
    // of the durations as being in something close to milliseconds.

    // Settings only have an effect when training.  When playing back recorded commands,
    // the states are used as recorded.

    var settings = {
        // Allow command variations to be repeated this many times without progressing
        // to a further position.
        numResetsWithoutProgress: 20,

        // How long to hold down a single press button or control before releasing.
        // Used for the jump and down buttons.
        buttonHoldDuration: 50,

        // After a reset, we wait a random number between 0 and resetNextCommandDelay cycles
        // before executing our next command.
        resetNextCommandDelay: 800,

        // ** Behavior Times **

        // When choosing a new behavior, these time values define the limits
        // For behavior 'Type' the minTypeDuration is the minimum wait before another behavior.
        // The randomTypeDuration is the random number of extra cycles waited. (0 to n - 1)
        //
        // For example, if min is 100 and random is 1000, that means the wait will be
        // between 100 and 1099 thousand cycles.  (100 + Math.random() * 1000)
        // Used numbers are truncated.
        minRightDuration: 100, // The delay after starting to move right
        randomRightDuration: 700,
        minStopDuration: 200, // Stop means hold the controller in the center (stop moving right)
        randomStopDuration: 1000,
        minDownDuration: 200, // Down is the amount of wait after releasing a vine
        randomDownDuration: 300,
        minJumpDuration: 554, // The wait for a Jump. (Jumps take about 554000 cycles.  This must be higher.)
        randomJumpDuration: 200,
        minNOOPDuration: 100,  // NOOP means extending the current state with no changes
        randomNOOPDuration: 2000,
        minReleaseVineDuration: 600, // This is the amount of wait when on a vine before releasing
        randomReleaseVineDuration: 5000,

        // ** Odds of Behaviors (as percentages) **

        chanceOfNoChange: 0.15, // The chance of not altering the current controls
        // Otherwise, if we are on a vine we automatically schedule our releaseVineDuration
        chanceOfRight: 0.75, // Otherwise, if stopped, the chance of starting to move right
        chanceOfStop: 0.15, // Otherwise, if going right, the chance of stopping
        // Otherwise, we jump.  When stationary, the jump is straight up, otherwise it is to the right.

        // When starting to go right, this is the chance of the right immediately being followed by
        // another command.  This makes the possibility of things like going right and jumping
        // together more likely.
        chanceOfShortRight: 0.5
    };


    /********************************************************************************
     * Agent Logic and Controls
     ********************************************************************************/

    this.scheduleCommand = function(cpuCycle, commandName, commandGroup, nextCommandCycle) {
        // commandGroup provides a unique identifier for a group of commands that occur together
        // nextCommandCycle determines the next cycle that a command will be scheduled for
        var offset;

        commandGroup = commandGroup || this.nextCommandGroup++;

        this.commands.push({
            cycle: parseInt(cpuCycle),
            commandName: commandName,
            worldPosition: undefined, // The world position when first executed
            execCounter: 0, // Number of executions
            checkPoint: false,
            commandGroup: commandGroup
        });

        // Add any extra actions needed by the command
        if (commandName == 'right') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minRightDuration + Math.random() * settings.randomRightDuration) * 1000;
        }
        else if (commandName == 'stop') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minStopDuration + Math.random() * settings.randomStopDuration) * 1000;
        }
        else if (commandName == 'down') { // Release vine
            this.scheduleCommand(cpuCycle + settings.buttonHoldDuration * 1000, 'downRelease', commandGroup);
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minDownDuration + Math.random() * settings.randomDownDuration) * 1000;
        }
        else if (commandName == 'jump') {
            this.scheduleCommand(cpuCycle + settings.buttonHoldDuration * 1000, 'jumpRelease', commandGroup);
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minJumpDuration + Math.random() * settings.randomJumpDuration) * 1000;
        }
        else if (commandName == 'noop') {
            this.nextCommandCycle = nextCommandCycle || cpuCycle +
                (settings.minNOOPDuration + Math.random() * settings.randomNOOPDuration) * 1000;
        }

        return this.commands[this.commands.length - 1];
    };


    this.chooseNextCommand = function(cpuCycle) {
        // Randomly pick the next command to run

        if (Math.random() <= settings.chanceOfNoChange) { // Stay unchanged for a little longer
            this.scheduleCommand(cpuCycle, 'noop');
        }
        else if (this.isPlayerOnVine()) {
            this.scheduleCommand(cpuCycle +
                                 (settings.minReleaseVineDuration +
                                  Math.random() * settings.randomReleaseVineDuration) * 1000, 'down');
        }
        else if (! this.controlStates.right && Math.random() <= settings.chanceOfRight) {
            // If we aren't going right, go right
            if (Math.random() <= settings.chanceOfShortRight) { // A short right followed by something else
                this.scheduleCommand(cpuCycle, 'right', undefined, cpuCycle + 100);
            }
            else {
                this.scheduleCommand(cpuCycle, 'right');
            }
        }
        else if (this.controlStates.right && Math.random() <= settings.chanceOfStop) {
            // If we are going right, stop
            this.scheduleCommand(cpuCycle, 'stop');
        }
        else {
            this.scheduleCommand(cpuCycle, 'jump');
        }
    };


    this.updateAndCheckState = function() {
{'fraction_non_alphanumeric': 0.12389118864577173, 'fraction_numerical': 0.017888823181549378, 'mean_word_length': 2.4095262096774195, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6242564', 'n_tokens_mistral': 3483, 'n_tokens_neox': 3122, 'n_words': 1185}