From 57e79b0ba27c570c955775225e771ba2a2789860 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Wed, 22 Apr 2020 10:28:56 +0300 Subject: [PATCH] Fix hero balance Add tests for checking --- .mocharc.json | 5 +++ Makefile | 2 +- package-lock.json | 20 +++++------ package.json | 6 ++-- src/Action/BalanceHeroResourcesAction.ts | 41 +++++----------------- src/Core/HeroBalance.ts | 43 ++++++++++++++++++++++++ tests/Core/HeroBalanceTest.ts | 34 +++++++++++++++++++ tsconfig.json | 2 +- 8 files changed, 106 insertions(+), 47 deletions(-) create mode 100644 .mocharc.json create mode 100644 src/Core/HeroBalance.ts create mode 100644 tests/Core/HeroBalanceTest.ts diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000..ab1e8c6 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,5 @@ +{ + "extension": ["ts"], + "spec": "tests/**/*.ts", + "require": "ts-node/register" +} \ No newline at end of file diff --git a/Makefile b/Makefile index c7e4a59..616b3f7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: format build +all: test format build restart-server: docker-compose restart diff --git a/package-lock.json b/package-lock.json index d5b601e..1c4f02c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/package.json b/package.json index c25b281..5e13699 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/Action/BalanceHeroResourcesAction.ts b/src/Action/BalanceHeroResourcesAction.ts index 9638074..cb929d8 100644 --- a/src/Action/BalanceHeroResourcesAction.ts +++ b/src/Action/BalanceHeroResourcesAction.ts @@ -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); + } } } diff --git a/src/Core/HeroBalance.ts b/src/Core/HeroBalance.ts new file mode 100644 index 0000000..fc6ba61 --- /dev/null +++ b/src/Core/HeroBalance.ts @@ -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); + } +} diff --git a/tests/Core/HeroBalanceTest.ts b/tests/Core/HeroBalanceTest.ts new file mode 100644 index 0000000..ab0210e --- /dev/null +++ b/tests/Core/HeroBalanceTest.ts @@ -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); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 3272ecf..56c874e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "allowJs": true, "experimentalDecorators": true, "isolatedModules": true, - "module": "es2015", + "module": "commonjs", "outDir": "./dist", "strictNullChecks": true, "strictPropertyInitialization": true,