Refactoring: plan actions as classes

This commit is contained in:
Anton Vakhrushev 2020-10-12 10:00:06 +03:00
parent d4ad7ec40c
commit 1b053de16a
4 changed files with 154 additions and 104 deletions

View File

@ -0,0 +1,62 @@
import { ConstructionPlan } from '../Village/VillageController';
import { ResourceType } from '../Core/ResourceType';
import { isBuildingPlanned } from '../Queue/Task';
import { UpgradeBuildingTask } from '../Handler/Task/UpgradeBuildingTask';
import { first } from '../Helpers/Collection';
import { VillageState } from '../Village/VillageState';
import { VillageTaskCollection } from '../Village/VillageTaskCollection';
import { VillageStorage } from '../Storage/VillageStorage';
export class CropBuildingPlan implements ConstructionPlan {
constructor(
private readonly state: VillageState,
private readonly storage: VillageStorage,
private readonly taskCollection: VillageTaskCollection
) {}
execute() {
const performance = this.state.performance;
if (performance.crop >= 30) {
return;
}
const resourceSlots = this.storage.getResourceSlots();
const tasks = this.state.tasks;
const cropSlots = resourceSlots.filter(
(s) => s.type === ResourceType.Crop && !s.isMaxLevel
);
if (cropSlots.length === 0) {
return;
}
// Check, if crop field is building now
const underContraction = cropSlots.find((s) => s.isUnderConstruction);
if (underContraction !== undefined) {
return;
}
// Check, if we already have crop task in queue
const cropBuildIds = cropSlots.map((s) => s.buildId);
for (let buildId of cropBuildIds) {
const upgradeTask = tasks.find(
isBuildingPlanned(UpgradeBuildingTask.name, buildId, undefined)
);
if (upgradeTask !== undefined) {
return;
}
}
// Find ready for building slots and sort them by level
cropSlots.sort((s1, s2) => s1.level - s2.level);
const targetCropBuildId = first(cropSlots)?.buildId;
if (!targetCropBuildId) {
return;
}
this.taskCollection.addTaskAsFirst(UpgradeBuildingTask.name, {
buildId: targetCropBuildId,
});
}
}

View File

@ -0,0 +1,70 @@
import { ConstructionPlan } from '../Village/VillageController';
import { isBuildingPlanned } from '../Queue/Task';
import { UpgradeBuildingTask } from '../Handler/Task/UpgradeBuildingTask';
import { first } from '../Helpers/Collection';
import { TaskState, VillageState } from '../Village/VillageState';
import { VillageTaskCollection } from '../Village/VillageTaskCollection';
import { VillageStorage } from '../Storage/VillageStorage';
import { BuildingSlot } from '../Core/Slot';
export class WarehouseBuildingPlan implements ConstructionPlan {
constructor(
private readonly buildTypeId: number,
private readonly checkNeedEnlargeFunc: (task: TaskState) => boolean,
private readonly state: VillageState,
private readonly storage: VillageStorage,
private readonly taskCollection: VillageTaskCollection
) {}
execute() {
const storageSlots = this.findStorageSlots();
if (storageSlots.length === 0) {
return;
}
// Check, if warehouse is building now
const underConstructionSlot = storageSlots.find((s) => s.isUnderConstruction);
if (underConstructionSlot !== undefined) {
return;
}
if (this.isWarehouseInBuildingQueue(storageSlots)) {
return;
}
const needStorageEnlargeTasks = this.state.tasks.filter(this.checkNeedEnlargeFunc);
if (needStorageEnlargeTasks.length === 0) {
return;
}
const firstSlot = first(storageSlots);
if (firstSlot) {
this.taskCollection.addTask(UpgradeBuildingTask.name, {
buildId: firstSlot.buildId,
buildTypeId: this.buildTypeId,
});
}
}
private findStorageSlots() {
const buildingSlots = this.storage.getBuildingSlots();
return buildingSlots.filter(
(slot) => slot.buildTypeId === this.buildTypeId && !slot.isMaxLevel
);
}
private isWarehouseInBuildingQueue(storageSlots: ReadonlyArray<BuildingSlot>): boolean {
const storageBuildIds = storageSlots.map((slot) => slot.buildId);
for (let buildId of storageBuildIds) {
const upgradeTask = this.state.tasks.find(
isBuildingPlanned(UpgradeBuildingTask.name, buildId, this.buildTypeId)
);
if (upgradeTask !== undefined) {
return true;
}
}
return false;
}
}

View File

@ -15,6 +15,7 @@ export interface Args {
troopId?: number; troopId?: number;
troopResources?: ResourcesInterface; troopResources?: ResourcesInterface;
trainCount?: number; trainCount?: number;
count?: number;
resources?: ResourcesInterface; resources?: ResourcesInterface;
coordinates?: CoordinatesInterface; coordinates?: CoordinatesInterface;
unitId?: number; unitId?: number;

View File

@ -5,12 +5,14 @@ import { Resources } from '../Core/Resources';
import { MerchantsInfo } from '../Core/Market'; import { MerchantsInfo } from '../Core/Market';
import { VillageStorage } from '../Storage/VillageStorage'; import { VillageStorage } from '../Storage/VillageStorage';
import { ReceiveResourcesMode } from '../Core/Village'; import { ReceiveResourcesMode } from '../Core/Village';
import { ResourceType } from '../Core/ResourceType';
import { UpgradeBuildingTask } from '../Handler/Task/UpgradeBuildingTask';
import { GARNER_ID, WAREHOUSE_ID } from '../Core/Buildings'; import { GARNER_ID, WAREHOUSE_ID } from '../Core/Buildings';
import { first } from '../Helpers/Collection';
import { isBuildingPlanned } from '../Queue/Task';
import { TaskId } from '../Queue/TaskId'; import { TaskId } from '../Queue/TaskId';
import { CropBuildingPlan } from '../Plan/CropBuildingPlan';
import { WarehouseBuildingPlan } from '../Plan/WarehouseBuildingPlan';
export interface ConstructionPlan {
execute(): void;
}
export class VillageController { export class VillageController {
private readonly villageId: number; private readonly villageId: number;
@ -157,105 +159,20 @@ export class VillageController {
if (this.state.tasks.length >= 100) { if (this.state.tasks.length >= 100) {
return; return;
} }
this.planCropBuilding(); new CropBuildingPlan(this.state, this.storage, this.taskCollection).execute();
this.planWarehouseBuilding(); new WarehouseBuildingPlan(
this.planGranaryBuilding(); WAREHOUSE_ID,
} (t) => !t.isEnoughWarehouseCapacity,
this.state,
private planCropBuilding() { this.storage,
const performance = this.state.performance; this.taskCollection
if (performance.crop >= 30) { ).execute();
return; new WarehouseBuildingPlan(
} GARNER_ID,
(t) => !t.isEnoughGranaryCapacity,
const resourceSlots = this.storage.getResourceSlots(); this.state,
const tasks = this.taskCollection.getTasks(); this.storage,
this.taskCollection
const cropSlots = resourceSlots.filter( ).execute();
(s) => s.type === ResourceType.Crop && !s.isMaxLevel
);
if (cropSlots.length === 0) {
return;
}
// Check, if crop field is building now
const underContraction = cropSlots.find((s) => s.isUnderConstruction);
if (underContraction !== undefined) {
return;
}
// Check, if we already have crop task in queue
const cropBuildIds = cropSlots.map((s) => s.buildId);
for (let buildId of cropBuildIds) {
const upgradeTask = tasks.find(
isBuildingPlanned(UpgradeBuildingTask.name, buildId, undefined)
);
if (upgradeTask !== undefined) {
return;
}
}
// Find ready for building slots and sort them by level
cropSlots.sort((s1, s2) => s1.level - s2.level);
const targetCropBuildId = first(cropSlots)?.buildId;
if (!targetCropBuildId) {
return;
}
this.taskCollection.addTaskAsFirst(UpgradeBuildingTask.name, {
buildId: targetCropBuildId,
});
}
private planWarehouseBuilding(): void {
this.planStorageBuilding(WAREHOUSE_ID, (t) => !t.isEnoughWarehouseCapacity);
}
private planGranaryBuilding(): void {
this.planStorageBuilding(GARNER_ID, (t) => !t.isEnoughGranaryCapacity);
}
private planStorageBuilding(
buildTypeId: number,
checkNeedEnlargeFunc: (task: TaskState) => boolean
): void {
const buildingSlots = this.storage.getBuildingSlots();
const storageSlots = buildingSlots.filter(
(s) => s.buildTypeId === buildTypeId && !s.isMaxLevel
);
if (storageSlots.length === 0) {
return;
}
// Check, if warehouse is building now
const underConstruction = storageSlots.find((s) => s.isUnderConstruction);
if (underConstruction !== undefined) {
return;
}
const tasks = this.state.tasks;
// Check, if we have warehouse is in building queue
const storageBuildIds = storageSlots.map((s) => s.buildId);
for (let buildId of storageBuildIds) {
const upgradeTask = tasks.find(
isBuildingPlanned(UpgradeBuildingTask.name, buildId, buildTypeId)
);
if (upgradeTask !== undefined) {
return;
}
}
const needStorageEnlargeTasks = tasks.filter(checkNeedEnlargeFunc);
if (needStorageEnlargeTasks.length === 0) {
return;
}
const firstSlot = first(storageSlots);
if (firstSlot) {
this.addTask(UpgradeBuildingTask.name, { buildId: firstSlot.buildId, buildTypeId });
}
} }
} }