Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

feat: adiciona novas opções ao modelo C #159

Merged
merged 4 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions browser/lib/plunder/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ipcRenderer } from 'electron';
import { isKeyOf, assertInteger, isInteger } from '$global/guards';
import { useUnitsStore } from '$renderer/stores/units';
import { assertFarmUnit } from '$global/guards';
import { Kronos } from '$global/constants';
import { PlunderError } from '$browser/error';
import { ipcInvoke } from '$renderer/ipc';
import type { usePlunderConfigStore } from '$renderer/stores/plunder';
Expand Down Expand Up @@ -152,6 +153,15 @@ function parseUnitAmount(row: 'a' | 'b', fields: Element[]) {
};
};

/**
* Calcula a razão entre a quantidade de recursos na aldeia-alvo e a capacidade de carga do modelo.
* @param resources Recursos na aldeia-alvo.
* @param template Modelo atacante.
*/
function calcResourceRatio(resources: number, template: PlunderTemplate) {
return resources / template.carry.value;
};

/**
* Filtra todos os modelos de saque disponíveis de acordo com a quantidade de recursos na aldeia-alvo.
* Caso a função retorne uma lista vazia, o ataque não deve ser enviado.
Expand Down Expand Up @@ -200,12 +210,12 @@ async function filterTemplates(info: PlunderTargetInfo, config: ReturnType<typeo
// Isso impede que sejam enviadas tropas em excesso para a aldeia-alvo.
// Quanto menor for a razão, maior a quantidade de tropas sendo enviada desnecessariamente.
// Não é necessário filtrar os modelos com capacidade de carga menor que a quantidade de recursos, pois eles sempre são válidos.
bigger = bigger.filter((template) => resources / template.carry.value >= config.resourceRatio);
bigger = bigger.filter((template) => calcResourceRatio(resources, template) >= config.resourceRatio);
return [...smaller, ...bigger];
};

export async function pickBestTemplate(info: PlunderTargetInfo, config: ReturnType<typeof usePlunderConfigStore>) {
if (config.useC) {
if (config.useC && config.useCPattern !== 'excess') {
const templateC = await getTemplateC(info, config);
if (templateC) return templateC;

Expand All @@ -221,13 +231,24 @@ export async function pickBestTemplate(info: PlunderTargetInfo, config: ReturnTy
config.blindAttack &&
config.blindAttackPattern === 'smaller'
) {
// Se a opção `blindAttack` estiver ativada e o padrão de seleção for `smaller`,
// seleciona o modelo com menor capacidade de carga.
// Se não houver informações sobre os recursos, a opção `blindAttack` estiver ativada
// e o padrão de seleção for `smaller`, seleciona o modelo com menor capacidade de carga.
return templates.reduce((prev, curr) => prev.carry < curr.carry ? prev : curr);
};

// Do contrário, apenas seleciona o modelo com maior capacidade de carga.
return templates.reduce((prev, curr) => prev.carry > curr.carry ? prev : curr);
const best = templates.reduce((prev, curr) => prev.carry > curr.carry ? prev : curr);

if (
config.useC &&
config.useCPattern === 'excess' &&
calcResourceRatio(info.res.total, best) > config.useCWhenResourceRatioIsBiggerThan
) {
const templateC = await getTemplateC(info, config);
if (templateC) return templateC;
};

return best;
};

async function getTemplateC(info: PlunderTargetInfo, config: ReturnType<typeof usePlunderConfigStore>) {
Expand All @@ -236,6 +257,7 @@ async function getTemplateC(info: PlunderTargetInfo, config: ReturnType<typeof u
if (!button) return null;

if (info.distance > config.maxDistanceC) return null;
if ((Date.now() - info.lastAttack) > config.ignoreOlderThanC * Kronos.Hour) return null;

const json = button.getAttributeStrict('data-units-forecast');
const cUnits = JSON.parse(json) as UnitAmount;
Expand Down
173 changes: 103 additions & 70 deletions electron/database/plunder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,33 @@ export class PlunderConfig extends Model<InferAttributes<PlunderConfig>, InferCr
declare readonly ignoreDelay: boolean;
declare readonly blindAttack: boolean;

// Configurações
declare readonly wallLevelToIgnore: WallLevel;
declare readonly wallLevelToDestroy: WallLevel;
declare readonly destroyWallMaxDistance: number;
declare readonly attackDelay: number;
declare readonly resourceRatio: number;
declare readonly minutesUntilReload: number;
// Ataque
declare readonly maxDistance: number;
declare readonly ignoreOlderThan: number;
declare readonly plunderedResourcesRatio: number;
declare readonly pageDelay: number;
declare readonly villageDelay: number;
declare readonly attackDelay: number;
declare readonly resourceRatio: number;
declare readonly blindAttackPattern: BlindAttackPattern;

// Modelo C
declare readonly useCPattern: UseCPattern;
declare readonly maxDistanceC: number;
declare readonly ignoreOlderThanC: number;
declare readonly useCWhenResourceRatioIsBiggerThan: number;

// Grupo
declare readonly plunderGroupId: number | null;
declare readonly fieldsPerWave: number;
declare readonly villageDelay: number;

declare readonly blindAttackPattern: BlindAttackPattern;
declare readonly useCPattern: UseCPattern;
// Muralha
declare readonly wallLevelToIgnore: WallLevel;
declare readonly wallLevelToDestroy: WallLevel;
declare readonly destroyWallMaxDistance: number;

// Outros
declare readonly minutesUntilReload: number;
declare readonly plunderedResourcesRatio: number;
declare readonly pageDelay: number;
};

PlunderConfig.init({
Expand All @@ -65,6 +73,7 @@ PlunderConfig.init({
}
},

// Painel
active: {
type: DataTypes.BOOLEAN,
allowNull: false,
Expand Down Expand Up @@ -101,34 +110,22 @@ PlunderConfig.init({
defaultValue: false
},

wallLevelToIgnore: {
type: DataTypes.INTEGER,
// Ataque
maxDistance: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 1,
defaultValue: 20,
validate: {
isWallLevel(value: unknown) {
assertWallLevel(value, DatabaseError);
}
min: 1,
isFloat: true
}
},

wallLevelToDestroy: {
ignoreOlderThan: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
validate: {
isWallLevel(value: unknown) {
assertWallLevel(value, DatabaseError);
}
}
},
destroyWallMaxDistance: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 20,
defaultValue: 10,
validate: {
min: 1,
isFloat: true
isInt: true
}
},
attackDelay: {
Expand All @@ -151,51 +148,63 @@ PlunderConfig.init({
isFloat: true
}
},
minutesUntilReload: {
type: DataTypes.INTEGER,
blindAttackPattern: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 10,
defaultValue: 'smaller' satisfies BlindAttackPattern,
validate: {
min: 1,
max: 60,
isInt: true
isIn: [['smaller', 'bigger'] satisfies BlindAttackPattern[]]
}
},
maxDistance: {

// Modelo C
useCPattern: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'normal' satisfies UseCPattern,
validate: {
isIn: [['excess', 'normal', 'only'] satisfies UseCPattern[]]
}
},
maxDistanceC: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 20,
defaultValue: 10,
validate: {
min: 1,
isFloat: true
}
},
ignoreOlderThan: {
ignoreOlderThanC: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 10,
defaultValue: 5,
validate: {
isInt: true
}
},
plunderedResourcesRatio: {
useCWhenResourceRatioIsBiggerThan: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 1,
defaultValue: 3,
validate: {
min: 0.2,
max: 1,
min: 1,
isFloat: true
}
},
pageDelay: {

// Grupo
plunderGroupId: {
type: DataTypes.INTEGER,
allowNull: true
},
fieldsPerWave: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 2000,
defaultValue: 10,
validate: {
min: 100,
max: 60000,
isInt: true
min: 5,
isFloat: true
}
},
villageDelay: {
Expand All @@ -208,7 +217,30 @@ PlunderConfig.init({
isInt: true
}
},
maxDistanceC: {

// Muralha
wallLevelToIgnore: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
validate: {
isWallLevel(value: unknown) {
assertWallLevel(value, DatabaseError);
}
}
},

wallLevelToDestroy: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
validate: {
isWallLevel(value: unknown) {
assertWallLevel(value, DatabaseError);
}
}
},
destroyWallMaxDistance: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 20,
Expand All @@ -218,36 +250,37 @@ PlunderConfig.init({
}
},

plunderGroupId: {
// Outros
minutesUntilReload: {
type: DataTypes.INTEGER,
allowNull: true
},
fieldsPerWave: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 10,
validate: {
min: 5,
isFloat: true
min: 1,
max: 60,
isInt: true
}
},

blindAttackPattern: {
type: DataTypes.STRING,
plunderedResourcesRatio: {
type: DataTypes.FLOAT,
allowNull: false,
defaultValue: 'smaller' satisfies BlindAttackPattern,
defaultValue: 1,
validate: {
isIn: [['smaller', 'bigger'] satisfies BlindAttackPattern[]]
min: 0.2,
max: 1,
isFloat: true
}
},
useCPattern: {
type: DataTypes.STRING,
pageDelay: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 'normal' satisfies UseCPattern,
defaultValue: 2000,
validate: {
isIn: [['normal', 'only'] satisfies UseCPattern[]]
min: 100,
max: 60000,
isInt: true
}
}
}
}, { sequelize, tableName: 'plunder_config', timestamps: true });

export class PlunderHistory extends Model<InferAttributes<PlunderHistory>, InferCreationAttributes<PlunderHistory>> implements PlunderHistoryType {
Expand Down
Loading