From 3b34e06a7d1256eea2ffd533584e6a6519278f10 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 17 May 2020 22:16:01 +0300 Subject: [PATCH] Improve resources sending Configure rounding values and postpone timeout --- src/Action/SendResourcesAction.ts | 17 +++++++++------ src/Core/Resources.ts | 29 ++++++++++++++++++++++++++ src/Core/Village.ts | 2 ++ src/DashboardView/Store.ts | 9 ++++++++ src/DashboardView/VillageEditor.vue | 12 +++++++++++ src/DashboardView/VillageStateList.vue | 7 +++---- tests/Core/ResourcesTest.ts | 28 +++++++++++++++++++++---- 7 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/Action/SendResourcesAction.ts b/src/Action/SendResourcesAction.ts index 174fd23..e54dabd 100644 --- a/src/Action/SendResourcesAction.ts +++ b/src/Action/SendResourcesAction.ts @@ -92,23 +92,28 @@ export class SendResourcesAction extends ActionController { } private getResourcesForTransfer(senderState: VillageState, recipientState: VillageState): Resources { + const multiplier = senderState.settings.sendResourcesMultiplier; const timeout = senderState.settings.sendResourcesTimeout; - const senderReadySendResources = this.getSenderAvailableResources(senderState); - const recipientNeedsResources = this.getRecipientRequirements(recipientState, timeout); - const contractResources = senderReadySendResources.min(recipientNeedsResources); + const senderReadyResources = this.getSenderAvailableResources(senderState).downTo(multiplier); + const recipientNeedResources = this.getRecipientRequirements(recipientState, timeout).upTo(multiplier); + const contractResources = senderReadyResources.min(recipientNeedResources); const merchantsCapacity = this.getMerchantsCapacity(timeout); let readyToTransfer = contractResources; if (contractResources.amount() > merchantsCapacity) { const merchantScale = merchantsCapacity / contractResources.amount(); - readyToTransfer = contractResources.scale(merchantScale); + readyToTransfer = contractResources.scale(merchantScale).downTo(multiplier); + } + + if (readyToTransfer.empty()) { + throw new TryLaterError(aroundMinutes(timeout), 'Not enough resources to transfer'); } console.log('Merchants capacity', merchantsCapacity); console.table([ - { name: 'Sender', ...senderReadySendResources }, - { name: 'Recipient', ...recipientNeedsResources }, + { name: 'Sender', ...senderReadyResources }, + { name: 'Recipient', ...recipientNeedResources }, { name: 'Prepared', ...contractResources }, { name: 'Ready to transfer', ...readyToTransfer }, ]); diff --git a/src/Core/Resources.ts b/src/Core/Resources.ts index 568bfd1..ac8d1a9 100644 --- a/src/Core/Resources.ts +++ b/src/Core/Resources.ts @@ -118,4 +118,33 @@ export class Resources implements ResourcesInterface { empty(): boolean { return this.eq(Resources.zero()); } + + upTo(multiplier: number): Resources { + const upper = (v: number) => { + if (v === 0) { + return v; + } + if (v % multiplier === 0) { + return v; + } + return (Math.floor(v / multiplier) + 1) * multiplier; + }; + + return new Resources(upper(this.lumber), upper(this.clay), upper(this.iron), upper(this.crop)); + } + + downTo(multiplier: number): Resources { + const lower = (v: number) => { + if (v === 0) { + return v; + } + if (v % multiplier === 0) { + return v; + } + const part = Math.floor(v / multiplier); + return part * multiplier; + }; + + return new Resources(lower(this.lumber), lower(this.clay), lower(this.iron), lower(this.crop)); + } } diff --git a/src/Core/Village.ts b/src/Core/Village.ts index 3735c84..95619f0 100644 --- a/src/Core/Village.ts +++ b/src/Core/Village.ts @@ -40,9 +40,11 @@ export type VillageList = Array; export interface VillageSettings { sendResourcesThreshold: number; sendResourcesTimeout: number; + sendResourcesMultiplier: number; } export const VillageSettingsDefaults: VillageSettings = { sendResourcesTimeout: 15, sendResourcesThreshold: 100, + sendResourcesMultiplier: 10, } as const; diff --git a/src/DashboardView/Store.ts b/src/DashboardView/Store.ts index f669679..932b774 100644 --- a/src/DashboardView/Store.ts +++ b/src/DashboardView/Store.ts @@ -14,6 +14,7 @@ export enum Mutations { SetVillageSettings = 'set_village_settings', UpdateVillageSendResourceThreshold = 'UpdateVillageSendResourceThreshold', UpdateVillageSendResourceTimeout = 'UpdateVillageSendResourceTimeout', + UpdateVillageSendResourcesMultiplier = 'UpdateVillageSendResourcesMultiplier', } export enum Actions { @@ -34,6 +35,7 @@ export function createStore(villageStateRepository: VillageStateRepository) { villageName: '', sendResourcesThreshold: 0, sendResourcesTimeout: 0, + sendResourcesMultiplier: 0, }, }, getters: { @@ -66,6 +68,9 @@ export function createStore(villageStateRepository: VillageStateRepository) { [Mutations.UpdateVillageSendResourceTimeout](state, value) { state.villageSettings.sendResourcesTimeout = getNumber(value); }, + [Mutations.UpdateVillageSendResourcesMultiplier](state, value) { + state.villageSettings.sendResourcesMultiplier = getNumber(value); + }, }, actions: { [Actions.OpenVillageEditor]({ commit }, { villageId }) { @@ -76,6 +81,7 @@ export function createStore(villageStateRepository: VillageStateRepository) { villageName: state.village.name, sendResourcesThreshold: settings.sendResourcesThreshold, sendResourcesTimeout: settings.sendResourcesTimeout, + sendResourcesMultiplier: settings.sendResourcesMultiplier, }); commit(Mutations.ToggleVillageEditor, true); }, @@ -87,6 +93,9 @@ export function createStore(villageStateRepository: VillageStateRepository) { state.villageSettings.sendResourcesThreshold || VillageSettingsDefaults.sendResourcesThreshold, sendResourcesTimeout: state.villageSettings.sendResourcesTimeout || VillageSettingsDefaults.sendResourcesTimeout, + sendResourcesMultiplier: + state.villageSettings.sendResourcesMultiplier || + VillageSettingsDefaults.sendResourcesMultiplier, }; const storage = new VillageStorage(villageId); storage.storeSettings(newSettings); diff --git a/src/DashboardView/VillageEditor.vue b/src/DashboardView/VillageEditor.vue index d3b12be..786abfd 100644 --- a/src/DashboardView/VillageEditor.vue +++ b/src/DashboardView/VillageEditor.vue @@ -13,6 +13,10 @@ +
+ + +
@@ -45,6 +49,14 @@ export default { this.$store.commit(Mutations.UpdateVillageSendResourceTimeout, value); }, }, + sendResourcesMultiplier: { + get() { + return this.$store.state.villageSettings.sendResourcesMultiplier; + }, + set(value) { + this.$store.commit(Mutations.UpdateVillageSendResourcesMultiplier, value); + }, + }, }, methods: { close() { diff --git a/src/DashboardView/VillageStateList.vue b/src/DashboardView/VillageStateList.vue index 4f5df9c..4f7645e 100644 --- a/src/DashboardView/VillageStateList.vue +++ b/src/DashboardView/VillageStateList.vue @@ -231,14 +231,13 @@ export default { villageHint(villageState) { const id = villageState.id; const name = villageState.village.name; - const timeout = villageState.settings.sendResourcesTimeout; - const threshold = villageState.settings.sendResourcesThreshold; - return `${name}, ${id}, отправка ${timeout} мин, порог ${threshold}`; + return `${name}, ${id}`; }, villageStatus(villageState) { const timeout = villageState.settings.sendResourcesTimeout; const threshold = villageState.settings.sendResourcesThreshold; - return `отправка ${timeout} мин, порог ${threshold}`; + const multiplier = villageState.settings.sendResourcesMultiplier; + return `отправка ${timeout} мин, порог ${threshold}, множ. ${multiplier}`; }, path(name, args) { return path(name, args); diff --git a/tests/Core/ResourcesTest.ts b/tests/Core/ResourcesTest.ts index da1e0dc..7036ce5 100644 --- a/tests/Core/ResourcesTest.ts +++ b/tests/Core/ResourcesTest.ts @@ -7,24 +7,44 @@ describe('Resources', function() { it('Can compare with lt', function() { const x = new Resources(0, 0, 0, 0); const y = new Resources(5, 5, 5, 5); - expect(true).is.equals(x.lt(y)); + expect(x.lt(y)).is.true; }); it('Can compare with lt (mixed)', function() { const x = new Resources(20, 20, 5, 20); const y = new Resources(10, 10, 10, 10); - expect(true).is.equals(x.lt(y)); + expect(x.lt(y)).is.true; }); it('Can compare with gt', function() { const x = new Resources(5, 5, 5, 5); const y = new Resources(0, 0, 0, 0); - expect(true).is.equals(x.gt(y)); + expect(x.gt(y)).is.true; }); it('Can compare with gt (mixed)', function() { const x = new Resources(30, 30, 10, 30); const y = new Resources(20, 20, 20, 20); - expect(false).is.equals(x.gt(y)); + expect(x.gt(y)).is.false; + }); + + it('Can up to 1', function() { + const resources = new Resources(0, 4, 10, 18); + const upped = resources.upTo(1); + expect(upped.eq(resources)).is.true; + }); + + it('Can up to 10', function() { + const resources = new Resources(0, 4, 10, 18); + const expected = new Resources(0, 10, 10, 20); + const upped = resources.upTo(10); + expect(upped.eq(expected)).is.true; + }); + + it('Can down to 10', function() { + const resources = new Resources(0, 4, 10, 18); + const expected = new Resources(0, 0, 10, 10); + const lowed = resources.downTo(10); + expect(lowed.eq(expected)).is.true; }); });