Improve hero balance with commitments

This commit is contained in:
Anton Vakhrushev 2020-05-02 10:51:00 +03:00
parent 9f17ed2bc3
commit bacedb0d84
3 changed files with 46 additions and 75 deletions

View File

@ -1,31 +1,47 @@
import { ActionController, registerAction } from './ActionController';
import { grabVillageResources, grabVillageResourceStorage } from '../Page/ResourcesBlock';
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
import { grabActiveVillageId } from '../Page/VillageBlock';
import { grabActiveVillageId, grabVillageList } from '../Page/VillageBlock';
import { HeroStorage } from '../Storage/HeroStorage';
import { calcHeroResource } from '../Core/HeroBalance';
import { HeroAllResources } from '../Core/Hero';
import { Args } from '../Queue/Args';
import { Task } from '../Queue/TaskProvider';
import { Resources } from '../Core/Resources';
import { createVillageStates } from '../VillageState';
import { ActionError } from '../Errors';
@registerAction
export class BalanceHeroResourcesAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const activeVillageId = grabActiveVillageId();
const thisVillageId = grabActiveVillageId();
const heroVillageId = new HeroStorage().getVillageId();
if (heroVillageId === undefined || activeVillageId !== heroVillageId) {
if (heroVillageId === undefined || heroVillageId !== thisVillageId) {
changeHeroResource(HeroAllResources);
return;
}
const resources = grabVillageResources();
const requiredResources = this.scheduler.getVillageRequiredResources(heroVillageId);
const totalRequiredResources = this.scheduler.getTotalVillageRequiredResources(heroVillageId);
const storage = grabVillageResourceStorage();
const currentType = grabCurrentHeroResource();
const villages = grabVillageList();
const villageStates = createVillageStates(villages, this.scheduler);
const thisVillageState = villageStates.find(s => s.id === thisVillageId);
const heroType = calcHeroResource(resources, requiredResources, totalRequiredResources, storage);
if (!thisVillageState) {
throw new ActionError(`State for village ${thisVillageId} not found`);
}
const requirements = [
thisVillageState.required.balance,
thisVillageState.commitments,
thisVillageState.totalRequired.balance,
thisVillageState.resources.sub(thisVillageState.storage),
];
console.log('Requirements');
console.table(requirements);
const heroType = calcHeroResource(requirements);
const currentType = grabCurrentHeroResource();
if (heroType !== currentType) {
changeHeroResource(heroType);

View File

@ -1,39 +1,27 @@
import { Resources } from './Resources';
import { ResourceStorage } from './ResourceStorage';
import { HeroAllResources, HeroResourceType } from './Hero';
export function calcHeroResource(
current: Resources,
required: Resources,
totalRequired: Resources,
storage: ResourceStorage
): HeroResourceType {
const resourceDiff = calcNeedResources(current, required, totalRequired, storage);
export function calcHeroResource(requirements: ReadonlyArray<Resources>): HeroResourceType {
const resourceDiff = getFirstRequirement(requirements);
const resourcesAsList = resourceDiff.asList();
const sorted = resourcesAsList.sort((x, y) => y.value - x.value);
const sorted = resourcesAsList.sort((x, y) => x.value - y.value);
const maxRequirement = sorted[0];
const minRequirement = sorted[sorted.length - 1];
const delta = maxRequirement.value - minRequirement.value;
const eps = maxRequirement.value / 10;
const delta = Math.abs(maxRequirement.value - minRequirement.value);
const eps = Math.abs(maxRequirement.value / 10);
return delta > eps ? maxRequirement.type : HeroAllResources;
}
function calcNeedResources(
current: Resources,
required: Resources,
totalRequired: Resources,
storage: ResourceStorage
): Resources {
if (current.lt(required)) {
return required.sub(current);
function getFirstRequirement(requirements: ReadonlyArray<Resources>): Resources {
for (let required of requirements) {
if (required.lt(Resources.zero())) {
return required;
}
}
if (current.lt(totalRequired)) {
return totalRequired.sub(current);
}
return Resources.fromStorage(storage).sub(current);
return Resources.zero();
}

View File

@ -4,51 +4,18 @@ import { expect } from 'chai';
import { calcHeroResource } from '../../src/Core/HeroBalance';
import { Resources } from '../../src/Core/Resources';
import { ResourceType } from '../../src/Core/ResourceType';
import { ResourceStorage } from '../../src/Core/ResourceStorage';
describe('HeroBalance', function() {
it('Get resource for requirement', function() {
const current = new Resources(100, 100, 100, 100);
const required = new Resources(200, 200, 400, 300);
const totalRequired = new Resources(200, 200, 400, 300);
const storage = new ResourceStorage(1000, 1000);
const heroRes = calcHeroResource(current, required, totalRequired, storage);
expect(ResourceType.Iron).to.equals(heroRes);
it('Get resource for single requirement', function() {
const req = new Resources(0, 0, -100, 0);
const heroRes = calcHeroResource([req]);
expect(heroRes).to.equals(ResourceType.Iron);
});
it('Get resource if one is enough, others non equal', function() {
const current = new Resources(100, 100, 100, 500);
const required = new Resources(200, 200, 400, 300);
const totalRequired = new Resources(200, 200, 400, 300);
const storage = new ResourceStorage(1000, 1000);
const heroRes = calcHeroResource(current, required, totalRequired, storage);
expect(ResourceType.Iron).to.equals(heroRes);
});
it('Get resource if one is enough, others three equal', function() {
const current = new Resources(100, 100, 100, 500);
const required = new Resources(400, 400, 400, 300);
const totalRequired = new Resources(400, 400, 400, 300);
const storage = new ResourceStorage(1000, 1000);
const heroRes = calcHeroResource(current, required, totalRequired, storage);
expect(ResourceType.Lumber).to.equals(heroRes);
});
it('Get resource if all are enough, but storage non optimal', function() {
const current = new Resources(500, 400, 300, 600);
const required = new Resources(100, 100, 100, 100);
const totalRequired = new Resources(100, 100, 100, 100);
const storage = new ResourceStorage(1000, 1000);
const heroRes = calcHeroResource(current, required, totalRequired, storage);
expect(ResourceType.Iron).to.equals(heroRes);
});
it('Get resource if enough, but total not enough', function() {
const current = new Resources(300, 300, 300, 300);
const required = new Resources(100, 100, 100, 100);
const totalRequired = new Resources(500, 600, 200, 200);
const storage = new ResourceStorage(1000, 1000);
const heroRes = calcHeroResource(current, required, totalRequired, storage);
expect(ResourceType.Clay).to.equals(heroRes);
it('Get resource for second requirement', function() {
const req1 = new Resources(0, 0, 100, 0);
const req2 = new Resources(0, -200, 20, 0);
const heroRes = calcHeroResource([req1, req2]);
expect(heroRes).to.equals(ResourceType.Clay);
});
});