Guest User

Untitled

a guest
Jan 16th, 2013
422
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.88 KB | None | 0 0
  1. import ika
  2. import time
  3.  
  4. class Node:
  5.  
  6.   def __init__(self,x,y,parent=None,g=0,h=0):
  7.     self.x = x
  8.     self.y = y
  9.     self.parent = parent
  10.     self.g = g
  11.     self.h = h
  12.    
  13.   def cost(self):
  14.     return self.g + self.h
  15.    
  16.   def equal(self,node):
  17.     if self.x == node.x and self.y == node.y:
  18.       return True
  19.     else:
  20.       return False
  21.      
  22. class Emerald_Pathfinder:
  23.  
  24.   def __init__(self):
  25.     pass
  26.    
  27.   def setup(self,start,goal):
  28.     self.start = start
  29.     self.goal = goal
  30.     self.openlist = [None,start]    # Implemented as binary heap
  31.     self.closedlist = {}            # Implemented as hash
  32.     self.onopenlist = {}            # Hash, for searching the openlist
  33.     self.found = False
  34.     self.current = None
  35.     self.iterations = 0
  36.    
  37.   def lowest_cost(self):
  38.     pass
  39.    
  40.   def add_nodes(self,current):
  41.     nodes = []
  42.     x = current.x
  43.     y = current.y
  44.     self.add_node(x+1,y,current,10,nodes)
  45.     self.add_node(x-1,y,current,10,nodes)
  46.     self.add_node(x,y+1,current,10,nodes)
  47.     self.add_node(x,y-1,current,10,nodes)
  48.     # Dont cut across corners
  49.     up = map.is_obstacle((x,y-1),x,y-1)
  50.     down = map.is_obstacle((x,y+1),x,y+1)
  51.     left = map.is_obstacle((x-1,y),x-1,y)
  52.     right = map.is_obstacle((x+1,y),x+1,y)
  53.     if right == False and down == False:
  54.       self.add_node(x+1,y+1,current,14,nodes)
  55.     if left == False and up == False:
  56.       self.add_node(x-1,y-1,current,14,nodes)
  57.     if right == False and up == False:
  58.       self.add_node(x+1,y-1,current,14,nodes)
  59.     if left == False and down == False:
  60.       self.add_node(x-1,y+1,current,14,nodes)
  61.     return nodes
  62.    
  63.   def heuristic(self,x1,y1,x2,y2):
  64.     return (abs(x1-x2)+abs(y1-y2))*10
  65.    
  66.   def add_node(self,x,y,parent,cost,list):
  67.     # If not obstructed
  68.     if map.is_obstacle((x,y),x,y) == False:
  69.       g = parent.g + cost
  70.       h = self.heuristic(x,y,self.goal.x,self.goal.y)
  71.       node = Node(x,y,parent,g,h)
  72.       list.append(node)
  73.  
  74.   def ignore(self,node,current):
  75.     # If its on the closed list, or open list, ignore
  76.     try:
  77.       if self.closedlist[(node.x,node.y)] == True:
  78.         return True
  79.     except:
  80.       pass
  81.     # If the node is on the openlist, do the following
  82.     try:
  83.       # If its on the open list
  84.       if self.onopenlist[(node.x,node.y)] != None:
  85.         # Get the id number of the item on the real open list
  86.         index = self.openlist.index(self.onopenlist[(node.x,node.y)])
  87.         # If one of the coordinates equal, its not diagonal.
  88.         if node.x == current.x or node.y == current.y:
  89.           cost = 10
  90.         else:
  91.           cost = 14
  92.         # Check, is this items G cost is higher, than the current G + cost
  93.         if self.openlist[index].g > (current.g + cost):
  94.           # If so, then, make the list items parent, the current node.
  95.           self.openlist[index].g = current.g + cost
  96.           self.openlist[index].parent = current
  97.           # Now resort the binary heap, in the right order.
  98.           self.resort_binary_heap(index)
  99.         # And ignore the node
  100.         return True
  101.     except:
  102.       pass
  103.     return False
  104.  
  105.   def resort_binary_heap(self,index):
  106.     m = index
  107.     while m > 1:
  108.       if self.openlist[m/2].cost() > self.openlist[m].cost():
  109.         temp = self.openlist[m/2]
  110.         self.openlist[m/2] = self.openlist[m]
  111.         self.openlist[m] = temp
  112.         m = m / 2
  113.       else:
  114.         break
  115.    
  116.   def heap_add(self,node):
  117.     self.openlist.append(node)
  118.     # Add item to the onopenlist.
  119.     self.onopenlist[(node.x,node.y)] = node
  120.     m = len(self.openlist)-1
  121.     while m > 1:
  122.       if self.openlist[m/2].cost() > self.openlist[m].cost():
  123.         temp = self.openlist[m/2]
  124.         self.openlist[m/2] = self.openlist[m]
  125.         self.openlist[m] = temp
  126.         m = m / 2
  127.       else:
  128.         break
  129.    
  130.   def heap_remove(self):
  131.     if len(self.openlist) == 1:
  132.       return
  133.     first = self.openlist[1]
  134.     # Remove the first item from the onopenlist
  135.     self.onopenlist[(self.openlist[1].x,self.openlist[1].y)] = None
  136.     last = self.openlist.pop(len(self.openlist)-1)
  137.     if len(self.openlist) == 1:
  138.       return last
  139.     else:
  140.       self.openlist[1] = last
  141.     v = 1
  142.     while True:
  143.       u = v
  144.       # If there is two children
  145.       if (2*u)+1 < len(self.openlist):
  146.         if self.openlist[2*u].cost() <= self.openlist[u].cost():
  147.           v = 2*u
  148.         if self.openlist[(2*u)+1].cost() <= self.openlist[v].cost():
  149.           v = (2*u)+1
  150.       # If there is only one children
  151.       elif 2*u < len(self.openlist):
  152.         if self.openlist[2*u].cost() <= self.openlist[u].cost():
  153.           v = 2*u
  154.       # If at least one child is smaller, than parent, swap them
  155.       if u != v:
  156.         temp = self.openlist[u]
  157.         self.openlist[u] = self.openlist[v]
  158.         self.openlist[v] = temp
  159.       else:
  160.         break
  161.     return first
  162.    
  163.   def iterate(self):
  164.     # If the open list is empty, exit the game
  165.     if len(self.openlist) == 1:
  166.       ika.Exit("no path found")
  167.     # Expand iteration by one
  168.     self.iterations += 1
  169.     # Make the current node the lowest cost
  170.     self.current = self.heap_remove()
  171.     # Add it to the closed list
  172.     self.closedlist[(self.current.x,self.current.y)] = True
  173.     # Are we there yet?
  174.     if self.current.equal(self.goal) == True:
  175.       # Target reached
  176.       self.goal = self.current
  177.       self.found = True
  178.       print self.iterations
  179.     else:
  180.       # Add the adjacent nodes, and check them
  181.       nodes_around = self.add_nodes(self.current)
  182.       for na in nodes_around:
  183.         if self.ignore(na,self.current) == False:
  184.           self.heap_add(na)
  185.          
  186.   def iterateloop(self):
  187.     time1 = time.clock()
  188.     while 1:
  189.       # If the open list is empty, exit the game
  190.       if len(self.openlist) == 1:
  191.         ika.Exit("no path found")
  192.       # Expand iteration by one
  193.       self.iterations += 1
  194.       # Make the current node the lowest cost
  195.       self.current = self.heap_remove()
  196.       # Add it to the closed list
  197.       self.closedlist[(self.current.x,self.current.y)] = True
  198.       # Are we there yet?
  199.       if self.current.equal(self.goal) == True:
  200.         # Target reached
  201.         self.goal = self.current
  202.         self.found = True
  203.         print "Number of iterations"
  204.         print self.iterations
  205.         break
  206.       else:
  207.         # Add the adjacent nodes, and check them
  208.         nodes_around = self.add_nodes(self.current)
  209.         for na in nodes_around:
  210.           if self.ignore(na,self.current) == False:
  211.             self.heap_add(na)
  212.     time2 = time.clock()
  213.     time3 = time2-time1
  214.     print "Seconds to find path:"
  215.     print time3
  216.    
  217. class Map:
  218.  
  219.   def __init__(self):
  220.     self.map_size_x = 20
  221.     self.map_size_y = 15
  222.     self.obstructed = {} # Library, containing x,y couples
  223.     self.start = [2*40,3*40]
  224.     self.unit = [16*40,8*40]
  225.    
  226.   def is_obstacle(self,couple,x,y):
  227.     if (x >= self.map_size_x or x < 0) or (y >= self.map_size_y or y < 0):
  228.       return True
  229.     try:
  230.       if self.obstructed[(couple)] != None:
  231.         return True
  232.     except:
  233.       return False
  234.  
  235. def render_screen():
  236.   # Draw the Character
  237.   ika.Video.DrawRect(map.start[0],map.start[1],map.start[0]+40,map.start[1]+40,ika.RGB(40,200,10),1)
  238.   # Draw walls
  239.   for x in range(0,map.map_size_x):
  240.     for y in range(0,map.map_size_y):
  241.       if map.is_obstacle((x,y),x,y) == True:
  242.         ika.Video.DrawRect(x*40,y*40,(x*40)+40,(y*40)+40,ika.RGB(168,44,0),1)
  243.   # Draw openlist items
  244.   for node in path.openlist:
  245.     if node == None:
  246.       continue
  247.     x = node.x
  248.     y = node.y
  249.     ika.Video.DrawRect(x*40,y*40,(x*40)+40,(y*40)+40,ika.RGB(100,100,100,50),1)
  250.   # Draw closedlist items
  251.   for x in range(0,map.map_size_x):
  252.     for y in range(0,map.map_size_y):
  253.       try:
  254.         if path.closedlist[(x,y)] == True:
  255.           ika.Video.DrawRect(x*40,y*40,(x*40)+20,(y*40)+20,ika.RGB(0,0,255))
  256.       except:
  257.         pass
  258.   # Draw the current square
  259.   try:
  260.     ika.Video.DrawRect(path.current.x*40,path.current.y*40,(path.current.x*40)+40,(path.current.y*40)+40,ika.RGB(128,128,128), 1)
  261.   except:
  262.     pass
  263.   ika.Video.DrawRect(mouse_x.Position(),mouse_y.Position(),mouse_x.Position()+8,mouse_y.Position()+8,ika.RGB(128,128,128), 1)
  264.   # Draw the path, if reached
  265.   if path.found == True:
  266.     node = path.goal
  267.     while node.parent:
  268.       ika.Video.DrawRect(node.x*40,node.y*40,(node.x*40)+40,(node.y*40)+40,ika.RGB(40,200,200),1)
  269.       node = node.parent
  270.   # Draw the Target
  271.   ika.Video.DrawRect(map.unit[0],map.unit[1],map.unit[0]+40,map.unit[1]+40,ika.RGB(128,40,200),1)
  272.  
  273. def mainloop():
  274.   while 1:
  275.     render_screen()
  276.     if mouse_middle.Pressed():
  277.       # Iterate pathfinder
  278.       if path.found == False:
  279.         path.iterateloop()
  280.     elif mouse_right.Pressed():
  281.       # Iterate pathfinder by one
  282.       if path.found == False:
  283.         path.iterate()
  284.     elif ika.Input.keyboard["A"].Pressed():
  285.       # Iterate pathfinder
  286.       if path.found == False:
  287.         path.iterateloop()
  288.     elif ika.Input.keyboard["S"].Pressed():
  289.       # Iterate pathfinder by one
  290.       if path.found == False:
  291.         path.iterate()
  292.     elif mouse_left.Position():
  293.       # Add a square to the map, to be obstructed
  294.       if path.iterations == 0:
  295.         x = mouse_x.Position()
  296.         y = mouse_y.Position()
  297.         map.obstructed[(int(x/40),int(y/40))] = True
  298.     # Mouse preview
  299.     x = mouse_x.Position()
  300.     y = mouse_y.Position()
  301.     mx = int(x/40)*40
  302.     my = int(y/40)*40
  303.     ika.Video.DrawRect(mx,my,mx+40,my+40,ika.RGB(150,150,150,70),1)
  304.     ika.Video.ShowPage()
  305.     ika.Input.Update()
  306.    
  307. map = Map()
  308. path = Emerald_Pathfinder()
  309. path.setup(Node(map.start[0]/40,map.start[1]/40),Node(map.unit[0]/40,map.unit[1]/40))
  310. mouse_middle = ika.Input.mouse.middle
  311. mouse_right = ika.Input.mouse.right
  312. mouse_left = ika.Input.mouse.left
  313. mouse_x = ika.Input.mouse.x
  314. mouse_y = ika.Input.mouse.y
  315. # Initialize loop
  316. mainloop()
Advertisement
Add Comment
Please, Sign In to add comment