Improve resources sending

Configure rounding values and postpone timeout
This commit is contained in:
Anton Vakhrushev 2020-05-17 22:16:01 +03:00
parent 0625abd4eb
commit 3b34e06a7d
7 changed files with 90 additions and 14 deletions

View File

@ -92,23 +92,28 @@ export class SendResourcesAction extends ActionController {
} }
private getResourcesForTransfer(senderState: VillageState, recipientState: VillageState): Resources { private getResourcesForTransfer(senderState: VillageState, recipientState: VillageState): Resources {
const multiplier = senderState.settings.sendResourcesMultiplier;
const timeout = senderState.settings.sendResourcesTimeout; const timeout = senderState.settings.sendResourcesTimeout;
const senderReadySendResources = this.getSenderAvailableResources(senderState); const senderReadyResources = this.getSenderAvailableResources(senderState).downTo(multiplier);
const recipientNeedsResources = this.getRecipientRequirements(recipientState, timeout); const recipientNeedResources = this.getRecipientRequirements(recipientState, timeout).upTo(multiplier);
const contractResources = senderReadySendResources.min(recipientNeedsResources); const contractResources = senderReadyResources.min(recipientNeedResources);
const merchantsCapacity = this.getMerchantsCapacity(timeout); const merchantsCapacity = this.getMerchantsCapacity(timeout);
let readyToTransfer = contractResources; let readyToTransfer = contractResources;
if (contractResources.amount() > merchantsCapacity) { if (contractResources.amount() > merchantsCapacity) {
const merchantScale = merchantsCapacity / contractResources.amount(); 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.log('Merchants capacity', merchantsCapacity);
console.table([ console.table([
{ name: 'Sender', ...senderReadySendResources }, { name: 'Sender', ...senderReadyResources },
{ name: 'Recipient', ...recipientNeedsResources }, { name: 'Recipient', ...recipientNeedResources },
{ name: 'Prepared', ...contractResources }, { name: 'Prepared', ...contractResources },
{ name: 'Ready to transfer', ...readyToTransfer }, { name: 'Ready to transfer', ...readyToTransfer },
]); ]);

View File

@ -118,4 +118,33 @@ export class Resources implements ResourcesInterface {
empty(): boolean { empty(): boolean {
return this.eq(Resources.zero()); 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));
}
} }

View File

@ -40,9 +40,11 @@ export type VillageList = Array<Village>;
export interface VillageSettings { export interface VillageSettings {
sendResourcesThreshold: number; sendResourcesThreshold: number;
sendResourcesTimeout: number; sendResourcesTimeout: number;
sendResourcesMultiplier: number;
} }
export const VillageSettingsDefaults: VillageSettings = { export const VillageSettingsDefaults: VillageSettings = {
sendResourcesTimeout: 15, sendResourcesTimeout: 15,
sendResourcesThreshold: 100, sendResourcesThreshold: 100,
sendResourcesMultiplier: 10,
} as const; } as const;

View File

@ -14,6 +14,7 @@ export enum Mutations {
SetVillageSettings = 'set_village_settings', SetVillageSettings = 'set_village_settings',
UpdateVillageSendResourceThreshold = 'UpdateVillageSendResourceThreshold', UpdateVillageSendResourceThreshold = 'UpdateVillageSendResourceThreshold',
UpdateVillageSendResourceTimeout = 'UpdateVillageSendResourceTimeout', UpdateVillageSendResourceTimeout = 'UpdateVillageSendResourceTimeout',
UpdateVillageSendResourcesMultiplier = 'UpdateVillageSendResourcesMultiplier',
} }
export enum Actions { export enum Actions {
@ -34,6 +35,7 @@ export function createStore(villageStateRepository: VillageStateRepository) {
villageName: '', villageName: '',
sendResourcesThreshold: 0, sendResourcesThreshold: 0,
sendResourcesTimeout: 0, sendResourcesTimeout: 0,
sendResourcesMultiplier: 0,
}, },
}, },
getters: { getters: {
@ -66,6 +68,9 @@ export function createStore(villageStateRepository: VillageStateRepository) {
[Mutations.UpdateVillageSendResourceTimeout](state, value) { [Mutations.UpdateVillageSendResourceTimeout](state, value) {
state.villageSettings.sendResourcesTimeout = getNumber(value); state.villageSettings.sendResourcesTimeout = getNumber(value);
}, },
[Mutations.UpdateVillageSendResourcesMultiplier](state, value) {
state.villageSettings.sendResourcesMultiplier = getNumber(value);
},
}, },
actions: { actions: {
[Actions.OpenVillageEditor]({ commit }, { villageId }) { [Actions.OpenVillageEditor]({ commit }, { villageId }) {
@ -76,6 +81,7 @@ export function createStore(villageStateRepository: VillageStateRepository) {
villageName: state.village.name, villageName: state.village.name,
sendResourcesThreshold: settings.sendResourcesThreshold, sendResourcesThreshold: settings.sendResourcesThreshold,
sendResourcesTimeout: settings.sendResourcesTimeout, sendResourcesTimeout: settings.sendResourcesTimeout,
sendResourcesMultiplier: settings.sendResourcesMultiplier,
}); });
commit(Mutations.ToggleVillageEditor, true); commit(Mutations.ToggleVillageEditor, true);
}, },
@ -87,6 +93,9 @@ export function createStore(villageStateRepository: VillageStateRepository) {
state.villageSettings.sendResourcesThreshold || VillageSettingsDefaults.sendResourcesThreshold, state.villageSettings.sendResourcesThreshold || VillageSettingsDefaults.sendResourcesThreshold,
sendResourcesTimeout: sendResourcesTimeout:
state.villageSettings.sendResourcesTimeout || VillageSettingsDefaults.sendResourcesTimeout, state.villageSettings.sendResourcesTimeout || VillageSettingsDefaults.sendResourcesTimeout,
sendResourcesMultiplier:
state.villageSettings.sendResourcesMultiplier ||
VillageSettingsDefaults.sendResourcesMultiplier,
}; };
const storage = new VillageStorage(villageId); const storage = new VillageStorage(villageId);
storage.storeSettings(newSettings); storage.storeSettings(newSettings);

