<commit_before>const _ = require('underscore');
const Player = require('./player.js');
const EventRegistrar = require('./eventregistrar.js');
const Settings = require('../settings.js');

class Challenge {
    constructor(game, properties) {
        this.game = game;
        this.attackingPlayer = properties.attackingPlayer;
        this.isSinglePlayer = !properties.defendingPlayer;
        this.defendingPlayer = properties.defendingPlayer || this.singlePlayerDefender();
        this.challengeType = properties.challengeType;
        this.number = properties.number;
        this.attackers = [];
        this.attackerStrength = 0;
        this.attackerStrengthModifier = 0;
        this.defenders = [];
        this.defenderStrength = 0;
        this.defenderStrengthModifier = 0;
        this.stealthData = [];
        this.events = new EventRegistrar(game, this);
        this.registerEvents(['onCardLeftPlay']);
    }

    singlePlayerDefender() {
        let dummyPlayer = new Player('', Settings.getUserWithDefaultsSet({ name: '<NAME>' }), false, this.game);
        dummyPlayer.initialise();
        dummyPlayer.startPlotPhase();
        return dummyPlayer;
    }

    resetCards() {
        this.attackingPlayer.resetForChallenge();
        this.defendingPlayer.resetForChallenge();
    }

    initiateChallenge() {
        this.attackingPlayer.trackChallenge(this);
        this.defendingPlayer.trackChallenge(this);
    }

    addAttackers(attackers) {
        this.attackers = this.attackers.concat(attackers);
        this.markAsParticipating(attackers);
        this.calculateStrength();
    }

    addAttacker(attacker) {
        this.attackers.push(attacker);
        this.markAsParticipating([attacker]);
        this.calculateStrength();
    }

    addDefenders(defenders) {
        this.defenders = this.defenders.concat(defenders);
        this.markAsParticipating(defenders);
        this.calculateStrength();
    }

    addDefender(defender) {
        this.defenders.push(defender);
        this.markAsParticipating([defender]);
        this.calculateStrength();
    }

    removeFromChallenge(card) {
        this.attackers = _.reject(this.attackers, c => c === card);
        this.defenders = _.reject(this.defenders, c => c === card);

        card.inChallenge = false;

        this.calculateStrength();

        this.game.raiseEvent('onRemovedFromChallenge', { card: card });
    }

    markAsParticipating(cards) {
        _.each(cards, card => {
            card.inChallenge = true;
        });
    }

    isAttacking(card) {
        return this.attackers.includes(card);
    }

    isDefending(card) {
        return this.defenders.includes(card);
    }

    isParticipating(card) {
        return this.isAttacking(card) || this.isDefending(card);
    }

    anyParticipants(predicate) {
        let participants = this.attackers.concat(this.defenders);
        return _.any(participants, predicate);
    }

    hasSingleParticipant(player) {
        if(this.attackingPlayer === player) {
            return this.attackers.length === 1;
        }
        return this.game.defenders.length === 1;
    }

    getNumberOfParticipants(predicate = () => true) {
        let participants = this.attackers.concat(this.defenders);
        return _.reduce(participants, (count, card) => {
            if(predicate(card)) {
                return count + 1;
            }

            return count;
        }, 0);
    }

    addStealthChoice(source, target) {
        this.stealthData.push({ source: source, target: target });
    }

    calculateStrength() {
        if(this.winnerDetermined) {
            return;
        }

        this.attackerStrength = this.calculateStrengthFor(this.attackers) + this.attackerStrengthModifier;
        this.defenderStrength = this.calculateStrengthFor(this.defenders) + this.defenderStrengthModifier;
    }
<commit_msg>game.defenders is not a thing Fixes THRONETEKI-1EW<commit_after>const _ = require('underscore');
const Player = require('./player.js');
const EventRegistrar = require('./eventregistrar.js');
const Settings = require('../settings.js');

class Challenge {
    constructor(game, properties) {
        this.game = game;
        this.attackingPlayer = properties.attackingPlayer;
        this.isSinglePlayer = !properties.defendingPlayer;
        this.defendingPlayer = properties.defendingPlayer || this.singlePlayerDefender();
        this.challengeType = properties.challengeType;
        this.number = properties.number;
        this.attackers = [];
        this.attackerStrength = 0;
        this.attackerStrengthModifier = 0;
        this.defenders = [];
        this.defenderStrength = 0;
        this.defenderStrengthModifier = 0;
        this.stealthData = [];
        this.events = new EventRegistrar(game, this);
        this.registerEvents(['onCardLeftPlay']);
    }

    singlePlayerDefender() {
        let dummyPlayer = new Player('', Settings.getUserWithDefaultsSet({ name: '<NAME>' }), false, this.game);
        dummyPlayer.initialise();
        dummyPlayer.startPlotPhase();
        return dummyPlayer;
    }

    resetCards() {
        this.attackingPlayer.resetForChallenge();
        this.defendingPlayer.resetForChallenge();
    }

    initiateChallenge() {
        this.attackingPlayer.trackChallenge(this);
        this.defendingPlayer.trackChallenge(this);
    }

    addAttackers(attackers) {
        this.attackers = this.attackers.concat(attackers);
        this.markAsParticipating(attackers);
        this.calculateStrength();
    }

    addAttacker(attacker) {
        this.attackers.push(attacker);
        this.markAsParticipating([attacker]);
        this.calculateStrength();
    }

    addDefenders(defenders) {
        this.defenders = this.defenders.concat(defenders);
        this.markAsParticipating(defenders);
        this.calculateStrength();
    }

    addDefender(defender) {
        this.defenders.push(defender);
        this.markAsParticipating([defender]);
        this.calculateStrength();
    }

    removeFromChallenge(card) {
        this.attackers = _.reject(this.attackers, c => c === card);
        this.defenders = _.reject(this.defenders, c => c === card);

        card.inChallenge = false;

        this.calculateStrength();

        this.game.raiseEvent('onRemovedFromChallenge', { card: card });
    }

    markAsParticipating(cards) {
        _.each(cards, card => {
            card.inChallenge = true;
        });
    }

    isAttacking(card) {
        return this.attackers.includes(card);
    }

    isDefending(card) {
        return this.defenders.includes(card);
    }

    isParticipating(card) {
        return this.isAttacking(card) || this.isDefending(card);
    }

    anyParticipants(predicate) {
        let participants = this.attackers.concat(this.defenders);
        return _.any(participants, predicate);
    }

    hasSingleParticipant(player) {
        if(this.attackingPlayer === player) {
            return this.attackers.length === 1;
        }

        return this.defenders.length === 1;
    }

    getNumberOfParticipants(predicate = () => true) {
        let participants = this.attackers.concat(this.defenders);
        return _.reduce(participants, (count, card) => {
            if(predicate(card)) {
                return count + 1;
            }

            return count;
        }, 0);
    }

    addStealthChoice(source, target) {
        this.stealthData.push({ source: source, target: target });
    }

    calculateStrength() {
        if(this.winnerDetermined) {
            return;
        }

        this.attackerStrength = this.calculateStrengthFor(this.attackers) + this.attackerStrengthModifier;
        this.defenderStrength = this.calculateStrengthFor(this.defenders) + this.defenderStrengthModifier;
    }

{'fraction_non_alphanumeric': 0.11994868505452214, 'fraction_numerical': 0.0021808851828094933, 'mean_word_length': 2.5745071068317285, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '3186294', 'n_tokens_mistral': 2394, 'n_tokens_neox': 2215, 'n_words': 330}