1 package cz.cuni.amis.pogamut.defcon.communication.worldview.modules.managers.buildings;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 import cz.cuni.amis.pogamut.defcon.agent.impl.DefConAgentLogicController;
8 import cz.cuni.amis.pogamut.defcon.base3d.worldview.object.DefConLocation;
9 import cz.cuni.amis.pogamut.defcon.communication.messages.infos.DefConUnitObject;
10 import cz.cuni.amis.pogamut.defcon.communication.worldview.polygons.GameMapInfoPolygons;
11 import cz.cuni.amis.pogamut.defcon.consts.UnitType;
12 import cz.cuni.amis.pogamut.defcon.utils.Pair;
13 import cz.cuni.amis.pogamut.defcon.utils.quadtree.QuadTree;
14 import cz.cuni.amis.pogamut.defcon.utils.quadtree.QuadTreeBFSIterator;
15 import cz.cuni.amis.pogamut.defcon.utils.quadtree.QuadTreeNode;
16 import cz.cuni.amis.pogamut.defcon.utils.quadtree.QuadTreesManager;
17
18
19
20
21
22
23
24 public class BuildingPlacementProvider {
25
26 private DefConAgentLogicController<?> logic;
27 private GameMapInfoPolygons mapInfo;
28 private QuadTreesManager qTreesManager;
29
30 public BuildingPlacementProvider(DefConAgentLogicController<?> logic,
31 GameMapInfoPolygons mapInfo, QuadTreesManager qTreesManager) {
32 this.logic = logic;
33 this.mapInfo = mapInfo;
34 this.qTreesManager = qTreesManager;
35 }
36
37
38
39
40
41
42
43
44
45
46 public List<DefConLocation> getLocations(double minDistance, int count,
47 UnitType buildingType) {
48 ArrayList<DefConLocation> locations = new ArrayList<DefConLocation>();
49
50 while (count > locations.size() && minDistance >= 5d) {
51 collectLocationsForBuildings(
52 locations,
53 minDistance,
54 count,
55 buildingType);
56 minDistance -= 5d;
57 }
58
59 return locations;
60 }
61
62 private void collectLocationsForBuildings(
63 ArrayList<DefConLocation> locations,
64 double minDistance, int count, UnitType buildingType) {
65
66
67 for (Pair<List<QuadTree>, List<QuadTree>> territory : qTreesManager
68 .getOwnQuadTrees().values()) {
69
70 for (QuadTree qTree : territory.second) {
71
72 Iterator<QuadTreeNode> nodeIterator = new QuadTreeBFSIterator(
73 qTree);
74 while (nodeIterator.hasNext()) {
75
76 QuadTreeNode node = nodeIterator.next();
77
78 if (node.getNodes() != null || !node.isLabeled())
79 continue;
80
81
82
83
84
85
86 boolean far_enough_from_others = true;
87
88 final Class<? extends DefConUnitObject<?>> buildingClass = (Class<? extends DefConUnitObject<?>>) buildingType
89 .getClassOfUnitType();
90
91 for (DefConUnitObject<?> other_buildings : logic
92 .getWorldView()
93 .getAll(buildingClass).values()) {
94
95 if (other_buildings.getTeamId() != logic.getGameInfo()
96 .getOwnTeamId())
97 continue;
98
99 if (!logic.getGameInfo()
100 .isValidBuildingPlacementLocation(
101 node.getCenter())
102 || other_buildings.getLocation().getDistance2D(
103 node.getCenter()) < minDistance) {
104 far_enough_from_others = false;
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 break;
123 }
124
125 }
126
127 if (far_enough_from_others) {
128 for (DefConLocation other : locations) {
129
130 if (!logic.getGameInfo()
131 .isValidBuildingPlacementLocation(
132 node.getCenter())
133 || other.getDistance2D(node.getCenter()) < minDistance) {
134 far_enough_from_others = false;
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 break;
154 }
155 }
156 }
157
158 if (!far_enough_from_others)
159 continue;
160
161 locations.add(new DefConLocation(node.getCenter()));
162
163 if (locations.size() >= count)
164 return;
165 }
166 }
167 }
168 }
169 }