<commit_before>var _ = require('lodash');

module.exports = {

    /**
     * @param {StructureTower} tower
     */
    run: function (tower) {
        if (tower.energy >= TOWER_ENERGY_COST) {
            var attackTarget = this.getAttackTarget(tower);
            if (attackTarget) {
                tower.attack(attackTarget);
            }
        }
    },

    getAttackTarget: function (tower) {
        var target = Game.getObjectById(tower.getFromMemory('attackTargetId'));
        if (target && (target.canAttack() || target.canHeal())) {
            return target;
        } else {
            // TODO: Come up with a formula to wage between distance and remaining health of the targets
            var attackTargets = tower.pos.findInRange(FIND_HOSTILE_CREEPS, 10, {
                filter: creep => creep.canAttack() || creep.canHeal()
            });
            target = _.first(_.sortBy(attackTargets, function (target) {
                // TODO: Is hit points a good selection criteria? What about e.g. damage output?
                return target.hits / target.hitsMax;
            }));

            if (target) {
                console.log(`Found new attack target at (${target.pos.x}, ${target.pos.y}) with body ${_.map(target.body, 'type')}, gunning down!`);
                tower.setToMemory('attackTargetId', target.id);
            } else {
                tower.clearFromMemory('attackTargetId');
            }

            return target;
        }
    }
};<commit_msg>Changed the way tower targeting works. There's no maximum range anymore, and new targets are chosen based on range only<commit_after>var _ = require('lodash');

module.exports = {

    /**
     * @param {StructureTower} tower
     */
    run: function (tower) {
        if (tower.energy >= TOWER_ENERGY_COST) {
            var attackTarget = this.getAttackTarget(tower);
            if (attackTarget) {
                tower.attack(attackTarget);
            }
        }
    },

    getAttackTarget: function (tower) {
        var target = Game.getObjectById(tower.getFromMemory('attackTargetId'));
        if (target && (target.canAttack() || target.canHeal())) {
            return target;
        }

        var hostiles = tower.room.find(FIND_HOSTILE_CREEPS);
        if (_.isEmpty(hostiles)) {
            target = null;
        } else {
            var offensiveHostiles = _.filter(hostiles, creep => creep.canAttack() || creep.canHeal());
            target = _.isEmpty(offensiveHostiles) ?
                    tower.pos.findClosestByRange(hostiles) : tower.pos.findClosestByRange(offensiveHostiles);
        }

        if (target) {
            console.log(`Found new attack target at (${target.pos.x}, ${target.pos.y}) with body ${_.map(target.body, 'type')}, gunning down!`);
            tower.setToMemory('attackTargetId', target.id);
        } else {
            tower.clearFromMemory('attackTargetId');
        }

        return target;
    }
};
{'fraction_non_alphanumeric': 0.124364622161979, 'fraction_numerical': 0.0006777363605557439, 'mean_word_length': 2.0245901639344264, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2608142', 'n_tokens_mistral': 865, 'n_tokens_neox': 833, 'n_words': 184}