171 lines
4.4 KiB
Python
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
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|