Last active
August 8, 2019 16:34
-
-
Save BoiJr/39574461b98be0777865cad9099ba1dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def __init__(self,unit): | |
## Type Options ## | |
## "path" is blue, "success" is green, "failed" is red, "node" is yellow, "blue" is itteration, True is white, False does not create an image ## | |
## THIS DETERMINES IF A PATH HAS BEEN FOUND AND WHAT IT IS IF IT HAS FOUND A PATH ## | |
self.pathFound = ["none"] | |
## KEEPS PATH FINDER LOOKING AS LONG AS THERE IS AN OPEN PATH OPTION ## | |
self.pathFoundViable = True | |
self.unit = unit | |
## THIS IS ALL THE PATH OPTION FOR THE UNIT DISPLAYED AS LINES## | |
for i in range(len(self.unit.debugPaths)-1,-1,-1): | |
self.unit.debugPaths[i].basicImage.sprite.kill() | |
self.unit.debugPaths = [] | |
## THIS IS THE STARTING POINT OF THE PATH FINDER ## | |
self.pathFindStart = copy.copy(unit.center) | |
## "nodes" these are places it will attempt to go to ## | |
self.nodes = [unit.goal] | |
self.paths = [ [[self.pathFindStart],0] ] | |
self.reached = [[self.pathFindStart,0,"path in table"]] | |
self.checked = [ ] | |
self.failedPaths = [] | |
self.currentNode = 0 | |
self.currentPath = 0 | |
self.currentTime = 0 | |
self.currentFrames = 0 | |
self.enterFrame = "none" | |
self.tickPathFinder("blank") | |
def tickPathFinder(self,blank): | |
aTime = delayCalculator("none") | |
currentDelay = 0 | |
allotedTime = 5 | |
while self.pathFoundViable == True and currentDelay < allotedTime: | |
## THIS SWITCHES THE PATH OFF IF NONE OF THE AVAILABLE PATHS HAVE A PLACE TO GO TO ## | |
self.pathFoundViable = False | |
## THIS CHECKES ALL POTENTIAL PATHS ## | |
for i in range(0,len(self.paths) ): | |
if (currentDelay > allotedTime): | |
break | |
if (i >= self.currentPath): | |
runPath = True | |
if (self.pathFound != ["none"]): | |
if (self.pathFound[1] <= self.paths[i][1]): | |
runPath = False | |
if (runPath == True): | |
for j in range(0,len(self.nodes) ): | |
if (j >= self.currentNode): | |
self.currentNode = 0 | |
self.currentLine = 0 | |
## CURRENT PATH BEING CHECKED ## | |
index = len(self.paths[i][0])-1 | |
## STARTING POINT OF THE PATH ## | |
start = list(self.paths[i][0][index]) | |
## ENDING POINT OF THE PATH ## | |
end = self.nodes[j] | |
## if the start and end have not been checked together and the start isnt the end ## | |
if ([start,end] not in self.checked and start != end): | |
## Calculates the total distance between start and the end ## | |
distance = solveDistance(start,end) | |
distance = distance[2] | |
## adds the distance to the total path distance ## | |
pathDistance = self.paths[i][1]+distance | |
## sets state of path (new,improved,worsened) ## | |
pathInfo = "new" | |
## adds start and end to list of paths checked ## | |
self.checked.append([start,end]) | |
## checks all paths already reached ## | |
for t in range(0,len(self.reached) ): | |
## if this point has been reached ## | |
if (end == self.reached[t][0]): | |
## if this path is shorter ## | |
if (pathDistance < self.reached[t][1]): | |
## Label this path state to be improved ## | |
pathInfo = "improved" | |
pathUpdate = self.reached[t] | |
## if this path is not shorter ## | |
else: | |
pathInfo = "worsened" | |
if (end != self.paths[i][0][index] and pathInfo == "new" or end != self.paths[i][0][index] and pathInfo == "improved"): | |
## this copies the end nodes seperating it completely from the node ## | |
realEnd = copy.deepcopy(end) | |
## this is the diferrence between the endx startx, endy starty # | |
parametrizationSlope = [end[0]-start[0],end[1]-start[1] ] | |
## this converts this to a difference relative to the distance of the line ## | |
parametrizationSlope[0] = parametrizationSlope[0]/distance | |
parametrizationSlope[1] = parametrizationSlope[1]/distance | |
## This adds distance equal to the units size as a cusion to the end point following along the parametrization slope line ## | |
realEnd[0] = realEnd[0]+parametrizationSlope[0]*self.unit.size*.6 | |
realEnd[1] = realEnd[1]+parametrizationSlope[1]*self.unit.size*.6 | |
## This signals that the path had at least one viable path off the previous path ## | |
self.pathFoundViable = True | |
## this sets the type of line in case it needs to be drawn ## | |
type = False | |
## creates a line object from start to end with the correct type ## | |
newLine = createLine(start,end,type) | |
## Creates a table to store all intersections that could happen ## | |
intersectionTable = checkLines(newLine,objectTable) ## SEND A LINE PLUS A TABLE OF POTENTIAL INTERSECTIONS AND IT WILL RETURN [THE INDEX SPOT IN TABLE,THE LINE,XVAL,YVAL] ## | |
## Creates a variable for if the path is going to fail ## | |
addedToFailed = False | |
## Loops through the intersection Table to find the closest intersection ## | |
for k in range(0,len(intersectionTable) ): | |
## If this path hasnt failed yet ## | |
if (addedToFailed == False): | |
## adds this path to the failed path list ## | |
self.failedPaths.append(list(intersectionTable[k]) ) | |
## this solves for the distance between the start of the line and the intersection ## | |
addedToFailed = solveDistance([intersectionTable[k][2],intersectionTable[k][3]],start) | |
## sets added to failed to the distance between the start of the line and the intersection ## | |
addedToFailed = addedToFailed[2] | |
## If this path has failed ## | |
elif (addedToFailed != False): | |
## this solves for the distance between the start of the line and the intersection ## | |
newAddedToFailed = solveDistance([intersectionTable[k][2],intersectionTable[k][3]],start) | |
## sets added to failed to the distance between the start of the line and the intersection ## | |
newAddedToFailed = newAddedToFailed[2] | |
## if this intersection is closer ## | |
if (newAddedToFailed < addedToFailed): | |
## finds index of previous path ## | |
index = len(self.failedPaths)-1 | |
## deletes previous path ## | |
del(self.failedPaths[index]) | |
## adds new path ## | |
self.failedPaths.append(list(intersectionTable[k]) ) | |
## Option to turn itterations on or off ## | |
itterations = "on" | |
## checks if itterations are on (they are the lines that check the edge of the unit ## | |
if (itterations == "on"): | |
type = False | |
if (Rules.pathFindingIterationLines == True): | |
type = "itteration" | |
## finds the inverse slope ## | |
inverseX = newLine.parametrizationSlope[1]*-1 | |
inverseY = newLine.parametrizationSlope[0] | |
## Adjusts to the unit size to the inverse slope to give proper size itteration line ## | |
netX = inverseX*self.unit.size/2 | |
netY = inverseY*self.unit.size/2 | |
## Creates Line Points "above" the original for start and end ## | |
inverseStart = [start[0]+netX,start[1]+netY] | |
inverseEnd = [realEnd[0]+netX,realEnd[1]+netY] | |
## Creates Line for Itteration Line above ## | |
parallelLine = createLine(inverseStart,inverseEnd,type) | |
## Checks for intersections ## | |
intersectionAddTable = checkLines(parallelLine,objectTable) | |
## Checks if this needs to be added to debugPath | |
if (Rules.pathFindingIterationLines == True): | |
## Adds to debugPath ## | |
self.unit.debugPaths.append(parallelLine) | |
## adds all intersections to the intersection table ## | |
for c in range(0,len(intersectionAddTable) ): | |
intersectionTable.append(intersectionAddTable[c]) | |
self.failedPaths.append(list(intersectionAddTable[c]) ) | |
## Repeats the above code except with it being "below" the original line ## | |
secondInverseStart = [start[0]-netX,start[1]-netY] | |
secondInverseEnd = [realEnd[0]-netX,realEnd[1]-netY] | |
parallelLine = createLine(secondInverseStart,secondInverseEnd,type) | |
intersectionAddTable = checkLines(parallelLine,objectTable) | |
if (Rules.pathFindingIterationLines == True): | |
self.unit.debugPaths.append(parallelLine) | |
for c in range(0,len(intersectionAddTable) ): | |
intersectionTable.append(intersectionAddTable[c]) | |
self.failedPaths.append(list(intersectionAddTable[c]) ) | |
## Creates Line to close the box around original line and then checks similar to above ## | |
endCapLineStart = [inverseEnd[0],inverseEnd[1]] | |
endCapLineEnd = [secondInverseEnd[0],secondInverseEnd[1]] | |
endCapLine = createLine(endCapLineStart,endCapLineEnd,type) | |
intersectionAddTable = checkLines(endCapLine,objectTable) | |
if (Rules.pathFindingIterationLines == True): | |
self.unit.debugPaths.append(endCapLine) | |
for c in range(0,len(intersectionAddTable) ): | |
intersectionTable.append(intersectionAddTable[c]) | |
self.failedPaths.append(list(intersectionAddTable[c]) ) | |
## If there was no intersections this is a real path ## | |
if (len(intersectionTable) == 0): | |
## Considered a path ## | |
type = "path" | |
else: | |
## Considered a failed path ## | |
type = "failed" | |
if (Rules.pathFindingLines == False): | |
type = False | |
## Creates Line with proper color Coding (This happened above with wrong color line?) ## | |
newLine = createLine(start,end,type) | |
## Checks if this needs to be added to debugPath | |
if (Rules.pathFindingLines == True): | |
## Adds to debug path ## | |
self.unit.debugPaths.append(newLine) | |
## Runs through all intersections and nodes ## | |
for k in range(0,len(intersectionTable) ): | |
for l in range(0,len(intersectionTable[k][0].nodes) ): | |
## Checks angle and finds line along the average slope ## | |
angle = (math.pi*intersectionTable[k][0].nodes[l][1])/180 | |
xShift = math.cos(angle)*self.unit.size | |
yShift = -math.sin(angle)*self.unit.size | |
## adds shift to node ## | |
checkX = intersectionTable[k][0].nodes[l][0].realX+xShift | |
checkY = intersectionTable[k][0].nodes[l][0].realY+yShift | |
## Puts Node in node table if it wasn't already ## | |
if ([checkX,checkY] not in self.nodes): | |
self.nodes.append( [checkX,checkY] ) | |
## If this path is to the goal and there wasn't any intersections ## | |
if (len(intersectionTable) == 0 and end == self.unit.goal): | |
## If this is the only sucessful path so far ## | |
if (self.pathFound == ["none"] ): | |
## Copies current path chain ## | |
pointTableCopy = copy.copy(self.paths[i][0]) | |
## adds new point ## | |
pointTableCopy.append(end) | |
## adds to successful path list ## | |
self.pathFound = [pointTableCopy,pathDistance] | |
else: | |
## if this isnt the only sucessfulpath so far checks if path distance is shorter ## | |
if (self.pathFound[1] > pathDistance): | |
pointTableCopy = copy.copy(self.paths[i][0]) | |
pointTableCopy.append(end) | |
## Replaces current path ## | |
self.pathFound = [pointTableCopy,pathDistance] | |
## If this path had no intersections ## | |
elif(len(intersectionTable) == 0): | |
## creates list of points ## | |
pathPoints = list(self.paths[i][0]) | |
## adds end point ## | |
pathPoints.append(end) | |
## adds new path to list of paths ## | |
self.paths.append([pathPoints,pathDistance]) | |
## updates index ## | |
newPathIndex = len(self.paths)-1 | |
## adds to list of reached points ## | |
self.reached.append([end,pathDistance,self.paths[newPathIndex] ]) | |
## if this path is an improvement ## | |
if (pathInfo == "improved"): | |
## it removes the old path and updates with correct and new information ## | |
pathUpdate[1] = pathDistance | |
oldPath = pathUpdate[2] | |
self.paths.remove(oldPath) | |
currentDelay = delayCalculator([aTime]) | |
if (currentDelay > allotedTime): | |
self.currentNode = j | |
self.currentPath = i | |
break | |
if (self.pathFound[0] != "none" and self.pathFoundViable == False): | |
for i in range(len(self.unit.debugPaths)-1,-1,-1 ): | |
for u in range(len(self.pathFound[0])-2,-1,-1): | |
if (self.unit.debugPaths[i].startPoint == self.pathFound[0][u] and self.unit.debugPaths[i].endPoint == self.pathFound[0][u+1] or self.pathFound[0][u] == self.unit.debugPaths[i].endPoint and self.pathFound[0][u+1] == self.unit.debugPaths[i].startPoint): | |
self.unit.debugPaths[i].basicImage.sprite.kill() | |
del self.unit.debugPaths[i] | |
for i in range(0,len(self.pathFound[0])-1 ): | |
newLine = createLine(self.pathFound[0][i],self.pathFound[0][i+1],"success") | |
if (Rules.pathFindingSuccessLines == True): | |
self.unit.debugPaths.append(newLine) | |
## THIS ATTEMPTS TO FIND THE NEAREST POINT IF NO PATH CAN BE FOUND ## | |
elif (self.pathFound[0] == "none" and self.pathFoundViable == False): | |
closest = solveDistance(self.unit.goal,[self.failedPaths[0][2],self.failedPaths[0][3]]) | |
closest = closest[2] | |
closest = [closest,0] | |
for i in range(0,len(self.failedPaths) ): | |
closestCheck = solveDistance(self.unit.goal,[self.failedPaths[i][2],self.failedPaths[i][3]]) | |
closestCheck = closestCheck[2] | |
if (closestCheck < closest[0]): | |
closest = [closestCheck,i] | |
index = closest[1] | |
self.failedPaths[index][2] | |
closestLine = self.failedPaths[closest[1]][1] | |
inverseX = self.failedPaths[closest[1]][1].parametrizationSlope[1]*-1 | |
inverseY = self.failedPaths[closest[1]][1].parametrizationSlope[0] | |
netX = inverseX*closest[0]*2 | |
netY = inverseY*closest[0]*2 | |
closestStart = [self.unit.goal[0]-netX/2,self.unit.goal[1]-netY/2] | |
closestEnd = [self.unit.goal[0]+netX,self.unit.goal[1]+netY] | |
if (closestStart == closestEnd): | |
closestEnd = [closestEnd[0]+1,closestEnd[1]+1] | |
closestLineCreation = createLine(closestStart,closestEnd,"none") | |
closestIntersectionTable = checkLines(closestLineCreation,[self.failedPaths[closest[1]][0]]) | |
closest = solveDistance(self.unit.goal,[closestIntersectionTable[0][2],closestIntersectionTable[0][3]] ) | |
closest = [closest,0,] | |
for i in range(0,len(closestIntersectionTable) ): | |
distance = solveDistance(self.unit.goal,[closestIntersectionTable[i][2],closestIntersectionTable[i][3]] ) | |
if (distance[2] < closest[0][0]): | |
closest = [distance,i,] | |
angle = math.atan2(-closest[0][1],closest[0][0]) | |
xShift = math.cos(angle)*self.unit.size*1 | |
yShift = -math.sin(angle)*self.unit.size*1 | |
newGoalX = closestIntersectionTable[closest[1]][2]-xShift | |
newGoalY = closestIntersectionTable[closest[1]][3]-yShift | |
self.unit.goal = [newGoalX,newGoalY] | |
if (self.enterFrame != "none"): | |
enterFrameTable.remove(self.enterFrame) | |
self.enterFrame = "none" | |
self.nodes = [self.unit.goal] | |
self.paths = [ [[self.pathFindStart],0] ] | |
self.reached = [[self.pathFindStart,0,"path in table"]] | |
self.checked = [ ] | |
self.failedPaths = [] | |
self.currentNode = 0 | |
self.currentPath = 0 | |
self.currentTime = 0 | |
self.currentFrames = 0 | |
self.enterFrame = "none" | |
self.tickPathFinder("blank") | |
self.tickPathFinder("blank") | |
if (self.pathFound != ["none"] and self.pathFoundViable == False): | |
self.unit.path = self.pathFound | |
if (self.enterFrame != "none"): | |
enterFrameTable.remove(self.enterFrame) | |
self.enterFrame = "none" | |
print(self.currentFrames) | |
if (currentDelay >= allotedTime and self.pathFoundViable == True): | |
self.currentTime += currentDelay | |
self.currentFrames += 1 | |
#print(" ") | |
#print("node "+str(self.currentNode) ) | |
#print("path "+str(self.currentPath) ) | |
#print("time "+str(self.currentTime) ) | |
#print("Frames Till Complete "+str(self.currentFrames) ) | |
if (self.enterFrame == "none"): | |
self.enterFrame = EnterFrame(0,self.tickPathFinder,"blank","onComplete") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment