1 import heapq
2 import math
3 import os
4 import re
5 import sys
6 import random
7
8 from collections import defaultdict
9
10 from cocos.batch import BatchableNode
11 from cocos import euclid, collision_model
12 from cocos.draw import Line
13 from cocos.layer import scrolling
14 from cocos.actions.interval_actions import Delay
15 from cocos.actions.instant_actions import CallFunc
16 from cocos.sprite import Sprite
17 import constants
18 from constants import TROOP_SLOT_SCALE, CELL_SIZE, NUM_OF_SLOTS, AS_OPACITY, \
19 SLOT_Z, BUILD_OFFSET_X, BUILD_OFFSET_Y, AS_EDGE_WIDTH, AS_COLORS, AS_SCALE, \
20 VERTEX_Z, AS_CIRCLE_Z, EDGE_COLOR, AS_EDGE_COLOR, EDGE_Z, MINIMAPCIRCLE_OPACITY, \
21 HALF_VISIBLE, PLAYER_COLORS
22 from heapItem import HeapItem
23 import objects
24 from utils import aabb_to_aa_rect, set_slots, get_action_menu_slots
25 from models import *
26
29 super(EmptyTroopSlot, self).__init__(os.path.join("images",
30 "maps", "empty_slot.png"))
31 self.position = euclid.Vector2(x, y)
32 self.scale = TROOP_SLOT_SCALE
33 self.opacity = opacity
34 self.troop = None
35
36
39 super(EmptyBuildingSlot, self).__init__(
40 os.path.join("images", "maps", "empty_building_slot.png"))
41 self.position = euclid.Vector2(x, y)
42 self.opacity = opacity
43
44
46
47 - def __init__(self, col, row, vid, asID, visibilityState=0, pid=0,image=None):
48 if not image:
49 super(Vertex, self).__init__(os.path.join("images", "maps",
50 "vertex.png"))
51 else:
52 super(Vertex, self).__init__(image)
53
54 self.position = euclid.Vector2(col * CELL_SIZE, row * CELL_SIZE)
55 self.cshape = aabb_to_aa_rect(self.get_AABB())
56 self.cshape.center = self.position
57 self.visibilityState = visibilityState
58
59 self.pid = pid
60
61 self.numOfSlots = NUM_OF_SLOTS
62
63 self.slotPositions = []
64
65 self.edges = []
66
67
68
69 self.building = None
70
71 self.vid = vid
72
73 self.asID = asID
74
75 self.asCircle = None
76
77 self.adjacentVertices = []
78
79 self.actionMenuSlots = get_action_menu_slots(4, self.position[0], self.position[1])
80 self.borderVertices = defaultdict(list)
81
82
83 self.emptySlots = []
84 self.emptyTroopSlots = {}
85
86 self.transTroopSlots = {}
87
88
89 self.troopSlots = {}
90
91 self.buildingSlot = None
92
93 self.opacity = visibilityState * 255
94
95
96 self.heapItem = None
97
99
100 if action == "attack":
101
102
103 return False,False
104 bool2 = (self.building and type(self.building) == Firewall and type(troop) != EncryptedTroop and self.building.pid != troop.pid)
105 is_firewall = (type(self.building) == Firewall and self.building.pid != troop.pid)
106 return bool2, is_firewall
107
109 if not self.emptyTroopSlots:
110 return False
111 i, slot = self.emptyTroopSlots.popitem()
112 slot.troop = troop
113 troop.slotIndex = i
114 self.troopSlots[i] = slot
115 troop.update_opacity(255 * math.floor(troop.curVertex.visibilityState))
116 if troop.pid == self.pid:
117 self._update_visibility()
118 self.set_neighbors_visibility()
119 return slot
120
122 if self.building:
123 return False
124 building.slotIndex = 0
125 self.building = building
126 building.opacity = 255 * math.floor(building.curVertex.visibilityState)
127 self.buildingSlot.color = PLAYER_COLORS[self.building.pid]
128 if self.building.pid == self.pid:
129 self._update_visibility()
130 self.set_neighbors_visibility()
131 return True
132
134 if not self.building:
135 return False
136 self.buildingSlot.color = (255,255,255)
137 if self.building.pid == self.pid:
138 self._update_visibility()
139 self.set_neighbors_visibility()
140
141
142 if type(self.building) == Database:
143 self.numOfSlots = 4
144 self.actionMenuSlots = get_action_menu_slots(self.numOfSlots, self.position[0], self.position[1])
145 for troopSlot in self.troopSlots.keys()[4:]:
146 troop = self.troopSlots[troopSlot].troop
147 self.remove_troop(troop)
148 self.building = None
149 return True
150
151
152
153
155 if self.emptyTroopSlots:
156 i, slot = self.emptyTroopSlots.popitem()
157 self.transTroopSlots[troop] = (i, slot)
158 return slot
159
160
162 index, slot = self.transTroopSlots.pop(troop)
163 slot.troop = troop
164 troop.slotIndex = index
165 self.troopSlots[index] = slot
166 troop.update_opacity(255 * math.floor(troop.curVertex.visibilityState))
167 if troop.pid == self.pid:
168 self._update_visibility()
169 self.set_neighbors_visibility()
170
171
173 if troop.slotIndex in self.troopSlots.keys():
174 slot = self.troopSlots.pop(troop.slotIndex)
175 elif troop not in self.transTroopSlots.keys():
176
177 return
178 else:
179 slot = self.transTroopSlots.pop(troop.slotIndex)
180 slot.troop = None
181 self.emptyTroopSlots[troop.slotIndex] = slot
182 if troop.pid == self.pid:
183 self._update_visibility()
184 self.set_neighbors_visibility()
185
186
188 visible=0
189 c = objects.Objects.get_controller()
190 if self.asID in c.visibleASes:
191 visible = HALF_VISIBLE
192 for v in self.adjacentVertices + [self]:
193 if v.asID == self.asID:
194 for slot in v.troopSlots.values():
195 if slot.troop.pid == self.pid:
196 visible = 1
197 break
198 if v.building and v.building.pid == self.pid:
199 visible = 1
200 self.set_visibility(visible)
201
203 for neighbor in self.adjacentVertices:
204 if neighbor.asID == self.asID:
205 neighbor._update_visibility()
206
208 if self.visibilityState == visibilityState:
209 return
210 self.visibilityState = visibilityState
211
212 for slot in self.troopSlots.values():
213 slot.opacity = math.floor(visibilityState) * 255
214 slot.troop.update_opacity(math.floor(visibilityState) * 255)
215
216 for slot in self.transTroopSlots.values():
217 slot[1].opacity = math.floor(visibilityState) * 255
218
219 for slot in self.emptyTroopSlots.values():
220 slot.opacity = math.floor(visibilityState) * 255
221
222
223 self.opacity = math.ceil(visibilityState) * 255
224 self.buildingSlot.opacity = math.floor(visibilityState) * 255
225 if self.building:
226 self.building.opacity = math.floor(visibilityState) * 255
227 for edge in self.edges:
228 edge.visible = bool(math.ceil(visibilityState))
229 self.asCircle.opacity = math.ceil(visibilityState) * 255 * AS_OPACITY
230
232 if isHighlighted:
233 for edge in self.edges:
234 edge.old_stroke_width = edge.stroke_width
235 edge.stroke_width = edge.stroke_width + 3
236
237
238
239
240 else:
241 for edge in self.edges:
242 edge.stroke_width = edge.old_stroke_width
243
244
245
246
247
248
250
251
252
253 curTroops = []
254 curBuilding = None
255
256
257 for slot in self.emptyTroopSlots.values():
258 gameMap.batch_remove(slot)
259
260 for slot in self.troopSlots.values():
261 curTroops.append(slot.troop)
262 gameMap.batch_remove(slot)
263 self.remove_troop(slot.troop)
264
265 for slot in self.transTroopSlots.values():
266 curTroops.append(slot.troop)
267 gameMap.batch_remove(slot)
268 self.remove_troop(slot.troop)
269
270 if self.buildingSlot:
271 gameMap.batch_remove(self.buildingSlot)
272
273 self.slotPositions = set_slots(self.numOfSlots, self.position[0], self.position[1])
274
275
276 for i in range(self.numOfSlots):
277 emptySlot = EmptyTroopSlot(
278 self.slotPositions[i][0], self.slotPositions[i][1], self.opacity)
279 gameMap.batch_add(emptySlot, z=SLOT_Z)
280 self.emptyTroopSlots[i] = emptySlot
281
282 self.actionMenuSlots = get_action_menu_slots(self.numOfSlots, self.position[0], self.position[1])
283
284
285 self.buildingSlot = EmptyBuildingSlot(
286 self.position[0] + BUILD_OFFSET_X, self.position[1] + BUILD_OFFSET_Y, self.opacity)
287 gameMap.batch_add(self.buildingSlot, z=SLOT_Z)
288 self._update_visibility()
289
290 for t in curTroops:
291 self.add_troop(t)
292
293
295 - def __init__(self, col, row, vid, adjacentVertices, visibilityState=0, pid=0):
296 super(Core, self).__init__(col, row, vid, adjacentVertices, visibilityState=0, pid=0,image=os.path.join("images", "maps", "core.png"))
297 self.color = (255,255,255)
298
300 if self.building:
301 return False
302 building.slotIndex = 0
303 self.building = building
304 if building.pid == self.pid:
305 self._update_visibility()
306 return True
307
309 if not self.building:
310 return False
311 self.building = None
312 if building.pid == self.pid:
313 self._update_visibility()
314 return True
315
317 if visibilityState == self.visibilityState:
318 return
319 self.visibilityState = visibilityState
320 self.opacity = 255 * math.ceil(visibilityState)
321 if self.building:
322 self.building.opacity = 255 * math.floor(visibilityState)
323
326
332
335
336
338 - def __init__(self, sourcePos, destPos, sourceV, destV, color, strokeWidth=3, visible=False):
339
340
341 start = (sourcePos[0] * CELL_SIZE, sourcePos[1] * CELL_SIZE)
342 end = (destPos[0] * CELL_SIZE, destPos[1] * CELL_SIZE)
343 super(Edge, self).__init__(start, end, color, strokeWidth)
344 self.visible = visible
345 self.color = color
346 self.stroke_width = strokeWidth
347 self.v1 = sourceV
348 self.v2 = destV
349
350
352 - def __init__(self, sourcePoint, destPoint, sourceV, destV, color, strokeWidth=AS_EDGE_WIDTH, visible=False, speed=0.1):
353
354 super(ASEdge, self).__init__(
355 sourcePoint, destPoint, sourceV, destV, color, strokeWidth)
356 self.visible = visible
357 self.color = color
358 self.speed = speed
359 self.stroke_width = strokeWidth
360 self.v1 = sourceV
361 self.v2 = destV
362
363
365 - def __init__(self, asID, vids, position=None, opacity=0):
366 self.circles = {}
367 self.asID = int(asID)
368 self.vids = vids
369 self.vertices = {}
370 self.cores = {}
371 self.usedCores = {}
372 self.position = position
373 self.opacity = opacity * 255
374 self.color = AS_COLORS[self.asID]
375
376
379 super(ASCircle, self).__init__(os.path.join("images",
380 "maps", "as_circle.png"))
381 self.color = color
382 self.scale = scale
383 self.opacity = opacity
384 self.position = euclid.Vector2(position[0], position[1])
385
386
387 -class Map(scrolling.ScrollableLayer):
388
389 - def __init__(self, mapFileName, cm=None, numPlayers = None, AIPlayers = None, seed = None):
390 super(Map, self).__init__()
391 self.cm = cm
392
393 self.batchableNode = BatchableNode()
394 self.batchableNode.position = 0,0
395 self.add(self.batchableNode,z=VERTEX_Z)
396
397
398 self.vertexPositions = {}
399 self.edgePositions = defaultdict(
400 list)
401
402 self.AS = {}
403 self.cores = {}
404 self.vertices = {}
405 self.edges = []
406
407 self.startingUnits = defaultdict(lambda: defaultdict(list))
408 self.startingResearch = defaultdict(list)
409 self.availResearch = []
410
411 self.w = - 1
412
413 self.h = - 1
414
415
416 self.players = []
417 self.AIPlayers = []
418 self.pid = 0
419 if mapFileName == "random":
420
421
422 random.seed(seed)
423
424 numRows = int(random.randint(6 * numPlayers, 14 * numPlayers))
425 numCols = int(random.randint(6 * numPlayers, 14 * numPlayers))
426
427
428 numASes = int(math.ceil((numCols * numRows) / 140.0))
429
430
431 minVertsPerAS = 2
432 maxVertsPerAS = 4
433
434 playerStartUnits = {0:[],1:[]}
435 playerResearch = {0:[],1:[]}
436
437 maxCoresPerAS = 2
438
439 mapFileName = self.generate_random_map(numPlayers, numCols, numRows, playerStartUnits, playerResearch, minVertsPerAS, maxVertsPerAS, numASes, maxCoresPerAS, AIPlayers, seed)
440
441
442 self.parse_map_file(mapFileName)
443
444 self.minimap = None
445
447 self.batchableNode.add(cocosNode,z=z)
448
450 self.batchableNode.remove(cocosNode)
451
453
454 with open(mapFileName, 'r') as f:
455 row = 0
456 isCellInfo = False
457 for line in f:
458 line = line.split()
459 if len(line) == 0 or line[0] == "#":
460 continue
461 elif line[0] == "MAP":
462 isCellInfo = True
463 self.w = int(line[1]) - 1
464 self.h = int(line[2]) - 1
465 elif line[0] == "ENDMAP":
466 isCellInfo = False
467 elif line[0] == "EDGES:" or line[0] == "CORE_EDGES:":
468 edgeList = []
469 for edge in line[1:]:
470 formattedEdge = re.findall("[0-9]+|[a-z]+", edge)
471 edgeList.append(formattedEdge)
472 for edge in edgeList:
473 self.edgePositions[edge[0]
474 ].append(edge[1])
475 self.edgePositions[edge[1]
476 ].append(edge[0])
477 elif line[0] == "AS":
478 vertsInAS = []
479 for i in range(2, len(line)):
480 r = re.split('\-', line[i])
481 if r[0].isdigit():
482 vertsInAS += [str(v) for v in range(int(r[0]), int(r[1]) + 1)]
483 else:
484 vertsInAS += [r[0]]
485 self.AS[int(line[1])] = AS(int(line[1]), vertsInAS)
486 elif "PLAYER" == line[0]:
487
488
489 pid = int(line[1])
490 self.players.append(pid)
491 for unit in line[2:]:
492 unit = unit.split(",")
493 unitType = unit[0]
494 unitVert = unit[1]
495 self.startingUnits[pid][unitVert].append(unitType)
496 elif line[0] == "AI":
497 self.AIPlayers = line[1:]
498 self.AIPlayers = [int(i) for i in self.AIPlayers]
499 for p in self.AIPlayers:
500 self.players.remove(p)
501 elif line[0] == "STARTRESEARCH":
502 pid = int(line[1])
503 for research in line[2:]:
504 self.startingResearch[pid].append(research)
505 elif line[0] == "AVAILRESEARCH":
506 for research in line[1:]:
507 self.availResearch.append(research)
508 elif isCellInfo == True:
509 col = 0
510 for cell in line:
511 if cell.isalpha() or cell.isdigit():
512 r = self.h - row
513 self.vertexPositions[cell] = (col, r)
514 col += 1
515 row += 1
516 f.close()
517
519 for asID in self.AS.keys():
520 curAS = self.AS[asID]
521
522
523 for vid in curAS.vids:
524 position = self.vertexPositions[str(vid)]
525 if vid.isalpha():
526 v = Core(position[0], position[1], vid, asID, pid=self.pid)
527 self.cores[vid] = v
528 self.vertices[vid] = v
529 curAS.cores[vid] = v
530 else:
531 v = Vertex(position[0], position[1], vid, asID, pid=self.pid)
532 v.asCircle = ASCircle(v.position, curAS.color)
533 v.color = curAS.color
534 curAS.circles[vid] = v.asCircle
535 v.draw_empty_slot_sprites(self)
536 curAS.vertices[vid] = v
537 self.vertices[vid] = v
538
539 self.batch_add(v, z=VERTEX_Z)
540 for v1, v2s in self.edgePositions.items():
541 for v2 in v2s:
542 position1 = self.vertexPositions[v1]
543 position2 = self.vertexPositions[v2]
544 vert1 = self.vertices[v1]
545 vert2 = self.vertices[v2]
546 if v1.isalpha() or (v2.isdigit() and (int(v1) > int(v2))):
547
548 if vert1.asID != vert2.asID:
549 vert1.borderVertices[vert2.asID].append(vert2)
550 vert2.borderVertices[vert1.asID].append(vert1)
551 edge = ASEdge(
552 position1, position2, vert1, vert2, AS_EDGE_COLOR)
553 else:
554 edge = Edge(
555 position1, position2, vert1, vert2, EDGE_COLOR)
556 vert1.edges.append(edge)
557 vert2.edges.append(edge)
558 if not v1.isalpha():
559 vert1.adjacentVertices.append(vert2)
560 vert2.adjacentVertices.append(vert1)
561 self.edges.append(edge)
562
563
564 for v in self.edges:
565 self.add(v, z=EDGE_Z)
566 pass
567
568 - def generate_random_map(self, numPlayers, numCols, numRows, playerStartUnits, playerResearch, minVertsPerAS, maxVertsPerAS, numASes, maxCoresPerAS, AIPlayers, seed):
569
570 ASvertices, AScores = self.add_verts_and_cores(numRows, numCols, minVertsPerAS, maxVertsPerAS, numASes, maxCoresPerAS)
571
572
573
574 mapLines, numCols, numRows, ASvertices, AScores = self.create_map_lines(numCols, numRows, ASvertices, AScores, maxVertsPerAS)
575
576
577 edges, coreEdges = self.make_edges(numCols, numRows, ASvertices, AScores)
578
579
580 playerStartUnits = [["Server","CPU"],["Server","CPU"]]
581 fullMapName = self.write_map_info_to_file(mapLines, ASvertices, AScores, edges, coreEdges, numPlayers, playerStartUnits, playerResearch, AIPlayers)
582
583 return fullMapName
584
585 - def add_verts_and_cores(self, numRows, numCols, minVertsPerAS, maxVertsPerAS, numASes, maxCoresPerAS):
586
587
588 endVert = random.randint(minVertsPerAS, maxVertsPerAS)
589 ASvertices = [range(0,endVert + 1)]
590
591 for i in range(1, numASes):
592
593 ASvertices.append(range(endVert + 1, 1 + random.randint(endVert + 2, endVert + 2 + random.randint(minVertsPerAS, maxVertsPerAS))))
594 endVert = ASvertices[i][-1]
595
596 endCore = 'b'
597
598 valList = range(ord('a'), ord(endCore) + 1)
599 for j in range(len(valList)):
600 valList[j] = chr(valList[j])
601
602
603 AScores = [valList]
604 nextDigit = ''
605 for i in range(1, numASes):
606
607
608
609 lowerVal = ord(endCore[-1]) + 1
610 upperVal = ord(endCore[-1]) + 1 + random.randint(1,maxCoresPerAS)
611 if upperVal > 122 and nextDigit == '':
612
613 nextDigit = 'a'
614 upperVal = (upperVal % 122) + 97
615 elif upperVal > 122 and nextDigit != '':
616
617 nextDigit = chr(ord(nextDigit) + 1)
618 upperVal = (upperVal % 122) + 97
619 valList = range(lowerVal, upperVal)
620
621
622 for j in range(len(valList)):
623 valList[j] = nextDigit + chr(valList[j])
624 AScores.append(valList)
625 endCore = AScores[i][-1]
626
627 return ASvertices, AScores
628
629 - def create_map_lines(self, numCols, numRows, ASvertices, AScores, maxVertices):
630
631
632 mapLines = [["-" for i in range(int(numCols))] for j in range(int(numRows))]
633
634
635 numASes = len(ASvertices)
636
637 dimensionFacilitator = maxVertices + 2
638 boundingBoxWidth = random.randint(3,dimensionFacilitator)
639 dimensionFacilitator -= boundingBoxWidth
640 boundingBoxHeight = random.randint(3,min(max(3,dimensionFacilitator),maxVertices))
641
642
643 topLeft = (0,0)
644 botRight = (topLeft[0] + boundingBoxWidth, topLeft[1] + boundingBoxHeight)
645
646
647 boundingBoxes = [(topLeft,botRight)]
648
649
650 boxesPlaced = 0
651 while boxesPlaced < (numASes + numASes):
652
653 if botRight[0] + boundingBoxWidth > numCols:
654
655 topLeft = (1,botRight[1] + 3)
656 else:
657
658 topLeft = (botRight[0] + 3, topLeft[1])
659 if (botRight[1] + boundingBoxHeight) > numRows:
660
661 numCols += 1
662 numRows += 1
663 for i in range(len(mapLines)):
664 row = mapLines[i]
665 row.append("-")
666 mapLines[i] = row
667 mapLines.append(["-" for row in range(int(numCols))])
668 else:
669
670 botRight = (topLeft[0] + boundingBoxWidth, topLeft[1] + boundingBoxHeight)
671 boundingBoxes.append((topLeft,botRight))
672 boxesPlaced += 1
673
674
675 for i in range(numASes):
676
677 nextASverts = ASvertices[i]
678 nextAScores = AScores[i]
679
680
681 try:
682 topLeft, botRight = random.choice(boundingBoxes)
683 boundingBoxes.remove((topLeft, botRight))
684 except:
685
686 break
687
688
689 vertIndex = 0
690 while vertIndex < len(nextASverts):
691 vert = nextASverts[vertIndex]
692 vertRow = random.randint(topLeft[0], max(min(len(mapLines) - 1, botRight[0]),topLeft[0] + 1))
693 vertCol = random.randint(topLeft[1], max(min(len(mapLines[-1]) - 1, botRight[1]),topLeft[1] + 1))
694 try:
695 while mapLines[vertRow][vertCol] != "-":
696
697 vertRow = random.randint(topLeft[0], min(len(mapLines) - 1, botRight[0]))
698 vertCol = random.randint(topLeft[1], min(len(mapLines[-1]) - 1, botRight[1]))
699
700 mapLines[vertRow][vertCol] = vert
701 vertIndex += 1
702 except:
703 ASvertices[i].remove(vert)
704
705
706 for j in range(len(ASvertices[i])):
707 if ASvertices[i][j] > vert:
708 ASvertices[i][j] -= 1
709
710
711 try:
712
713 for core in nextAScores:
714 coreRow = random.randint(topLeft[0], max(min(len(mapLines) - 1, botRight[0]),topLeft[0] + 1))
715 coreCol = random.randint(topLeft[1], max(min(len(mapLines[-1]) - 1, botRight[1]),topLeft[1] + 1))
716 while mapLines[coreRow][coreCol] != "-":
717
718 coreRow = random.randint(topLeft[0], min(len(mapLines) - 1, botRight[0]))
719 coreCol = random.randint(topLeft[1], min(len(mapLines[-1]) - 1, botRight[1]))
720
721 mapLines[coreRow][coreCol] = core
722 except:
723 AScores[i].remove(core)
724
725 return mapLines, numCols, numRows, ASvertices, AScores
726
727 - def make_edges(self, numCols, numRows, ASvertices, AScores):
728
729
730
731 edgeList = []
732 coreEdgeList = []
733
734
735 for AS in ASvertices:
736
737 vertList = sorted(list(AS))
738
739
740 pruferSeq = self.generate_prufer_seq(sorted(list(AS)))
741
742 edgeList += self.generate_mst(pruferSeq, vertList)
743
744
745 asBorderRouters = []
746 for AS in ASvertices:
747 if len(AS) > 0:
748 asBorderRouters.append(random.choice(AS))
749
750 ASpruferSeq = self.generate_prufer_seq(list(asBorderRouters))
751
752 edgeList += self.generate_mst(ASpruferSeq, asBorderRouters)
753
754
755 for i in range(len(AScores)):
756 for j in range(len(AScores[i])):
757 if len(ASvertices[i]) > 0:
758 core = AScores[i][j]
759 randomVertInSameAS = random.choice(ASvertices[i])
760 coreEdgeList.append([randomVertInSameAS, core])
761
762 return edgeList, coreEdgeList
763
765
766
767
768 if len(vertList) == 0:
769 return []
770 exhausted = [vertList.pop(0)]
771 pruferSeq = []
772
773 while len(vertList) > 0:
774 try:
775 randVert = random.choice(exhausted)
776 pruferSeq.append(randVert)
777 new = vertList.pop(0)
778 exhausted.append(new)
779 except:
780
781 break
782
783 return pruferSeq
784
786
787 if len(pruferSeq) == 0:
788 return []
789 vertList.remove(pruferSeq[0])
790 edgeList = []
791 while True:
792 if len(pruferSeq) == 1:
793 edgeList.append([vertList[0], pruferSeq[0]])
794 break
795 elif len(vertList) == 2:
796
797 edgeList.append([vertList[0], pruferSeq[0]])
798 edgeList.append([vertList[1], pruferSeq[1]])
799 break
800 else:
801 nextVert = None
802 for vert in vertList:
803 if vert != pruferSeq[0]:
804 nextVert = vert
805 vertList.remove(vert)
806 break
807 otherVert = pruferSeq.pop(0)
808 edgeList.append([nextVert, otherVert])
809 return edgeList
810
811 - def write_map_info_to_file(self, mapLines, ASvertices, AScores, edges, coreEdges, numPlayers, playerStartUnits, playerResearch, AIPlayers):
812
813 mapName = "random" + str(random.randint(1, 1000)) + ".map"
814 numRows = len(mapLines)
815 numCols = len(mapLines[0])
816
817 fullMapName = os.path.join("maps", "random", mapName)
818 newMapFile = file(fullMapName, "w")
819
820
821 edgeString = " "
822 for edge in edges:
823 temp = str(edge).replace(" ", "")
824 edgeString += temp + " "
825
826
827 coreEdgeString = " "
828 for coreEdge in coreEdges:
829 temp = str(coreEdge).replace(" ", "").replace("\'","")
830 coreEdgeString += temp + " "
831 newMapFile.write("EDGES:" + edgeString + "\n")
832 newMapFile.write("CORE_EDGES:" + coreEdgeString + "\n")
833
834 for index in range(len(ASvertices)):
835 AS = ASvertices[index]
836
837 AScoreList = ""
838 for core in AScores[index]:
839 AScoreList += core + " "
840
841 if len(AS) > 0:
842 newMapFile.write("AS " + str(index) + " " + str(AS[0]) + "-" + str(AS[-1]) + " " + AScoreList + "\n")
843
844 newMapFile.write("\n")
845
846 newMapFile.write("MAP " + str(numCols) + " " + str(numRows) + "\n")
847
848
849 for line in mapLines:
850 newMapFile.write(self.list_to_string(line) + "\n")
851 newMapFile.write("ENDMAP\n")
852 newMapFile.write("\n")
853
854
855 for i in range(0,numPlayers):
856 nextUnitString = ""
857 for j in range(len(playerStartUnits[i])):
858 if len(ASvertices[i]) > 0:
859
860 if playerStartUnits[i][j] != "CPU":
861 nextUnitString += playerStartUnits[i][j] + "," + str(random.choice(ASvertices[i])) + " "
862 elif len(AScores) > 0:
863 nextUnitString += playerStartUnits[i][j] + "," + str(random.choice(AScores[i])) + " "
864 if len(ASvertices[i]) > 0:
865 newMapFile.write("PLAYER " + str(i) + " " + str(nextUnitString) + "\n")
866 if AIPlayers != None:
867 newMapFile.write("\n")
868 for AI in AIPlayers:
869 AIstring = str(AI)
870 newMapFile.write("AI " + AIstring + "\n")
871 newMapFile.write("\n")
872 newMapFile.close()
873 return fullMapName
874
876
877 s = ""
878 for item in l:
879 s += str(item) + " "
880 return s
881
882 - def get_path(self, source, dest, pid, troop, action=None):
883 '''
884 Djikstra's Algorithm from Wikipedia:
885 http://en.wikipedia.org/wiki/Dijkstra's_algorithm
886 '''
887
888 vertices = []
889
890 for vertex in self.vertices.values():
891 if not vertex.is_blocking_troop(troop, action)[0]:
892 h = HeapItem(vertex, sys.maxint)
893 vertex.heapItem = h
894 vertices.append(h)
895 if vertex == source:
896 h.depth = 0
897
898 heapq.heapify(vertices)
899
900 while vertices:
901 u = heapq.heappop(vertices)
902 if u.vertex == dest and u.depth != sys.maxint:
903
904 path = []
905 while u:
906 path.append(u.vertex.vid)
907 u = u.parent
908 path.reverse()
909 return path
910
911 for vertex in u.vertex.adjacentVertices:
912 if not vertex.is_blocking_troop(troop, action)[0]:
913 v = vertex.heapItem
914
915 alt = u.depth + 1
916 if alt < v.depth:
917 v.depth = alt
918 v.parent = u
919 vertices.append(v)
920
921 heapq.heapify(vertices)
922
923 return None
924
925
927
928
929
930 vertices = sourceVertex.adjacentVertices
931
932 if (type(troop) != EncryptedTroop) and (type(destVertex.building) == Firewall or type(destVertex.building) == Database) and destVertex.building.pid != pid:
933 return False
934
935 head = HeapItem(sourceVertex, 0)
936
937 heapVertices = []
938 for vertex in vertices:
939
940 if vertex.visibilityState > 0 and (type(troop) == EncryptedTroop or type(vertex.building) != Firewall or vertex.building.pid == pid):
941 heapVertex = HeapItem(vertex, 1, head)
942 heapq.heappush(heapVertices, heapVertex)
943 else:
944 pass
945 numVerticesInMap = len(self.vertices)
946
947 deadVerts = []
948 while head.vertex != destVertex:
949 if len(deadVerts) > numVerticesInMap:
950
951
952 return False
953
954 head = heapq.heappop(heapVertices)
955 newMoves = head.vertex.adjacentVertices
956
957 for vertex in newMoves:
958 if vertex.visibilityState > 0 and (type(troop) == EncryptedTroop or type(vertex.building) != Firewall or vertex.building.pid == pid):
959
960
961 heapVertex = HeapItem(vertex, head.depth + 1, head)
962
963
964
965 if heapVertex.vertex.vid not in [heapVert.vertex.vid for heapVert in heapVertices] and heapVertex.vertex not in deadVerts:
966
967
968
969 heapq.heappush(heapVertices, heapVertex)
970 else:
971 deadVerts.append(vertex)
972
973 path = []
974 while head.getParent():
975 path.insert(0, head.vertex)
976 head = head.getParent()
977 path.insert(0, head.vertex)
978 return path
979
981 if vid.isalpha():
982 return self.cores[vid]
983 return self.vertices[vid]
984
985
987 - def __init__(self, ASes, numMapCols, numMapRows, edges, player):
988 super(MiniMap, self).__init__(os.path.join("images",
989 "maps", "minimap_bg.png"))
990 self.edges = edges
991 self.minimapBuildings = {}
992 self.minimapTroops = {}
993 self.opacity = 255
994 self.scale = 0.6
995 self.mapCellWidth = numMapCols * CELL_SIZE
996 self.mapCellHeight = numMapRows * CELL_SIZE
997 self.ASes = ASes
998 self.cshape = aabb_to_aa_rect(self.get_AABB())
999 self.player = player
1000 self.setup()
1001
1003 self.miniMapCircles = {}
1004 self.edgeList = []
1005 for asID in self.ASes:
1006 for vid in self.ASes[asID].circles.keys():
1007
1008
1009
1010 circ = self.ASes[asID].circles[vid]
1011 newX = self.get_rect().width * circ.position[0] / self.mapCellWidth - 124
1012 newY = self.get_rect().height * circ.position[1] / self.mapCellHeight - 142
1013
1014 newPosition = (newX, newY)
1015 color = circ.color
1016 self.miniMapCircles[vid] = MiniMapCircle(
1017 newPosition, circ.position, color, 1)
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1036 - def __init__(self, miniCircleSourcePos, miniCircleDestPos, sourceV, destV, color, strokeWidth=1):
1037
1038 start = miniCircleSourcePos
1039 end = miniCircleDestPos
1040 super(MiniMapEdge, self).__init__(start, end, color, strokeWidth)
1041 self.color = color
1042 self.stroke_width = strokeWidth
1043 self.v1 = sourceV
1044 self.v2 = destV
1045
1046
1048 - def __init__(self, position, asPosition, color, scale, building=False):
1049 super(MiniMapCircle, self).__init__(os.path.join("images",
1050 "maps", "minimap_circle.png"))
1051 self.color = color
1052 self.scale = scale
1053 self.position = euclid.Vector2(float(position[0]), float(position[1]))
1054 self.asPosition = asPosition
1055
1056 self.cshape = collision_model.CircleShape(
1057 euclid.Vector2(x=self.position[0], y=self.position[1]), 14)
1058 if building:
1059 self.building = Sprite(os.path.join(
1060 'images', 'maps', 'minimap_building.png'), position=euclid.Vector2(float(position[0]), float(position[1])))
1061
1062