View File

@ -13,6 +13,10 @@
<label class="label" title="Таймаут отправки (мин)">Таймаут отправки (мин)</label> <label class="label" title="Таймаут отправки (мин)">Таймаут отправки (мин)</label>
<input class="input" type="text" v-model="sendResourcesTimeout" /> <input class="input" type="text" v-model="sendResourcesTimeout" />
</div> </div>
<div class="form-input">
<label class="label" title="Множитель отправки (up to)">Множитель отправки (up to)</label>
<input class="input" type="text" v-model="sendResourcesMultiplier" />
</div>
<div class="form-actions"> <div class="form-actions">
<button class="btn">Сохранить</button> <button class="btn">Сохранить</button>
</div> </div>
@ -45,6 +49,14 @@ export default {
this.$store.commit(Mutations.UpdateVillageSendResourceTimeout, value); this.$store.commit(Mutations.UpdateVillageSendResourceTimeout, value);
}, },
}, },
sendResourcesMultiplier: {
get() {
return this.$store.state.villageSettings.sendResourcesMultiplier;
},
set(value) {
this.$store.commit(Mutations.UpdateVillageSendResourcesMultiplier, value);
},
},
}, },
methods: { methods: {
close() { close() {

View File

@ -231,14 +231,13 @@ export default {
villageHint(villageState) { villageHint(villageState) {
const id = villageState.id; const id = villageState.id;
const name = villageState.village.name; const name = villageState.village.name;
const timeout = villageState.settings.sendResourcesTimeout; return `${name}, ${id}`;
const threshold = villageState.settings.sendResourcesThreshold;
return `${name}, ${id}, отправка ${timeout} мин, порог ${threshold}`;
}, },
villageStatus(villageState) { villageStatus(villageState) {
const timeout = villageState.settings.sendResourcesTimeout; const timeout = villageState.settings.sendResourcesTimeout;
const threshold = villageState.settings.sendResourcesThreshold; const threshold = villageState.settings.sendResourcesThreshold;
return `отправка ${timeout} мин, порог ${threshold}`; const multiplier = villageState.settings.sendResourcesMultiplier;
return `отправка ${timeout} мин, порог ${threshold}, множ. ${multiplier}`;
}, },
path(name, args) { path(name, args) {
return path(name, args); return path(name, args);

View File

@ -7,24 +7,44 @@ describe('Resources', function() {
it('Can compare with lt', function() { it('Can compare with lt', function() {
const x = new Resources(0, 0, 0, 0); const x = new Resources(0, 0, 0, 0);
const y = new Resources(5, 5, 5, 5); 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() { it('Can compare with lt (mixed)', function() {
const x = new Resources(20, 20, 5, 20); const x = new Resources(20, 20, 5, 20);
const y = new Resources(10, 10, 10, 10); 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() { it('Can compare with gt', function() {
const x = new Resources(5, 5, 5, 5); const x = new Resources(5, 5, 5, 5);
const y = new Resources(0, 0, 0, 0); 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() { it('Can compare with gt (mixed)', function() {
const x = new Resources(30, 30, 10, 30); const x = new Resources(30, 30, 10, 30);
const y = new Resources(20, 20, 20, 20); 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;
}); });
}); });