]> Dogcows Code - chaz/carfire/blob - CarFire/CarFire/CarFire/AI.cs
git-svn-id: https://bd85.net/svn/cs3505_group@163 92bb83a3-7c8f-8a45-bc97-515c4e399668
[chaz/carfire] / CarFire / CarFire / CarFire / AI.cs
1 //#define DisplayRegions
2 #define DisplayFinalRegions
3
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Text;
8 using Microsoft.Xna.Framework;
9
10 namespace CarFire
11 {
12 /// <summary>
13 /// AI infomation to be used by monsters. The map is split into deferent regions,
14 /// each region is then linked to other regions that it can see.
15 /// </summary>
16 public class AI
17 {
18 Game game;
19 int[,] regions;
20 List<Region> regionList;
21 int regionCnt;
22
23 public AI(Game _game)
24 {
25 game = _game;
26 regions = new int[game.State.Map.Width, game.State.Map.Height];
27 regionList = new List<Region>();
28 regionCnt = 0;
29
30 //set all square to -1 to show they have not been assigned to a region yet.
31 for (int y = 0; y < regions.GetLength(1); y++)
32 {
33 for (int x = 0; x < regions.GetLength(0); x++)
34 {
35 regions[x, y] = -1;
36 }
37 }
38 regionList.Add(new Region(0)); //region 0 will represent all walls and things like it.
39
40 #if DisplayRegions
41 printRegions();
42 #endif
43
44 setUpRegions();
45 foreach (Region r in regionList)
46 r.CalcCenter();
47
48
49 #if (DisplayRegions || DisplayFinalRegions)
50 printRegions();
51 #endif
52 linkRegions();
53 }
54
55 /// <summary>
56 /// check to see if a spot on the map is visible from another spot
57 /// </summary>
58 /// <param name="curX">Current X position</param>
59 /// <param name="curY">Current Y position</param>
60 /// <param name="testX">X location to test</param>
61 /// <param name="testY">Y location to test</param>
62 public bool spaceVisible(int curX, int curY, int testX, int testY)
63 {
64 return regionList[regions[curX, curY]].VisibleRegions.Contains(regions[testX, testY]);
65 }
66 public bool spaceVisible(Point Monster, Point Player )
67 {
68 return regionList[regions[Monster.X, Monster.Y]].VisibleRegions.Contains(regions[Player.X, Player.Y]);
69 }
70 //find regions in map. these regions will be large groups of connected grid squares.
71 public int setUpRegions()
72 {
73
74 //find open space that has not been assigned yet
75 for (int y = 0; y < regions.GetLength(1); y++)
76 {
77 for (int x = 0; x < regions.GetLength(0); x++)
78 {
79 if (regions[x, y] == -1 && spaceOpen(x, y))
80 {
81 regionCnt++;
82 regionList.Add(new Region(regionCnt));
83 createRegion(x, y);
84 }
85 else if (regions[x, y] == -1) //grid square is a wall
86 {
87 regions[x, y] = 0;
88 }
89 else //grid already assigned to region, do nothing
90 {
91 }
92 }
93 }
94
95 return regionList.Count;
96 }
97
98 #region Private Methods
99 private void createRegion(int x, int y)
100 {
101 regionList[regionCnt].Left = x;
102 regionList[regionCnt].Top = y;
103
104 for (int rY = 0; rY < 5 && y + rY < regions.GetLength(1); rY++) // creates a region as large as possible up to 5x5
105 {
106 for (int rX = 0; rX < 5 && x + rX < regions.GetLength(0); rX++)
107 {
108 if (regions[x + rX, y + rY] == -1 && spaceOpen(x + rX, y + rY))
109 {
110 regions[x + rX, y + rY] = regionCnt;
111 }
112 else if (regions[x + rX, y + rY] == -1) //grid square is a wall
113 {
114 regions[x + rX, y + rY] = 0;
115 regionList[regionCnt].Right = x + rX;
116 regionList[regionCnt].Bottom = y + rY;
117 #if DisplayRegions
118 printRegions();
119 #endif
120 if (!spaceOpen(x + rX + 1, y + rY)) // hit horizontal wall end region
121 if(x + rX >= regions.GetLength(0)-1)
122 break;
123 else
124 return;
125 else
126 break;
127
128 //todo: figure out how to get region to stop being created when
129 }
130 else //grid already assigned to region, do nothing
131 {
132 }
133 regionList[regionCnt].Right = x + rX;
134 }
135
136 regionList[regionCnt].Bottom = y + rY;
137 }
138 #if DisplayRegions
139 printRegions();
140 #endif
141 return;
142 }
143 private bool spaceOpen(int x, int y)
144 {
145 if (x >= regions.GetLength(0)) return false;
146 if (y >= regions.GetLength(1)) return false;
147 return !game.State.Map.IsWall(x, y);
148 }
149 //TODO: scans out from each corner, some areas are still missed
150 private void linkRegions()
151 {
152 foreach (Region r in regionList)
153 {
154 if (r.Label == 0)
155 continue;
156 //scan from center
157
158 //scan from corners
159 //top Left
160 int x = r.Left;
161 int y = r.Top;
162 //scan up
163 for (int t = 1; spaceOpen(x, y - t); t++)
164 {
165 if ( regions[x, y] != regions[x, y - t] )
166 {
167 regionList[regions[x, y]].AddVisible(regions[x, y - t]);
168 }
169 }
170 //scan left
171 for (int t = 1; spaceOpen(x - t, y); t++)
172 {
173 if ( regions[x, y] != regions[x - t, y] )
174 {
175 regionList[regions[x, y]].AddVisible(regions[x - t, y]);
176 }
177 }
178 //scan diag
179 for (int t = 1; spaceOpen(x - t, y - t); t++)
180 {
181 if (regions[x, y] != regions[x - t, y - t])
182 {
183 regionList[regions[x, y]].AddVisible(regions[x - t, y - t]);
184 }
185 }
186
187 //top Right
188 x = r.Right;
189 y = r.Top;
190 //scan up
191 for (int t = 1; spaceOpen(x, y - t); t++)
192 {
193 if (regions[x, y] != regions[x, y - t])
194 {
195 regionList[regions[x, y]].AddVisible(regions[x, y - t]);
196 }
197 }
198 //scan Right
199 for (int t = 1; spaceOpen(x + t, y); t++)
200 {
201 if (regions[x, y] != regions[x + t, y])
202 {
203 regionList[regions[x, y]].AddVisible(regions[x + t, y]);
204 }
205 }
206 //scan diag
207 for (int t = 1; spaceOpen(x + t, y - t); t++)
208 {
209 if (regions[x, y] != regions[x + t, y - t])
210 {
211 regionList[regions[x, y]].AddVisible(regions[x + t, y - t]);
212 }
213 }
214
215 //bottom Right
216 x = r.Right;
217 y = r.Bottom;
218 //scan down
219 for (int t = 1; spaceOpen(x, y + t); t++)
220 {
221 if (regions[x, y] != regions[x, y + t])
222 {
223 regionList[regions[x, y]].AddVisible(regions[x, y + t]);
224 }
225 }
226 //scan Right
227 for (int t = 1; spaceOpen(x + t, y); t++)
228 {
229 if (regions[x, y] != regions[x + t, y])
230 {
231 regionList[regions[x, y]].AddVisible(regions[x + t, y]);
232 }
233 }
234 //scan diag
235 for (int t = 1; spaceOpen(x + t, y + t); t++)
236 {
237 if (regions[x, y] != regions[x + t, y + t])
238 {
239 regionList[regions[x, y]].AddVisible(regions[x + t, y + t]);
240 }
241 }
242
243 //bottom left
244 x = r.Left;
245 y = r.Bottom;
246 //scan down
247 for (int t = 1; spaceOpen(x, y + t); t++)
248 {
249 if (regions[x, y] != regions[x, y + t])
250 {
251 regionList[regions[x, y]].AddVisible(regions[x, y + t]);
252 }
253 }
254 //scan Left
255 for (int t = 1; spaceOpen(x - t, y); t++)
256 {
257 if (regions[x, y] != regions[x - t, y])
258 {
259 regionList[regions[x, y]].AddVisible(regions[x - t, y]);
260 }
261 }
262 //scan diag
263 for (int t = 1; spaceOpen(x - t, y + t); t++)
264 {
265 if (regions[x, y] != regions[x - t, y + t])
266 {
267 regionList[regions[x, y]].AddVisible(regions[x - t, y + t]);
268 }
269 }
270 }
271 }
272 #endregion
273 //for testing print the region grid to the console
274 public void printRegions()
275 {
276 Console.WriteLine("--Printing Regions--");
277 for (int y = 0; y < regions.GetLength(1); y++)
278 {
279 for (int x = 0; x < regions.GetLength(0); x++)
280 {
281 Console.Write(regions[x, y]);
282 }
283 Console.WriteLine("");
284 }
285 }
286 }
287
288 /// <summary>
289 /// a chuck of the map that is at most 5x5 used to determine line of sight
290 /// </summary>
291 public class Region
292 {
293 List<int> visibleRegions; //other regions that are in this regions sight
294 int label;
295 int centerX;
296 int centerY;
297
298 //edges
299 int left, right, top, bottom;
300
301 public Region(int _label)
302 {
303 label = _label;
304 visibleRegions = new List<int>();
305 }
306
307 public void AddVisible(int region)
308 {
309 if(!visibleRegions.Contains(region))
310 visibleRegions.Add(region);
311 }
312
313 public void CalcCenter()
314 {
315 if (right != left) centerX = right + (right - left) / 2;
316 else centerX = right;
317 if (top != bottom) centerY = top + (bottom - top) / 2;
318 else centerY = top;
319 }
320
321 public int Left
322 {
323 get { return left; }
324 set { left = value; }
325 }
326 public int Right
327 {
328 get { return right; }
329 set { right = value; }
330 }
331 public int Top
332 {
333 get { return top; }
334 set { top = value; }
335 }
336 public int Bottom
337 {
338 get { return bottom; }
339 set { bottom = value; }
340 }
341
342 public Point Center { get { return new Point(centerX, centerY); } }
343 public int Label { get { return label; } }
344
345 public List<int> VisibleRegions { get { return visibleRegions; } }
346
347
348 }
349 }
This page took 0.049821 seconds and 4 git commands to generate.