Sztuczna_inteligencja/pathfinder.py

171 lines
4.4 KiB
Python

import board
def distance_between(startpoint, endpoint):
sx = startpoint % board.BOARDCOLS
sy = startpoint // board.BOARDCOLS
ex = endpoint % board.BOARDCOLS
ey = endpoint // board.BOARDCOLS
return (abs((ex - sx)) + abs((ey - sy)))
def find_bomb(fields, start_position):
bombfield = -1
mindist = board.BOARDCOLS ** 2
for i in range(len(fields)):
if fields[i].type == 'B':
if fields[i].object.defused == False:
dist = distance_between(start_position, i)
if dist < mindist:
bombfield = i
mindist = dist
return bombfield
class Node:
def __init__(self,fieldN,parent,destination,obstacle_deley_value):
self.field_number = fieldN
self.parent_field = parent
self.distance_to_destination = distance_between(fieldN,destination)
if parent is None:
self.distance_to_agent = 0
self.obstacle_deley = obstacle_deley_value
else:
self.distance_to_agent = parent.distance_to_agent + 1
self.obstacle_deley = obstacle_deley_value + parent.obstacle_deley
self.path_cost = self.distance_to_destination + self.distance_to_agent + self.obstacle_deley
class Pathfind:
def __init__(self, fields, bombfield, agent_position):
self.open_nodes = []
self.closed_nodes = []
self.fields = fields
self.bombfield = bombfield
self.agent_position = agent_position
self.way = self.pathway()
def lowest_cost_node(self):
lowestcost = self.open_nodes[0].path_cost
bestnode = self.open_nodes[0]
#print("szukam lowest cost!")
#print("lowest cost: ", lowestcost)
#print("przeszukuje nodes")
for node in self.open_nodes:
#print(node.path_cost)
if (node.path_cost < lowestcost) or (node.path_cost == lowestcost and node.distance_to_destination < bestnode.distance_to_destination):
lowestcost = node.path_cost
bestnode = node
#print("zmienilem node")
#print("skonczylem wyszukiwac, lowest cost = ", bestnode.path_cost)
return bestnode
def neighbours(self, node):
actuallpos = node.field_number
neighboursTab = []
if not actuallpos - board.BOARDCOLS < 0:
neighboursTab.append(actuallpos - board.BOARDCOLS)
if not actuallpos + board.BOARDCOLS >= (board.BOARDCOLS ** 2):
neighboursTab.append(actuallpos + board.BOARDCOLS)
if not (actuallpos - 1 < 0 or actuallpos%board.BOARDCOLS == 0 ):
neighboursTab.append(actuallpos - 1)
if not (actuallpos + 1 >= (board.BOARDCOLS ** 2) or actuallpos%board.BOARDCOLS == (board.BOARDCOLS-1) ):
neighboursTab.append(actuallpos + 1)
return neighboursTab
def node_in_closed(self, fn):
for node in self.closed_nodes:
if node.field_number == fn:
return True
return False
def node_in_open(self,fn):
for node in self.open_nodes:
if node.field_number == fn:
return node
return None
def findway(self):
startnode = Node(self.agent_position, None, self.bombfield, 0)
self.open_nodes.append(startnode)
while True:
current = self.lowest_cost_node()
#print("szukam drogi , current field:", current.field_number)
self.open_nodes.remove(current)
self.closed_nodes.append(current)
if current.field_number == self.bombfield:
#print("znalazlem droge !!!!!!!!!!!!")
return current
neighbours = self.neighbours(current)
#print("neighbours: ", end=" ")
#for x in neighbours:
#print(x, end=" ")
#print("")
for neighbour in neighbours:
if self.node_in_closed(neighbour) == False:
if self.node_in_open(neighbour) is None:
node = Node(neighbour, current, self.bombfield, self.fields[neighbour].deley_value)
self.open_nodes.append(node)
#print(neighbour, ": ", node.path_cost)
else:
newcost = distance_between(neighbour, self.bombfield) + current.obstacle_deley + self.fields[neighbour].deley_value + current.distance_to_agent + 1
if newcost < self.node_in_open(neighbour).path_cost:
self.node_in_open(neighbour).pathcost = newcost
self.node_in_open(neighbour).parent_field = current
#print(neighbour, ": ", node.path_cost)
def pathway(self):
way = []
current = self.findway()
while current.field_number != self.agent_position:
way.append(current.field_number)
current = current.parent_field
way.reverse()
#print("path is: ", end =" ")
#for x in way:
#print(x, end = " ")
#print("")
return way