Started Routefinding Part 1. Framework is mostly setup for the assignment.

This commit is contained in:
Charles Descamps 2025-02-26 15:33:51 -07:00
parent 01f18dd14a
commit fde713cecf

View file

@ -1,4 +1,149 @@
# Define Searcher class here.
# Define Searcher, hSLD, SearchNode.
import DRDViz
import math
def hSLD(node, search):
# take the node value in
# find the node value coordinates
coords = search.nodeLocs[node]
goalCoords = search.nodeLocs[search.endNode]
# calculate the distance between the two points
distance = math.sqrt((abs(int(coords[0]) - int(goalCoords[0])))**2 + abs(int(coords[1]) - int(goalCoords[1]))**2)
return distance
class SearchNode:
def __init__(self, label, pathcost):
self.label = label
self.pathcost = pathcost
self.node = tuple((label, pathcost))
def showBasic(self):
# print(self.node) # debugging purposes
return self.node
def __eq__(self, object):
return ((self.label) == (object.label))
def __lt__(self, object):
return ((self.label) < (object.label))
def __repr__(self):
return repr(self.node)
class Searcher:
def __init__(self, mapfile, searchType, verbose=False):
self.mapfile = mapfile
self.searchType = searchType
# load the mapfile's structure
with open(self.mapfile) as mapper:
mapContents = mapper.read()
mapContents = mapContents.split("\n")
for mapIter in range(len(mapContents)):
mapContents[mapIter] = mapContents[mapIter].split(", ")
for firstDimMapIter in range(len(mapContents) - 1):
for secondDimMapIter in range(len(mapContents[firstDimMapIter])):
mapContents[firstDimMapIter][secondDimMapIter] = mapContents[firstDimMapIter][secondDimMapIter].strip("')(][")
mapContents.pop(len(mapContents) - 1)
for tupleIter in range(len(mapContents)):
mapContents[tupleIter] = tuple(mapContents[tupleIter])
# print(mapContents) # list of tuples
# print(mapContents[0]) # tuple of strings (data)
# [first node, second node, path cost, first node x, first node y, second node x, second node y]
# 0 1 2 3 4 5 6
# print(mapContents[0][0]) # data, string format
# make two dictionaries of nodes, iterating through list of tuples to make note of every node's paths and locations
nodeLoc = dict()
nodePaths = dict()
for nodeIter in range(len(mapContents)):
# these node locations are fine, because they should technically be in only one place.
nodeLoc[mapContents[nodeIter][0]] = tuple((mapContents[nodeIter][3], mapContents[nodeIter][4]))
nodeLoc[mapContents[nodeIter][1]] = tuple((mapContents[nodeIter][5], mapContents[nodeIter][6]))
# however, this is only taking the first node path it gets to...
# I probably need a list instead, that gets updated if the node is not in the node's child list.
# check if the key exists, if it does, then add the value to the internal dictionary,
# if the internal dictionary doesn't exist, then create it and add the node.
if mapContents[nodeIter][0] not in nodePaths.keys():
nodePaths[mapContents[nodeIter][0]] = dict()
nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2]
else:
if nodePaths[mapContents[nodeIter][0]].values() not in nodePaths[mapContents[nodeIter][0]].keys():
nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = dict()
nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2]
else:
nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2]
if mapContents[nodeIter][1] not in nodePaths.keys():
nodePaths[mapContents[nodeIter][1]] = dict()
nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2]
else:
if nodePaths[mapContents[nodeIter][1]].values() not in nodePaths[mapContents[nodeIter][1]].keys():
nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = dict()
nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2]
else:
nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2]
self.nodePaths = nodePaths
self.nodeLocs = nodeLoc
# need to get the myViz attribute by importing the DRDViz stuff.
self.myViz = DRDViz.DRDViz()
# now, start using the myViz thingy to 'display' a map.
self.myViz.loadGraphFromFile(mapfile)
self.myViz.plot()
# create an 'open' list
self.open = list()
def setStartGoal(self, startNode, endNode):
self.startNode = startNode
self.endNode = endNode
self.myViz.markStart(self.startNode)
self.myViz.markGoal(self.endNode)
# add the starting node to the 'open' list.
starting = SearchNode(startNode, 0)
self.open.append(starting)
def successors(self, parentNode):
childList = list()
# grab the nodes from the nested dictionary given that the parentNode is a tuple.
nodeChildren = self.nodePaths.get(parentNode.label)
# grab each value from the dictionary, turn it into a SearchNode.
for node in nodeChildren.keys():
childList.append(SearchNode(node, int(nodeChildren[node])))
# sort the child node list
childList.sort()
return (childList)
def reset(self):
# clear all the items from the open list
self.open.clear()
# add the start node back into the list.
self.open.append(SearchNode(self.startNode, 0))
# do I need to reset the visualization too?
def insert_front(self, nodeList):
# backwards "sort"
# loop through each element, and apply it to the beginning of the open list.
for item in nodeList:
if item not in self.open:
self.open.insert(0, item)
def insert_end(self, nodeList):
# forwards "sort"
# loop through each element, and apply it to the end of the open list.
for item in nodeList:
if item not in self.open:
self.open.append(item)
def insert_ordered(self, nodeList):
# sort by the lowest cost after adding all the elements to the open list.
# add the nodes to the list
self.open.extend(nodeList)
# sort via a lambda function key, using the sorted function
sortedList = sorted(self.open, key=lambda item: item.pathcost)
# clear out the open list
self.open.clear()
# replace it with the sorted list by extending the blank list.
self.open.extend(sortedList)
def search(self):
print(f"Begin Searching with type {self.searchType}")
if self.searchType.lower() == "depth":
print()
elif self.searchType.lower() == "breadth":
print()
elif self.searchType.lower() == "best":
print()
elif self.searchType.lower() == "a*":
print()
else:
print("Invalid searchtype.")
# 10test.txt map
x=Searcher("10test.txt", searchType="DEPTH", verbose=True)