Fix hero balance
Add tests for checking
This commit is contained in:
parent
ea4d6f6681
commit
57e79b0ba2
5
.mocharc.json
Normal file
5
.mocharc.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"extension": ["ts"],
|
||||
"spec": "tests/**/*.ts",
|
||||
"require": "ts-node/register"
|
||||
}
|
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
||||
all: format build
|
||||
all: test format build
|
||||
|
||||
restart-server:
|
||||
docker-compose restart
|
||||
|
20
package-lock.json
generated
20
package-lock.json
generated
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@anwinged/predictor",
|
||||
"name": "@anwinged/travian",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
@ -47,9 +47,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz",
|
||||
"integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
|
||||
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
@ -175,9 +175,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helpers": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.0.tgz",
|
||||
"integrity": "sha512-/9GvfYTCG1NWCNwDj9e+XlnSCmWW/r9T794Xi58vPF9WCcnZCAZ0kWLSn54oqP40SUvh1T2G6VwKmFO5AOlW3A==",
|
||||
"version": "7.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz",
|
||||
"integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/template": "^7.8.3",
|
||||
@ -5152,9 +5152,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
|
||||
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz",
|
||||
"integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
|
@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@anwinged/predictor",
|
||||
"name": "@anwinged/travian",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"author": "Anton Vakhrushev",
|
||||
"license": "MIT",
|
||||
"main": "dist/predictor.js",
|
||||
"main": "dist/travian.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anwinged/predictor.git"
|
||||
"url": "https://github.com/anwinged/travian.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
|
@ -3,9 +3,10 @@ import { Args } from '../Command';
|
||||
import { Task } from '../Queue/TaskQueue';
|
||||
import { grabResources, grabResourceStorage } from '../Page/ResourcesBlock';
|
||||
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
|
||||
import { HeroAllResources, Resources } from '../Game';
|
||||
import { HeroAllResources } from '../Game';
|
||||
import { grabActiveVillageId } from '../Page/VillageBlock';
|
||||
import { HeroState } from '../State/HeroState';
|
||||
import { Core } from '../Core/HeroBalance';
|
||||
|
||||
@registerAction
|
||||
export class BalanceHeroResourcesAction extends ActionController {
|
||||
@ -18,40 +19,16 @@ export class BalanceHeroResourcesAction extends ActionController {
|
||||
return;
|
||||
}
|
||||
|
||||
const resources = this.getRequirements(heroVillageId);
|
||||
|
||||
const resourcesAsList = resources.asList();
|
||||
const currentType = grabCurrentHeroResource();
|
||||
|
||||
const sorted = resourcesAsList.sort((x, y) => y.value - x.value);
|
||||
const maxRequirement = sorted[0];
|
||||
const minRequirement = sorted[sorted.length - 1];
|
||||
const delta = Math.abs(maxRequirement.value - minRequirement.value);
|
||||
const eps = Math.abs(maxRequirement.value / 10);
|
||||
|
||||
console.log('REQUIREMENTS', sorted);
|
||||
console.log('REQUIREMENTS', maxRequirement, minRequirement, delta, eps);
|
||||
|
||||
const resType = delta > eps ? maxRequirement.type : HeroAllResources;
|
||||
if (resType !== currentType) {
|
||||
changeHeroResource(resType);
|
||||
}
|
||||
}
|
||||
|
||||
private getRequirements(heroVillageId): Resources {
|
||||
const resources = grabResources();
|
||||
const requiredResources = this.scheduler.getVillageRequiredResources(heroVillageId);
|
||||
const totalRequiredResources = this.scheduler.getTotalVillageRequiredResources(heroVillageId);
|
||||
|
||||
if (requiredResources.gt(resources)) {
|
||||
return requiredResources.sub(resources);
|
||||
}
|
||||
|
||||
if (totalRequiredResources.gt(resources)) {
|
||||
return totalRequiredResources.sub(resources);
|
||||
}
|
||||
|
||||
const storage = grabResourceStorage();
|
||||
return Resources.fromStorage(storage).sub(resources);
|
||||
const currentType = grabCurrentHeroResource();
|
||||
|
||||
const heroType = Core.calcHeroResource(resources, requiredResources, totalRequiredResources, storage);
|
||||
|
||||
if (heroType !== currentType) {
|
||||
changeHeroResource(heroType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
43
src/Core/HeroBalance.ts
Normal file
43
src/Core/HeroBalance.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { HeroAllResources, HeroResourceType, Resources, ResourceStorage } from '../Game';
|
||||
|
||||
export namespace Core {
|
||||
export function calcHeroResource(
|
||||
current: Resources,
|
||||
required: Resources,
|
||||
totalRequired: Resources,
|
||||
storage: ResourceStorage
|
||||
): HeroResourceType {
|
||||
const resourceDiff = calcNeedResources(current, required, totalRequired, storage);
|
||||
const resourcesAsList = resourceDiff.asList();
|
||||
|
||||
const sorted = resourcesAsList.filter(x => x.value > 0).sort((x, y) => y.value - x.value);
|
||||
|
||||
if (sorted.length === 0) {
|
||||
return HeroAllResources;
|
||||
}
|
||||
|
||||
const maxRequirement = sorted[0];
|
||||
const minRequirement = sorted[sorted.length - 1];
|
||||
const delta = maxRequirement.value - minRequirement.value;
|
||||
const eps = maxRequirement.value / 10;
|
||||
|
||||
return delta > eps ? maxRequirement.type : HeroAllResources;
|
||||
}
|
||||
|
||||
function calcNeedResources(
|
||||
current: Resources,
|
||||
required: Resources,
|
||||
totalRequired: Resources,
|
||||
storage: ResourceStorage
|
||||
): Resources {
|
||||
if (!current.gt(required)) {
|
||||
return required.sub(current);
|
||||
}
|
||||
|
||||
if (!current.gt(totalRequired)) {
|
||||
return totalRequired.sub(current);
|
||||
}
|
||||
|
||||
return Resources.fromStorage(storage).sub(current);
|
||||
}
|
||||
}
|
34
tests/Core/HeroBalanceTest.ts
Normal file
34
tests/Core/HeroBalanceTest.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { it, describe } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { Resources, ResourceStorage, ResourceType } from '../../src/Game';
|
||||
import { Core } from '../../src/Core/HeroBalance';
|
||||
|
||||
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 = Core.calcHeroResource(current, required, totalRequired, storage);
|
||||
expect(heroRes).to.equals(ResourceType.Iron);
|
||||
});
|
||||
|
||||
it('Get resource if one is enough', 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 = Core.calcHeroResource(current, required, totalRequired, storage);
|
||||
expect(heroRes).to.equals(ResourceType.Iron);
|
||||
});
|
||||
|
||||
it('Get resource if all are enough, but storage non optimal', function() {
|
||||
const current = new Resources(600, 600, 500, 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 = Core.calcHeroResource(current, required, totalRequired, storage);
|
||||
expect(heroRes).to.equals(ResourceType.Iron);
|
||||
});
|
||||
});
|
@ -3,7 +3,7 @@
|
||||
"allowJs": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": true,
|
||||
"module": "es2015",
|
||||
"module": "commonjs",
|
||||
"outDir": "./dist",
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": true,
|
||||
|
Loading…
Reference in New Issue
Block a user