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

Commit

Permalink
Merge pull request #159 from ferreira-tb/150-opções-adicionais-para-u…
Browse files Browse the repository at this point in the history
…so-do-modelo-c

feat: adiciona novas opções ao modelo C
  • Loading branch information
ferreira-tb authored Apr 18, 2023
2 parents 04d4ab1 + 6f91698 commit 27e617f
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 189 deletions.
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

0 comments on commit 27e617f

Please sign in to comment.