1 /*
2  * Copyright (C) 2009-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_AI_AI_HELP_STRUCTS_H
21 #define WL_AI_AI_HELP_STRUCTS_H
22 
23 #include <bitset>
24 
25 #include "ai/ai_hints.h"
26 #include "economy/flag.h"
27 #include "economy/road.h"
28 #include "logic/ai_dna_handler.h"
29 #include "logic/game.h"
30 #include "logic/map.h"
31 #include "logic/map_objects/checkstep.h"
32 #include "logic/map_objects/findnode.h"
33 #include "logic/map_objects/map_object.h"
34 #include "logic/map_objects/tribes/ship.h"
35 #include "logic/map_objects/world/terrain_description.h"
36 #include "logic/map_objects/world/world.h"
37 #include "logic/player.h"
38 
39 namespace Widelands {
40 
41 class ProductionSite;
42 class MilitarySite;
43 
44 enum class ExtendedBool : uint8_t { kUnset, kTrue, kFalse };
45 
46 enum class MutatingIntensity : uint8_t { kNo, kNormal, kAgressive };
47 
48 enum class BuildingNecessity : uint8_t {
49 	kForced,
50 	kNeeded,
51 	kNotNeeded,
52 	kUnset,
53 	kNotBuildable,
54 	kAllowed,
55 	kNeededPending,
56 	kForbidden
57 };
58 
59 // A building type can have no, one or multiple of these attributes
60 enum class BuildingAttribute : uint8_t {
61 	kRanger,
62 	kBuildable,
63 	kLumberjack,
64 	kPort,
65 	kNeedsRocks,
66 	kWell,
67 	kNeedsCoast,
68 	kHunter,
69 	kFisher,
70 	kShipyard,
71 	kBarracks,
72 	kSpaceConsumer,
73 	kRecruitment,
74 	kBuildingMatProducer,
75 	kUpgradeSubstitutes,
76 	kUpgradeExtends,
77 	// TODO(Nordfriese): Someone should update the AI code to handle buildings that need waterways
78 	// enabled
79 	kNeedsSeafaring,
80 	kSupportsSeafaring,
81 	kSupportingProducer,
82 	kNeedsBerry,
83 };
84 
85 enum class ExpansionMode : uint8_t { kResources = 0, kSpace = 1, kEconomy = 2, kBoth = 3 };
86 
87 enum class AiModeBuildings : uint8_t { kAnotherAllowed, kOnLimit, kLimitExceeded };
88 
89 enum class SchedulerTaskId : uint8_t {
90 	kBbuildableFieldsCheck,
91 	kMineableFieldsCheck,
92 	kRoadCheck,
93 	kUnbuildableFCheck,
94 	kCheckEconomies,
95 	kProductionsitesStats,
96 	kConstructBuilding,
97 	kCheckProductionsites,
98 	kCheckShips,
99 	KMarineDecisions,
100 	kCheckMines,
101 	kWareReview,
102 	kPrintStats,
103 	kCheckMilitarysites,
104 	kCheckTrainingsites,
105 	kCountMilitaryVacant,
106 	kCheckEnemySites,
107 	kManagementUpdate,
108 	kUpdateStats,
109 	kWarehouseFlagDist,
110 	kUnset
111 };
112 
113 enum class DnaParent : uint8_t { kPrimary, kSecondary };
114 
115 // This is a simplification of a curve, to avoid repeated calculation
116 const std::vector<std::vector<int8_t>> neuron_curves = {
117    {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100},
118    {0, 0, 1, 2, 4, 6, 9, 12, 16, 20, 25, 30, 36, 42, 49, 56, 64, 72, 81, 90, 100},
119    {0, 17, 25, 32, 38, 44, 49, 53, 58, 62, 66, 70, 74, 78, 81, 84, 88, 91, 94, 97, 100},
120 };
121 
122 // TODO(tiborb): this should be replaced by command line switch
123 constexpr int kFNeuronBitSize = 32;
124 constexpr int kMutationRatePosition = 42;
125 // This is expiration time for distance from a flag to nearest warehouse
126 constexpr int kFlagDistanceExpirationPeriod = 120 * 1000;
127 // If the distance of flag-warehouse was not updated for this time, we presume that the flag
128 // does not exist anymore and remove it
129 constexpr int kOldFlagRemoveTime = 5 * 60 * 1000;
130 
131 constexpr uint32_t kNever = std::numeric_limits<uint32_t>::max();
132 
133 constexpr uint32_t kNoField = std::numeric_limits<uint32_t>::max();
134 
135 constexpr uint32_t kOneMinute = 60 * 1000;
136 
137 constexpr uint16_t kFarButReachable = 1000;
138 
139 struct CheckStepRoadAI {
140 	CheckStepRoadAI(Player* const pl, uint8_t const mc, bool const oe);
141 
142 	bool allowed(const Map&, FCoords start, FCoords end, int32_t dir, CheckStep::StepId) const;
143 	bool reachable_dest(const Map&, const FCoords& dest) const;
144 
145 	Player* player;
146 	uint8_t movecaps;
147 	bool open_end;
148 };
149 
150 // Used to walk ower own territory, on fields that are walkable (or as given by mc)
151 // plus one step more to a field with own immovable. So that also flags and buildings are
152 // included in resulting list
153 struct CheckStepOwnTerritory {
154 	CheckStepOwnTerritory(Player* const pl, uint8_t const mc, bool const oe);
155 
156 	bool allowed(const Map&, FCoords start, FCoords end, int32_t dir, CheckStep::StepId) const;
157 	bool reachable_dest(const Map&, const FCoords& dest) const;
158 
159 	Player* player;
160 	uint8_t movecaps;
161 	bool open_end;
162 };
163 
164 // We are looking for fields we can walk on
165 // and owned by hostile player.
166 struct FindNodeEnemy {
167 	FindNodeEnemy(Player* p, Game& g);
168 
169 	bool accept(const EditorGameBase&, const FCoords& fc) const;
170 
171 	Player* player;
172 	Game& game;
173 };
174 
175 // We are looking for buildings owned by hostile player
176 // (sometimes there is a enemy's teritorry without buildings, and
177 // this confuses the AI)
178 
179 struct FindNodeEnemiesBuilding {
180 	FindNodeEnemiesBuilding(Player* p, Game& g);
181 
182 	bool accept(const EditorGameBase&, const FCoords& fc) const;
183 
184 	Player* player;
185 	Game& game;
186 };
187 
188 // We need to count walkable fields owned by enemy
189 struct FindEnemyNodeWalkable {
190 	FindEnemyNodeWalkable(Player* p, Game& g);
191 
192 	bool accept(const EditorGameBase&, const FCoords& fc) const;
193 
194 	Player* player;
195 	Game& game;
196 };
197 
198 // Sometimes we need to know how many nodes our allies owns
199 struct FindNodeAllyOwned {
200 	FindNodeAllyOwned(Player* p, Game& g, PlayerNumber n);
201 
202 	bool accept(const EditorGameBase&, const FCoords& fc) const;
203 
204 	Player* player;
205 	Game& game;
206 	PlayerNumber player_number;
207 };
208 
209 // When looking for unowned terrain to acquire, we must
210 // pay speciall attention to fields where mines can be built.
211 // Fields should be completely unowned
212 struct FindNodeUnownedMineable {
213 	FindNodeUnownedMineable(Player* p, Game& g, int32_t t = INVALID_INDEX);
214 
215 	bool accept(const EditorGameBase&, const FCoords& fc) const;
216 
217 	Player* player;
218 	Game& game;
219 	int32_t ore_type;
220 };
221 
222 // When looking for unowned terrain to acquire, we must
223 // consider if any buildings (incl. mines) can be built on unowned land.
224 struct FindNodeUnownedBuildable {
225 	FindNodeUnownedBuildable(Player* p, Game& g);
226 
227 	bool accept(const EditorGameBase&, const FCoords& fc) const;
228 
229 	Player* player;
230 	Game& game;
231 };
232 
233 // Unowned but walkable fields nearby
234 struct FindNodeUnownedWalkable {
235 	FindNodeUnownedWalkable(Player* p, Game& g);
236 
237 	bool accept(const EditorGameBase&, const FCoords& fc) const;
238 
239 	Player* player;
240 	Game& game;
241 };
242 
243 // Looking only for mines-capable fields nearby
244 // of specific type
245 struct FindNodeMineable {
246 	FindNodeMineable(Game& g, DescriptionIndex r);
247 
248 	bool accept(const EditorGameBase&, const FCoords& fc) const;
249 
250 	Game& game;
251 	int32_t res;
252 };
253 
254 // Fishers and fishbreeders must be built near water
255 struct FindNodeWater {
256 	explicit FindNodeWater(const World& world);
257 
258 	bool accept(const EditorGameBase&, const FCoords& coord) const;
259 
260 private:
261 	const World& world_;
262 };
263 
264 // This is to be used for shipyards to make sure the water is wide enough
265 // Open water is a field where all 6 adjacent triangles are water
266 struct FindNodeOpenWater {
267 	// 'world' is unused, but we need to fit the template.
FindNodeOpenWaterFindNodeOpenWater268 	explicit FindNodeOpenWater(const World& /* world */) {
269 	}
270 
271 	bool accept(const EditorGameBase&, const FCoords& coord) const;
272 };
273 
274 struct FindNodeWithFlagOrRoad {
275 	bool accept(const EditorGameBase&, FCoords) const;
276 };
277 
278 // Accepts any field
279 struct FindNodeAcceptAll {
acceptFindNodeAcceptAll280 	bool accept(const EditorGameBase&, FCoords) const {
281 		return true;
282 	}
283 };
284 
285 struct NearFlag {
286 	// ordering nearflags by biggest reduction
287 	struct CompareShortening {
operatorNearFlag::CompareShortening288 		bool operator()(const NearFlag& a, const NearFlag& b) const {
289 			return a.current_road_distance > b.current_road_distance;
290 		}
291 	};
292 	NearFlag();
293 	NearFlag(const Flag* f, int32_t const c);
294 
295 	bool operator<(const NearFlag& f) const {
296 		return current_road_distance > f.current_road_distance;
297 	}
298 
299 	bool operator==(Flag const* const f) const {
300 		return flag == f;
301 	}
302 
303 	Flag const* flag;
304 	bool to_be_checked;
305 	uint32_t current_road_distance;
306 };
307 
308 // FIFO like structure for pairs <gametime,id>, where id is optional
309 // used to count events within a time frame - duration_ (older ones are
310 // stripped with strip_old function)
311 struct EventTimeQueue {
312 	EventTimeQueue();
313 
314 	void push(uint32_t, uint32_t = std::numeric_limits<uint32_t>::max());
315 	uint32_t count(uint32_t, uint32_t = std::numeric_limits<uint32_t>::max());
316 	void strip_old(uint32_t);
317 
318 private:
319 	const uint32_t duration_ = 20 * 60 * 1000;
320 	// FIFO container where newest goes to the front
321 	std::deque<std::pair<uint32_t, uint32_t>> queue;
322 };
323 
324 struct WalkableSpot {
325 	Coords coords;
326 	bool has_flag;
327 
328 	int32_t cost;
329 	void* eco;
330 
331 	int16_t from;
332 	int16_t neighbours[6];
333 };
334 
335 struct BuildableField {
336 	explicit BuildableField(const Widelands::FCoords& fc);
337 
338 	Widelands::FCoords coords;
339 
340 	uint32_t field_info_expiration;
341 
342 	bool preferred;
343 	bool enemy_nearby;
344 	bool enemy_accessible_;
345 
346 	bool enemy_wh_nearby;
347 	uint16_t unowned_land_nearby;
348 	uint16_t enemy_owned_land_nearby;
349 	uint16_t unowned_buildable_spots_nearby;
350 	uint16_t unowned_portspace_vicinity_nearby;
351 	uint16_t nearest_buildable_spot_nearby;
352 	// to identify that field is too close to border and no production building should be built there
353 	bool near_border;
354 	uint16_t unowned_mines_spots_nearby;
355 	uint16_t unowned_iron_mines_nearby;
356 	uint8_t trees_nearby;
357 	uint8_t bushes_nearby;
358 	uint8_t rocks_nearby;
359 	int16_t water_nearby;
360 	int16_t open_water_nearby;
361 	int16_t distant_water;
362 	int16_t fish_nearby;
363 	int8_t critters_nearby;
364 	ResourceAmount ground_water;  // used by wells
365 	uint8_t space_consumers_nearby;
366 	uint8_t rangers_nearby;
367 	// to manage the military better following variables exists:
368 	// capacity of nearby buildings:
369 	int16_t area_military_capacity;
370 	// distance to near buldings:
371 	int16_t military_loneliness;
372 	// count of military buildings in construction
373 	// when making decision on new mulitary buildings it considers also
374 	// unowned fields and mines, but this information is not quite correct as there
375 	// are construction sites that will change this once they are built
376 	int16_t military_in_constr_nearby;
377 	// actual count of soldiers in nearby buldings
378 	int16_t own_military_presence;
379 	int16_t enemy_military_presence;
380 	int16_t enemy_military_sites;  // Including unfinished
381 	int16_t ally_military_presence;
382 	// stationed (manned) military buildings nearby
383 	int16_t military_stationed;
384 	// unconnected buildings nearby
385 	bool unconnected_nearby;
386 	int16_t military_unstationed;
387 	int16_t own_non_military_nearby;
388 	bool defense_msite_allowed;
389 	Widelands::ExtendedBool is_portspace;
390 	bool port_nearby;  // to increase priority if a port is nearby,
391 	// especially for new colonies
392 	Widelands::ExtendedBool portspace_nearby;  // special fields intended for ports
393 	int32_t max_buildcap_nearby;
394 	// It is not necessary to check resources (stones, fish...) too frequently as they do not change
395 	// fast. This stores the time of the last check.
396 	uint32_t last_resources_check_time;
397 	int32_t military_score_;
398 	bool inland;
399 	uint16_t local_soldier_capacity;
400 	bool is_militarysite;
401 
402 	std::vector<uint8_t> consumers_nearby;
403 	std::vector<uint8_t> producers_nearby;
404 	std::vector<uint8_t> collecting_producers_nearby;
405 	// and for rangers, fishbreeders:
406 	std::vector<uint8_t> supporters_nearby;
407 };
408 
409 struct MineableField {
410 	explicit MineableField(const Widelands::FCoords& fc);
411 
412 	Widelands::FCoords coords;
413 	uint32_t field_info_expiration;
414 	bool preferred;
415 	int32_t mines_nearby;
416 	// this is to provide that a mine is not built on the edge of mine area
417 	int32_t same_mine_fields_nearby;
418 };
419 
420 struct EconomyObserver {
421 	explicit EconomyObserver(Widelands::Economy& e);
422 
423 	Widelands::Economy& economy;
424 	std::deque<Widelands::Flag const*> flags;
425 	uint32_t dismantle_grace_time;
426 	uint32_t fields_block_last_time;
427 };
428 
429 struct BuildingObserver {
430 
431 	enum class Type {
432 		kBoring,
433 		kConstructionsite,
434 		kProductionsite,
435 		kMilitarysite,
436 		kWarehouse,
437 		kTrainingsite,
438 		kMine
439 	};
440 
441 	int32_t total_count() const;
442 	Widelands::AiModeBuildings aimode_limit_status() const;
443 	bool buildable(Widelands::Player& p);
444 
445 	// Convenience functions for is_what
446 	bool is(BuildingAttribute) const;
447 	void set_is(BuildingAttribute);
448 	void unset_is(BuildingAttribute);
449 
450 	// Building collects a ware from the map
451 	bool has_collected_map_resource() const;
452 	void set_collected_map_resource(const TribeDescr& tribe, const std::string& ware_name);
453 	DescriptionIndex get_collected_map_resource() const;
454 
455 	char const* name;
456 	Widelands::DescriptionIndex id;
457 	Widelands::BuildingDescr const* desc;
458 
459 	Type type;
460 
461 	Widelands::BuildingNecessity new_building;
462 	uint32_t new_building_overdue;
463 	int32_t primary_priority;
464 
465 	bool expansion_type;       // military building used that can be used to control area
466 	bool fighting_type;        // military building built near enemies
467 	bool mountain_conqueror;   // military building built near mountains
468 	uint32_t prohibited_till;  // do not build before (ms)
469 	uint32_t forced_after;     // do not wait until ware is needed
470 	uint8_t max_trainingsites_proportion;
471 
472 	uint16_t unconnected_count;  // to any warehouse (count of such buildings)
473 
474 	DescriptionIndex mines;  // type of resource it mines_
475 	uint16_t mines_percent;  // % of res it can mine
476 	uint32_t current_stats;
477 
478 	uint32_t basic_amount;  // basic amount for basic economy as defined in init.lua
479 
480 	std::vector<Widelands::DescriptionIndex> inputs;
481 	std::vector<Widelands::DescriptionIndex> ware_outputs;
482 	std::vector<Widelands::DescriptionIndex> positions;
483 	std::vector<Widelands::DescriptionIndex> critical_building_material;
484 
485 	// It seems that fish and meat are subsitutes (for trainingsites), so
486 	// when testing if a trainingsite is supplied enough
487 	// we count the wares together
488 	std::unordered_set<Widelands::DescriptionIndex> substitute_inputs;
489 	int32_t substitutes_count;
490 
491 	std::set<DescriptionIndex> production_hints;
492 
493 	bool requires_supporters;
494 
495 	// information needed for decision on new building construction
496 	int16_t initial_preciousness;
497 	int16_t max_preciousness;
498 	int16_t max_needed_preciousness;
499 	int32_t cnt_built;
500 	int32_t cnt_under_construction;
501 	int32_t cnt_target;           // number of buildings as target
502 	int32_t cnt_limit_by_aimode;  // limit imposed by weak or normal AI mode
503 
504 	int32_t cnt_upgrade_pending;  // number of buildings that are to be upgraded
505 
506 	// used to track amount of wares produced by building
507 	uint32_t stocklevel_count;
508 	uint32_t stocklevel_time;  // time when stocklevel_ was last time recalculated
509 	uint32_t last_dismantle_time;
510 	uint32_t construction_decision_time;
511 	uint32_t last_building_built;
512 
513 	uint32_t unoccupied_count;
514 
515 	bool build_material_shortage;
516 
517 private:
518 	DescriptionIndex collected_map_resource;
519 	std::set<BuildingAttribute> is_what;
520 };
521 
522 struct ProductionSiteObserver {
523 	Widelands::ProductionSite* site = nullptr;
524 	uint32_t built_time = 0U;
525 	uint32_t unoccupied_till = 0U;
526 	uint32_t no_resources_since = kNever;
527 	bool upgrade_pending = false;
528 	uint32_t dismantle_pending_since = kNever;
529 	BuildingObserver* bo = nullptr;
530 };
531 
532 struct MilitarySiteObserver {
533 	Widelands::MilitarySite* site;
534 	BuildingObserver* bo;
535 	uint16_t understaffed;
536 	uint32_t last_change;  // to prevent switching the occupancy policy too fast
537 	uint32_t built_time;
538 };
539 
540 struct TrainingSiteObserver {
541 	Widelands::TrainingSite* site;
542 	BuildingObserver* bo;
543 };
544 
545 struct WarehouseSiteObserver {
546 
547 	Widelands::Warehouse* site;
548 	BuildingObserver* bo;
549 	uint32_t flag_distances_last_update;
550 };
551 
552 struct ShipObserver {
553 	Widelands::Ship* ship;
554 	bool waiting_for_command_ = false;
555 	uint32_t last_command_time = 0;
556 	bool escape_mode = false;
557 
558 	// direction by which the ship circumvents an island
559 	// this is the last circle-island command's direction
560 	Widelands::IslandExploreDirection island_circ_direction =
561 	   Widelands::IslandExploreDirection::kClockwise;
562 };
563 
564 struct WareObserver {
565 	bool refined_build_material = false;
566 	uint8_t preciousness;
567 };
568 
569 // Computer player does not get notification messages about enemy militarysites
570 // and warehouses, so following is collected based on observation
571 // It is conventient to have some information preserved, like nearby minefields,
572 // when it was attacked, whether it is warehouse and so on
573 // Also AI test more such targets when considering attack and calculated score is
574 // is stored in the observer
575 struct EnemySiteObserver {
576 	bool is_warehouse = false;
577 	int32_t attack_soldiers_strength = 0;
578 	int32_t attack_soldiers_competency = 0;
579 	int32_t defenders_strength = 0;
580 	uint8_t stationed_soldiers = 0U;
581 	uint32_t last_time_seen = 0U;
582 	uint32_t last_tested = 0U;
583 	int16_t score = 0;
584 	Widelands::ExtendedBool mines_nearby = Widelands::ExtendedBool::kUnset;
585 	uint32_t last_time_attacked = 0U;
586 	uint32_t attack_counter = 0U;
587 	uint16_t enemy_military_presence_in_region = 0U;
588 	uint16_t enemy_military_sites_in_region = 0U;
589 };
590 
591 // as all mines have 3 levels, AI does not know total count of mines per mined material
592 // so this observer will be used for this
593 struct MineTypesObserver {
594 	MineTypesObserver();
595 
596 	uint16_t total_count() const;
597 
598 	uint16_t in_construction;
599 	uint16_t finished;
600 	bool is_critical;
601 	uint16_t unoccupied;
602 };
603 
604 // This struct contains count of mineable fields grouped by ore/resource type
605 struct MineFieldsObserver {
606 
607 	void zero();
608 	void add(Widelands::DescriptionIndex);
609 	void add_critical_ore(Widelands::DescriptionIndex);
610 	bool has_critical_ore_fields();
611 	uint16_t get(Widelands::DescriptionIndex);
612 	uint8_t count_types();
613 
614 private:
615 	// This is the central information of the struct: a pair of resource and count of fields
616 	std::map<Widelands::DescriptionIndex, uint16_t> stat;
617 	std::set<Widelands::DescriptionIndex> critical_ores;
618 };
619 
620 constexpr int kNeuronWeightLimit = 100;
621 constexpr size_t kNeuronMaxPosition = 20;
622 constexpr size_t kSecondParentProbability = 50;
623 
624 // A bunch of parameters used for trainig AI (for calculation of fitness function result)
625 constexpr int16_t kCurrentLandDivider = 2;
626 constexpr int16_t kLandDeltaMultiplier = 1;
627 constexpr int16_t kBonus = 1000;
628 constexpr int16_t kAttackersMultiplier = 1;
629 constexpr int16_t kAttackBonus = 100;
630 constexpr int16_t kTrainedSoldiersScore = 250;
631 constexpr int16_t kConqueredWhBonus = 300;
632 constexpr int16_t kStrengthMultiplier = 30;
633 constexpr int16_t kPSitesRatioMultiplier = 1;
634 
635 struct Neuron {
clip_weight_to_rangeNeuron636 	static int clip_weight_to_range(int w) {
637 		assert(w < 125);
638 		assert(w > -125);
639 		return std::max(-kNeuronWeightLimit, std::min(kNeuronWeightLimit, w));
640 	}
641 
642 	Neuron(int8_t, uint8_t, uint16_t);
643 	void recalculate();
644 	void set_weight(int8_t w);
get_weightNeuron645 	int8_t get_weight() {
646 		return weight;
647 	}
648 	int8_t get_result(size_t);
649 	int8_t get_result_safe(int32_t, bool = false);
650 	void set_type(uint8_t);
get_typeNeuron651 	uint8_t get_type() {
652 		return type;
653 	}
get_idNeuron654 	uint16_t get_id() {
655 		return id;
656 	}
657 
658 private:
659 	int8_t results[21];  // kPositions + 1
660 	int8_t weight;
661 	uint8_t type;
662 	uint16_t id;
663 };
664 
665 struct FNeuron {
666 	FNeuron(uint32_t, uint16_t);
667 
668 	void flip_bit(uint8_t);
669 	bool get_result(bool, bool, bool, bool bool4 = true, bool bool5 = true);
670 	bool get_position(uint8_t);
671 	uint32_t get_int();
get_idFNeuron672 	uint16_t get_id() {
673 		return id;
674 	}
675 
676 private:
677 	std::bitset<kFNeuronBitSize> core;
678 	uint16_t id;
679 };
680 
681 struct ExpansionType {
682 	ExpansionType();
683 
684 	void set_expantion_type(ExpansionMode);
get_expansion_typeExpansionType685 	ExpansionMode get_expansion_type() {
686 		return type;
687 	}
688 
689 private:
690 	ExpansionMode type;
691 };
692 
693 // This is to keep all data related to AI magic numbers
694 struct ManagementData {
695 	void mutate(PlayerNumber = 0);
696 	void new_dna_for_persistent(uint8_t, Widelands::AiType);
697 	void copy_persistent_to_local();
698 	void review(uint32_t gametime,
699 	            PlayerNumber pn,
700 	            uint32_t land,
701 	            uint32_t max_e_land,
702 	            uint32_t old_land,
703 	            uint16_t attackers,
704 	            int16_t trained_soldiers,
705 	            uint16_t strength,
706 	            uint32_t existing_ps,
707 	            uint32_t first_iron_mine_time);
708 	void dump_data(PlayerNumber);
new_neuron_idManagementData709 	uint16_t new_neuron_id() {
710 		++next_neuron_id;
711 		return next_neuron_id - 1;
712 	}
reset_neuron_idManagementData713 	void reset_neuron_id() {
714 		next_neuron_id = 0;
715 	}
new_bi_neuron_idManagementData716 	uint16_t new_bi_neuron_id() {
717 		++next_bi_neuron_id;
718 		return next_bi_neuron_id - 1;
719 	}
reset_bi_neuron_idManagementData720 	void reset_bi_neuron_id() {
721 		next_bi_neuron_id = 0;
722 	}
set_ai_training_modeManagementData723 	void set_ai_training_mode() {
724 		ai_training_mode_ = true;
725 	}
726 
727 	int16_t get_military_number_at(uint8_t);
728 	void set_military_number_at(uint8_t, int16_t);
729 	MutatingIntensity do_mutate(uint8_t, int16_t);
730 	int8_t shift_weight_value(int8_t, bool = true);
731 	void test_consistency(bool = false);
732 
733 	std::vector<Neuron> neuron_pool;
734 	std::vector<FNeuron> f_neuron_pool;
735 	Widelands::Player::AiPersistentState* persistent_data;
736 
737 private:
738 	void dump_output(Widelands::Player::AiPersistentState, PlayerNumber);
739 
740 	int32_t score = 1;
741 	uint8_t primary_parent = 255;
742 	uint16_t next_neuron_id = 0U;
743 	uint16_t next_bi_neuron_id = 0U;
744 	uint16_t performance_change = 0U;
745 	Widelands::AiType ai_type = Widelands::AiType::kNormal;
746 	bool ai_training_mode_ = false;
747 	uint16_t pref_number_probability = 200;
748 	AiDnaHandler ai_dna_handler;
749 };
750 
751 // this is used to count militarysites by their size
752 struct MilitarySiteSizeObserver {
753 	MilitarySiteSizeObserver();
754 
755 	uint16_t in_construction;
756 	uint16_t finished;
757 };
758 
759 // this represents a scheduler task
760 struct SchedulerTask {
761 	SchedulerTask(const uint32_t time,
762 	              const Widelands::SchedulerTaskId t,
763 	              const uint8_t p,
764 	              const char* d);
765 
766 	bool operator<(const SchedulerTask& other) const;
767 
768 	uint32_t due_time;
769 	Widelands::SchedulerTaskId id;
770 	// used to sort jobs when AI has to perform more jobs at once
771 	uint8_t priority;
772 	// used only for debug purposes
773 	std::string descr;
774 };
775 
776 // List of blocked fields with block time, with some accompanying functions
777 struct BlockedFields {
778 	void add(Coords coords, uint32_t till);
779 	uint32_t count();
780 	void remove_expired(uint32_t gametime);
781 	bool is_blocked(Coords coords);
782 
783 private:
784 	// <hash of field coordinates, time till blocked>
785 	std::map<uint32_t, uint32_t> blocked_fields_;
786 };
787 
788 // This is a struct that stores strength of players, info on teams and provides some outputs from
789 // these data
790 struct PlayersStrengths {
791 private:
792 	struct PlayerStat {
793 		PlayerStat() = default;
794 		PlayerStat(Widelands::TeamNumber tc,
795 		           uint32_t pp,
796 		           uint32_t op,
797 		           uint32_t o60p,
798 		           uint32_t cs,
799 		           uint32_t land,
800 		           uint32_t oland,
801 		           uint32_t o60l);
802 
803 		Widelands::TeamNumber team_number = 0U;
804 		uint32_t players_power = 0U;
805 		uint32_t old_players_power = 0U;
806 		uint32_t old60_players_power = 0U;
807 		uint32_t players_casualities = 0U;
808 		uint32_t last_time_seen = 0U;
809 		uint32_t players_land = 0U;
810 		uint32_t old_players_land = 0U;
811 		uint32_t old60_players_land = 0U;
812 	};
813 
814 public:
815 	PlayersStrengths();
816 	// Inserting/updating data
817 	void add(Widelands::PlayerNumber pn,
818 	         Widelands::PlayerNumber opn,
819 	         Widelands::TeamNumber mytn,
820 	         Widelands::TeamNumber pltn,
821 	         uint32_t pp,
822 	         uint32_t op,
823 	         uint32_t o60p,
824 	         uint32_t cs,
825 	         uint32_t land,
826 	         uint32_t oland,
827 	         uint32_t o60l);
828 	void remove_stat(Widelands::PlayerNumber pn);
829 	void recalculate_team_power();
830 
831 	// This is strength of player plus third of strength of other members of his team
832 	uint32_t get_modified_player_power(Widelands::PlayerNumber pn);
833 	uint32_t get_player_power(Widelands::PlayerNumber pn);
834 	uint32_t get_old_player_power(Widelands::PlayerNumber pn);
835 	uint32_t get_old60_player_power(Widelands::PlayerNumber pn);
836 	uint32_t get_player_land(Widelands::PlayerNumber pn);
837 	uint32_t get_old_player_land(Widelands::PlayerNumber pn);
838 	uint32_t get_old60_player_land(Widelands::PlayerNumber pn);
839 	uint32_t get_visible_enemies_power(uint32_t);
840 	uint32_t get_enemies_average_power();
841 	uint32_t get_enemies_average_land();
842 	uint32_t get_enemies_max_power();
843 	uint32_t get_enemies_max_land();
844 	uint32_t get_old_visible_enemies_power(uint32_t);
845 	bool players_in_same_team(Widelands::PlayerNumber pl1, Widelands::PlayerNumber pl2);
846 	bool strong_enough(Widelands::PlayerNumber pl);
847 	void set_last_time_seen(uint32_t, Widelands::PlayerNumber);
848 	bool player_seen_lately(Widelands::PlayerNumber, uint32_t);
849 	bool get_is_enemy(Widelands::PlayerNumber);
850 	uint8_t enemies_seen_lately_count(uint32_t);
851 	bool any_enemy_seen_lately(uint32_t);
852 	void set_update_time(uint32_t);
853 	uint32_t get_update_time();
854 
855 private:
856 	// This is the core part of this struct
857 	std::map<Widelands::PlayerNumber, PlayerStat> all_stats;
858 
859 	// Number of team, sum of players' strength
860 	std::map<Widelands::TeamNumber, uint32_t> team_powers;
861 
862 	uint32_t update_time;
863 	PlayerNumber this_player_number;
864 	PlayerNumber this_player_team;
865 };
866 
867 // This is a wrapper around map of <Flag coords hash:distance from flag to nearest warehouse>
868 // Flags does not have observers so this stuct server like "lazy" substitution for this, where
869 // keys are hash of flags positions
870 // This "lives" during entire "session", and is not saved, but is easily recalulated
871 struct FlagWarehouseDistances {
872 private:
873 	struct FlagInfo {
874 		FlagInfo();
875 		FlagInfo(uint32_t, uint16_t, uint32_t);
876 		// Distance to a nearest warehouse expires, but in two stages
877 		// This is complete expiration and such flag is treated as without distance to WH
878 		uint32_t expiry_time;
879 		// When recalculating new distance, if the current information is younger than
880 		// soft_expiry_time it is only decreased if new value is smaller After soft_expiry_time is
881 		// updated in any case
882 		uint32_t soft_expiry_time;
883 		uint16_t distance;
884 		// This is coords hash of nearest warehouse, not used by now
885 		uint32_t nearest_warehouse;
886 		// after building of new road, the distance information is updated not immediately so
887 		// we prohibit current flag from another road building...
888 		uint32_t new_road_prohibited_till;
889 
890 		bool update(uint32_t, uint16_t, uint32_t);
891 		// Saying the road was built and when
892 		void set_road_built(uint32_t);
893 		// Asking if road can be built from this flag (providing current gametime)
894 		bool is_road_prohibited(uint32_t) const;
895 		// get current distance (providing current gametime)
896 		uint16_t get(uint32_t, uint32_t*) const;
897 	};
898 	std::map<uint32_t, FlagInfo> flags_map;
899 
900 public:
901 	// All these function uses lookup in flags_map so first argument is usually flag coords hash
902 	bool set_distance(uint32_t flag_coords,
903 	                  uint16_t distance,
904 	                  uint32_t gametime,
905 	                  uint32_t nearest_warehouse);
906 	int16_t get_distance(uint32_t flag_coords, uint32_t gametime, uint32_t* nw);
907 	void set_road_built(uint32_t coords_hash, uint32_t gametime);
908 	bool is_road_prohibited(uint32_t coords_hash, uint32_t gametime);
909 	uint16_t count() const;
910 	bool remove_old_flag(uint32_t gametime);
911 };
912 
913 // This is one-time structure - initiated and filled up when investigating possible roads to be
914 // built to a flag. At the end the flags are scored based on gained info), ordered and if treshold
915 // is achieved the road is to be built
916 struct FlagCandidates {
917 
FlagCandidatesFlagCandidates918 	explicit FlagCandidates(uint16_t wd) : start_flag_dist_to_wh(wd) {
919 	}
920 
921 	struct Candidate {
922 		Candidate() = delete;
923 		Candidate(uint32_t, bool, uint16_t, uint16_t, uint16_t);
924 		uint16_t air_distance;
925 		uint32_t coords_hash;
926 		bool different_economy;
927 		uint16_t start_flag_dist_to_wh;
928 		uint16_t flag_to_flag_road_distance;
929 		uint16_t possible_road_distance;
930 		uint16_t cand_flag_distance_to_wh;
931 		// Scoring is considering multiple things
932 		int16_t score() const;
is_buildableFlagCandidates::Candidate933 		bool is_buildable() {
934 			return possible_road_distance > 0;
935 		}
936 		bool operator<(const Candidate& other) const {
937 			return score() > other.score();
938 		}
939 	};
940 
941 private:
942 	std::vector<Candidate> flags_;
943 	uint16_t start_flag_dist_to_wh;
944 
945 public:
flagsFlagCandidates946 	const std::vector<Candidate>& flags() const {
947 		return flags_;
948 	}
949 	bool has_candidate(uint32_t) const;
950 	void add_flag(uint32_t, bool, uint16_t, uint16_t);
951 	bool set_cur_road_distance(uint32_t, uint16_t);
952 	bool set_road_possible(uint32_t, uint16_t);
953 	void sort();
954 	void sort_by_air_distance();
countFlagCandidates955 	uint32_t count() {
956 		return flags_.size();
957 	}
958 	FlagCandidates::Candidate* get_winner(const int16_t = 0);
959 };
960 }  // namespace Widelands
961 
962 #endif  // end of include guard: WL_AI_AI_HELP_STRUCTS_H
963