Improve hero balance with commitments
This commit is contained in:
parent
9f17ed2bc3
commit
bacedb0d84
@ -1,31 +1,47 @@
|
|||||||
import { ActionController, registerAction } from './ActionController';
|
import { ActionController, registerAction } from './ActionController';
|
||||||
import { grabVillageResources, grabVillageResourceStorage } from '../Page/ResourcesBlock';
|
import { grabVillageResources, grabVillageResourceStorage } from '../Page/ResourcesBlock';
|
||||||
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
|
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
|
||||||
import { grabActiveVillageId } from '../Page/VillageBlock';
|
import { grabActiveVillageId, grabVillageList } from '../Page/VillageBlock';
|
||||||
import { HeroStorage } from '../Storage/HeroStorage';
|
import { HeroStorage } from '../Storage/HeroStorage';
|
||||||
import { calcHeroResource } from '../Core/HeroBalance';
|
import { calcHeroResource } from '../Core/HeroBalance';
|
||||||
import { HeroAllResources } from '../Core/Hero';
|
import { HeroAllResources } from '../Core/Hero';
|
||||||
import { Args } from '../Queue/Args';
|
import { Args } from '../Queue/Args';
|
||||||
import { Task } from '../Queue/TaskProvider';
|
import { Task } from '../Queue/TaskProvider';
|
||||||
|
import { Resources } from '../Core/Resources';
|
||||||
|
import { createVillageStates } from '../VillageState';
|
||||||
|
import { ActionError } from '../Errors';
|
||||||
|
|
||||||
@registerAction
|
@registerAction
|
||||||
export class BalanceHeroResourcesAction extends ActionController {
|
export class BalanceHeroResourcesAction extends ActionController {
|
||||||
async run(args: Args, task: Task): Promise<any> {
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
const activeVillageId = grabActiveVillageId();
|
const thisVillageId = grabActiveVillageId();
|
||||||
const heroVillageId = new HeroStorage().getVillageId();
|
const heroVillageId = new HeroStorage().getVillageId();
|
||||||
|
|
||||||
if (heroVillageId === undefined || activeVillageId !== heroVillageId) {
|
if (heroVillageId === undefined || heroVillageId !== thisVillageId) {
|
||||||
changeHeroResource(HeroAllResources);
|
changeHeroResource(HeroAllResources);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resources = grabVillageResources();
|
const villages = grabVillageList();
|
||||||
const requiredResources = this.scheduler.getVillageRequiredResources(heroVillageId);
|
const villageStates = createVillageStates(villages, this.scheduler);
|
||||||
const totalRequiredResources = this.scheduler.getTotalVillageRequiredResources(heroVillageId);
|
const thisVillageState = villageStates.find(s => s.id === thisVillageId);
|
||||||
const storage = grabVillageResourceStorage();
|
|
||||||
const currentType = grabCurrentHeroResource();
|
|
||||||
|
|
||||||
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) {
|
if (heroType !== currentType) {
|
||||||
changeHeroResource(heroType);
|
changeHeroResource(heroType);
|
||||||
|
@ -1,39 +1,27 @@
|
|||||||
import { Resources } from './Resources';
|
import { Resources } from './Resources';
|
||||||
import { ResourceStorage } from './ResourceStorage';
|
|
||||||
import { HeroAllResources, HeroResourceType } from './Hero';
|
import { HeroAllResources, HeroResourceType } from './Hero';
|
||||||
|
|
||||||
export function calcHeroResource(
|
export function calcHeroResource(requirements: ReadonlyArray<Resources>): HeroResourceType {
|
||||||
current: Resources,
|
const resourceDiff = getFirstRequirement(requirements);
|
||||||
required: Resources,
|
|
||||||
totalRequired: Resources,
|
|
||||||
storage: ResourceStorage
|
|
||||||
): HeroResourceType {
|
|
||||||
const resourceDiff = calcNeedResources(current, required, totalRequired, storage);
|
|
||||||
const resourcesAsList = resourceDiff.asList();
|
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 maxRequirement = sorted[0];
|
||||||
const minRequirement = sorted[sorted.length - 1];
|
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;
|
return delta > eps ? maxRequirement.type : HeroAllResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcNeedResources(
|
function getFirstRequirement(requirements: ReadonlyArray<Resources>): Resources {
|
||||||
current: Resources,
|
for (let required of requirements) {
|
||||||
required: Resources,
|
if (required.lt(Resources.zero())) {
|
||||||
totalRequired: Resources,
|
return required;
|
||||||
storage: ResourceStorage
|
}
|
||||||
): Resources {
|
|
||||||
if (current.lt(required)) {
|
|
||||||
return required.sub(current);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.lt(totalRequired)) {
|
return Resources.zero();
|
||||||
return totalRequired.sub(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Resources.fromStorage(storage).sub(current);
|
|
||||||
}
|
}
|
||||||
|
@ -4,51 +4,18 @@ import { expect } from 'chai';
|
|||||||
import { calcHeroResource } from '../../src/Core/HeroBalance';
|
import { calcHeroResource } from '../../src/Core/HeroBalance';
|
||||||
import { Resources } from '../../src/Core/Resources';
|
import { Resources } from '../../src/Core/Resources';
|
||||||
import { ResourceType } from '../../src/Core/ResourceType';
|
import { ResourceType } from '../../src/Core/ResourceType';
|
||||||
import { ResourceStorage } from '../../src/Core/ResourceStorage';
|
|
||||||
|
|
||||||
describe('HeroBalance', function() {
|
describe('HeroBalance', function() {
|
||||||
it('Get resource for requirement', function() {
|
it('Get resource for single requirement', function() {
|
||||||
const current = new Resources(100, 100, 100, 100);
|
const req = new Resources(0, 0, -100, 0);
|
||||||
const required = new Resources(200, 200, 400, 300);
|
const heroRes = calcHeroResource([req]);
|
||||||
const totalRequired = new Resources(200, 200, 400, 300);
|
expect(heroRes).to.equals(ResourceType.Iron);
|
||||||
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 non equal', function() {
|
it('Get resource for second requirement', function() {
|
||||||
const current = new Resources(100, 100, 100, 500);
|
const req1 = new Resources(0, 0, 100, 0);
|
||||||
const required = new Resources(200, 200, 400, 300);
|
const req2 = new Resources(0, -200, 20, 0);
|
||||||
const totalRequired = new Resources(200, 200, 400, 300);
|
const heroRes = calcHeroResource([req1, req2]);
|
||||||
const storage = new ResourceStorage(1000, 1000);
|
expect(heroRes).to.equals(ResourceType.Clay);
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user