AIMap.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from random import choice
  2. import heapq
  3. from mymath import D60, D105, D360
  4. import math
  5. FREE, OBSTACLE = range(2)
  6. class AIMap():
  7. def __init__(self, level):
  8. self.totalWidth = level.totalWidth
  9. self.totalHeight = level.totalHeight
  10. self.cellSize = level.cellSize
  11. obstacleMap = level.structure
  12. self.cellsX = self.totalWidth // self.cellSize
  13. self.cellsY = self.totalHeight // self.cellSize
  14. self.structure = [[ OBSTACLE if obstacleMap[x][y] else FREE for y in xrange(self.cellsY)] for x in xrange(self.cellsX)]
  15. def getNewExplore(self, position, tankAngle):
  16. cell = self.calculateCell(position)
  17. successors = self.getSuccessors(cell)
  18. good = []
  19. for (successor,wildcard) in successors :
  20. #successorCoords = self.calculateCoords(successor)
  21. diffAngle = math.fabs(tankAngle - self.getAngleToDest(cell,successor))
  22. if diffAngle > math.pi :
  23. diffAngle = D360-diffAngle
  24. value = len(self.getSuccessors(successor))
  25. if diffAngle <= D60 :
  26. good.append((successor,value+7))
  27. elif diffAngle <= D105 :
  28. good.append((successor,value+4))
  29. else :
  30. good.append((successor,value))
  31. max_value = 0
  32. result = []
  33. for (pos,value) in good :
  34. if value > max_value :
  35. result = [pos]
  36. max_value = value
  37. elif value == max_value :
  38. result.append(pos)
  39. return self.calculateCoords(choice(result))
  40. def getSuccessors(self, (xpos,ypos)):
  41. successors = []
  42. i = 0
  43. for y in range(ypos-1,ypos+2):
  44. for x in range(xpos-1,xpos+2):
  45. i = i + 1
  46. if x >= 0 and x < self.cellsX and y >= 0 and y < self.cellsY :
  47. if i == 5 :
  48. continue
  49. elif self.structure[x][y] == FREE :
  50. if (x == xpos or y == ypos) :
  51. successors.append(((x,y),1))
  52. elif i == 1 :
  53. if self.structure[x+1][y] == FREE and self.structure[x][y+1] == FREE : successors.append(((x,y),1.4))
  54. elif i == 3 :
  55. if self.structure[x-1][y] == FREE and self.structure[x][y+1] == FREE : successors.append(((x,y),1.4))
  56. elif i == 7 :
  57. if self.structure[x+1][y] == FREE and self.structure[x][y-1] == FREE : successors.append(((x,y),1.4))
  58. elif i == 9 :
  59. if self.structure[x-1][y] == FREE and self.structure[x][y-1] == FREE : successors.append(((x,y),1.4))
  60. return successors
  61. def calculateCell(self, (xp,yp)):
  62. return ( int(xp / self.cellSize) , int(yp / self.cellSize) )
  63. def calculateCoords(self,cell):
  64. return (self.cellSize * (cell[0]+0.5),self.cellSize * (cell[1]+0.5))
  65. def getAngleToDest(self,(xpos,ypos),(xdes,ydes)):
  66. return math.atan2(ypos-ydes, xdes-xpos) % D360
  67. #------PathFinding----#
  68. def calculatePath(self, start, destination):
  69. #self.controller.stop()
  70. class PriorityQueue:
  71. def __init__(self):
  72. self.heap = []
  73. def push(self, item, priority):
  74. pair = (priority,item)
  75. heapq.heappush(self.heap,pair)
  76. def pop(self):
  77. popped = heapq.heappop(self.heap)
  78. return popped[1]#item
  79. def isEmpty(self):
  80. return len(self.heap) == 0
  81. #A*
  82. start_cell = self.calculateCell(start)
  83. destination_cell = self.calculateCell(destination)
  84. explored = {}
  85. fringe = PriorityQueue();
  86. startNode = (start_cell, 0, 0) #(state,parent,cost to get to this state)
  87. fringe.push(startNode, startNode[2])
  88. while (True) :
  89. while (True) :
  90. currentNode = fringe.pop()
  91. if currentNode[0] not in explored : #same node on the fringe multiple times. we only want the lowest cost node expanded.
  92. break
  93. explored[currentNode[0]] = currentNode
  94. if currentNode[0] == destination_cell :
  95. break
  96. successors = self.getSuccessors(currentNode[0])
  97. for (successor,cost) in successors :
  98. totalcost = currentNode[2] + cost
  99. if successor not in explored : #nodes that are not expanded yet, but are already on the fringe will still be added.
  100. node = (successor, currentNode, totalcost)
  101. heuristic = ((successor[0] - destination[0]) ** 2 + (successor[1] - destination[1]) ** 2 ) ** 0.5
  102. fringe.push(node,(totalcost+heuristic))
  103. newpoints = []
  104. while ( currentNode[0] != start_cell) :
  105. newpoints.insert(0, self.calculateCoords(currentNode[0]))
  106. currentNode = currentNode[1]
  107. return newpoints