Scheduler: buildings after training

This commit is contained in:
Anton Vakhrushev 2020-04-19 19:38:30 +03:00
parent 500e266517
commit c203666280

View File

@ -10,6 +10,7 @@ import { GrabVillageState } from './Task/GrabVillageState';
import { ActionList, ActionQueue } from './Queue/ActionQueue'; import { ActionList, ActionQueue } from './Queue/ActionQueue';
import { Resources, ResourcesInterface } from './Game'; import { Resources, ResourcesInterface } from './Game';
import { UpdateResourceContracts } from './Task/UpdateResourceContracts'; import { UpdateResourceContracts } from './Task/UpdateResourceContracts';
import { TrainTroopTask } from './Task/TrainTroopTask';
export class Scheduler { export class Scheduler {
private taskQueue: TaskQueue; private taskQueue: TaskQueue;
@ -57,16 +58,10 @@ export class Scheduler {
scheduleTask(name: string, args: Args, ts?: number | undefined): void { scheduleTask(name: string, args: Args, ts?: number | undefined): void {
this.logger.log('PUSH TASK', name, args, ts); this.logger.log('PUSH TASK', name, args, ts);
this.taskQueue.push(name, args, ts || timestamp());
const villageId = args.villageId; const villageId = args.villageId;
if (isBuildingTask(name)) { if (villageId) {
const insertedTs = calculateTimeToPushAfter( this.reorderVillageTasks(villageId);
this.taskQueue.seeItems(),
t => isBuildingTask(t.name) && sameVillage(villageId, t.args),
ts
);
this.taskQueue.push(name, args, insertedTs);
} else {
this.taskQueue.push(name, args, ts || timestamp());
} }
} }
@ -92,16 +87,22 @@ export class Scheduler {
if (!task) { if (!task) {
return; return;
} }
if (isBuildingTask(task.name) && task.args.villageId) {
this.taskQueue.modify( const villageId = task.args.villageId;
t => sameVillage(task.args.villageId, t.args), const modifyTime = t => withTime(t, timestamp() + seconds);
t => withTime(t, timestamp() + seconds) const buildPred = t => sameVillage(villageId, t.args) && isBuildingTask(task.name);
); const trainPred = t => sameVillage(villageId, t.args) && isTrainTroopTask(task.name);
if (isBuildingTask(task.name) && villageId) {
this.taskQueue.modify(buildPred, modifyTime);
} else if (isTrainTroopTask(task.name) && villageId) {
this.taskQueue.modify(trainPred, modifyTime);
} else { } else {
this.taskQueue.modify( this.taskQueue.modify(t => t.id === taskId, modifyTime);
t => t.id === taskId, }
t => withTime(t, timestamp() + seconds)
); if (villageId) {
this.reorderVillageTasks(villageId);
} }
} }
@ -128,6 +129,20 @@ export class Scheduler {
} }
return undefined; return undefined;
} }
private reorderVillageTasks(villageId: number) {
const tasks = this.taskQueue.seeItems();
const trainPred = t => isTrainTroopTask(t.name) && sameVillage(villageId, t.args);
const buildPred = t => isBuildingTask(t.name) && sameVillage(villageId, t.args);
const lastTrainTaskTs = lastTaskTime(tasks, trainPred);
if (lastTrainTaskTs) {
this.taskQueue.modify(buildPred, t => withTime(t, lastTrainTaskTs + 1));
}
}
}
function isTrainTroopTask(taskName: string) {
return taskName === TrainTroopTask.name;
} }
function isBuildingTask(taskName: string) { function isBuildingTask(taskName: string) {
@ -146,14 +161,16 @@ function withResources(task: Task, resources: ResourcesInterface): Task {
return new Task(task.id, task.ts, task.name, { ...task.args, resources }); return new Task(task.id, task.ts, task.name, { ...task.args, resources });
} }
function calculateTimeToPushAfter(tasks: TaskList, predicate: (t: Task) => boolean, ts: number | undefined): number { function firstTaskTime(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined {
const normalizedTs = ts || timestamp(); return tasks.find(predicate)?.ts;
}
function lastTaskTime(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined {
const queuedTaskIndex = findLastIndex(tasks, predicate); const queuedTaskIndex = findLastIndex(tasks, predicate);
if (queuedTaskIndex === undefined) { if (queuedTaskIndex === undefined) {
return normalizedTs; return undefined;
} }
const queuedTask = tasks[queuedTaskIndex]; return tasks[queuedTaskIndex].ts;
return Math.max(normalizedTs, queuedTask.ts + 1);
} }
function findLastIndex(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined { function findLastIndex(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined {