Refactoring: plan actions as classes
This commit is contained in:
parent
d4ad7ec40c
commit
1b053de16a
62
src/Plan/CropBuildingPlan.ts
Normal file
62
src/Plan/CropBuildingPlan.ts
Normal 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
70
src/Plan/WarehouseBuildingPlan.ts
Normal file
70
src/Plan/WarehouseBuildingPlan.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user