Fix hero balance

Add tests for checking
This commit is contained in:
Anton Vakhrushev 2020-04-22 10:28:56 +03:00
parent ea4d6f6681
commit 57e79b0ba2
8 changed files with 106 additions and 47 deletions

5
.mocharc.json Normal file
View File

@ -0,0 +1,5 @@
{
"extension": ["ts"],
"spec": "tests/**/*.ts",
"require": "ts-node/register"
}

View File

@ -1,4 +1,4 @@
all: format build
all: test format build
restart-server:
docker-compose restart

20
package-lock.json generated
View File

@ -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"

View File

@ -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",

View File

@ -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
View 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);
}
}

View 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);
});
});

View File

@ -3,7 +3,7 @@
"allowJs": true,
"experimentalDecorators": true,
"isolatedModules": true,
"module": "es2015",
"module": "commonjs",
"outDir": "./dist",
"strictNullChecks": true,
"strictPropertyInitialization": true,