From bacedb0d842b3717a54967b78982e1887f6d4ee2 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sat, 2 May 2020 10:51:00 +0300 Subject: [PATCH] Improve hero balance with commitments --- src/Action/BalanceHeroResourcesAction.ts | 34 +++++++++++----- src/Core/HeroBalance.ts | 36 ++++++----------- tests/Core/HeroBalanceTest.ts | 51 +++++------------------- 3 files changed, 46 insertions(+), 75 deletions(-) diff --git a/src/Action/BalanceHeroResourcesAction.ts b/src/Action/BalanceHeroResourcesAction.ts index 3247f7f..5c1072c 100644 --- a/src/Action/BalanceHeroResourcesAction.ts +++ b/src/Action/BalanceHeroResourcesAction.ts @@ -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 { - 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); diff --git a/src/Core/HeroBalance.ts b/src/Core/HeroBalance.ts index 89ea658..ca8c5f2 100644 --- a/src/Core/HeroBalance.ts +++ b/src/Core/HeroBalance.ts @@ -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): 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 { + 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(); } diff --git a/tests/Core/HeroBalanceTest.ts b/tests/Core/HeroBalanceTest.ts index 4c2dab8..2a51a9d 100644 --- a/tests/Core/HeroBalanceTest.ts +++ b/tests/Core/HeroBalanceTest.ts @@ -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); }); });