"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findLast = exports.shuffleArray = exports.pickMultipleRandomDifferent = exports.decode = exports.encode = exports.pickRandomHighestHealth = exports.pickRandomHighestAttack = exports.pickRandomLowestAttack = exports.pickRandomLowestHealth = exports.pickMultipleRandomAlive = exports.pickRandomAlive = exports.pickMultipleRandom = exports.pickRandom = exports.sleep = exports.partitionArray = exports.groupByFunction = void 0;
function partitionArray(array, partitionSize) {
    const workingCopy = [...array];
    const result = [];
    while (workingCopy.length) {
        result.push(workingCopy.splice(0, partitionSize));
    }
    return result;
}
exports.partitionArray = partitionArray;
async function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
exports.sleep = sleep;
const groupByFunction = (keyExtractor) => (array) => {
    return (array !== null && array !== void 0 ? array : []).reduce((objectsByKeyValue, obj) => {
        var _a;
        const value = keyExtractor(obj);
        objectsByKeyValue[value] = (_a = objectsByKeyValue[value]) !== null && _a !== void 0 ? _a : [];
        objectsByKeyValue[value].push(obj);
        return objectsByKeyValue;
    }, {});
};
exports.groupByFunction = groupByFunction;
const pickRandom = (array) => {
    if (!(array === null || array === void 0 ? void 0 : array.length)) {
        return null;
    }
    return array[Math.floor(Math.random() * array.length)];
};
exports.pickRandom = pickRandom;
const pickMultipleRandom = (array, quantity) => {
    const picked = [];
    for (let i = 0; i < quantity; i++) {
        const target = array.filter((e) => !picked.includes(e));
        const chosenEntity = (0, exports.pickRandom)(target);
        if (!!chosenEntity) {
            picked.push(chosenEntity);
        }
    }
    return picked;
};
exports.pickMultipleRandom = pickMultipleRandom;
const pickRandomAlive = (board) => {
    const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);
    const chosenEntity = (0, exports.pickRandom)(targetBoard);
    return chosenEntity;
};
exports.pickRandomAlive = pickRandomAlive;
const pickMultipleRandomAlive = (board, quantity) => {
    const picked = [];
    for (let i = 0; i < quantity; i++) {
        const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead).filter((e) => !picked.includes(e));
        const chosenEntity = (0, exports.pickRandom)(targetBoard);
        if (!!chosenEntity) {
            picked.push(chosenEntity);
        }
    }
    return picked;
};
exports.pickMultipleRandomAlive = pickMultipleRandomAlive;
const pickRandomLowestHealth = (board) => {
    const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);
    const lowestHealth = Math.min(...targetBoard.map((e) => e.health));
    const entitiesWithLowestHealth = targetBoard.filter((e) => e.health === lowestHealth);
    const chosenEntity = (0, exports.pickRandom)(entitiesWithLowestHealth);
    return chosenEntity;
};
exports.pickRandomLowestHealth = pickRandomLowestHealth;
const pickRandomLowestAttack = (board) => {
    const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);
    const lowestAttack = Math.min(...targetBoard.map((e) => e.attack));
    const entitiesWithLowestAttack = targetBoard.filter((e) => e.attack === lowestAttack);
    const chosenEntity = (0, exports.pickRandom)(entitiesWithLowestAttack);
    return chosenEntity;
};
exports.pickRandomLowestAttack = pickRandomLowestAttack;
const pickRandomHighestAttack = (board) => {
    const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);
    const highestAttack = Math.max(...targetBoard.map((e) => e.attack));
    const entitiesWithHighestAttack = targetBoard.filter((e) => e.attack === highestAttack);
    const chosenEntity = (0, exports.pickRandom)(entitiesWithHighestAttack);
    return chosenEntity;
};
exports.pickRandomHighestAttack = pickRandomHighestAttack;
const pickRandomHighestHealth = (board) => {
    const targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);
    const highestHealth = Math.max(...targetBoard.map((e) => e.health));
    const entitiesWithHighestHealth = targetBoard.filter((e) => e.health === highestHealth);
    const chosenEntity = (0, exports.pickRandom)(entitiesWithHighestHealth);
    return chosenEntity;
};
exports.pickRandomHighestHealth = pickRandomHighestHealth;
const encode = (input) => {
    const buff = Buffer.from(input, 'utf-8');
    const base64 = buff.toString('base64');
    return base64;
};
exports.encode = encode;
const decode = (base64) => {
    const buff = Buffer.from(base64, 'base64');
    const str = buff.toString('utf-8');
    return str;
};
exports.decode = decode;
const pickMultipleRandomDifferent = (list, n) => {
    const shuffled = (0, exports.shuffleArray)([...list]);
    return shuffled.slice(0, n);
};
exports.pickMultipleRandomDifferent = pickMultipleRandomDifferent;
const shuffleArray = (array) => {
    let currentIndex = array.length;
    let randomIndex = 0;
    while (currentIndex != 0) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex--;
        [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
    }
    return array;
};
exports.shuffleArray = shuffleArray;
const findLast = (array, predicate) => {
    const filtred = array.filter(predicate);
    if (!(filtred === null || filtred === void 0 ? void 0 : filtred.length)) {
        return null;
    }
    const last = filtred[filtred.length - 1];
    return last;
};
exports.findLast = findLast;
//# sourceMappingURL=utils.js.map