|
|
|
@ -181,13 +181,32 @@ class DBController: |
|
|
|
self.graph.add_edge(from_pfic, to_pfic, method=method) |
|
|
|
|
|
|
|
def get_evolution_graph(self, pfic): |
|
|
|
if self.graph.has_node(pfic) == False: |
|
|
|
return [] |
|
|
|
|
|
|
|
return list(self.graph.successors(pfic)) |
|
|
|
|
|
|
|
def get_previous_evolution(self, pfic): |
|
|
|
if self.graph.has_node(pfic) == False: |
|
|
|
return None, None |
|
|
|
|
|
|
|
predecessor = next(self.graph.predecessors(pfic), None) |
|
|
|
|
|
|
|
if predecessor: |
|
|
|
method = self.graph[predecessor][pfic]["method"] |
|
|
|
return predecessor, method |
|
|
|
else: |
|
|
|
return None, None |
|
|
|
|
|
|
|
def get_evolution_paths(self, start_node): |
|
|
|
paths = [] |
|
|
|
|
|
|
|
if self.graph.has_node(start_node) == False: |
|
|
|
return paths |
|
|
|
|
|
|
|
# Define a recursive function to traverse the graph |
|
|
|
def traverse(current_node, current_path): |
|
|
|
def traverse(current_node, current_path, is_root=False): |
|
|
|
if is_root: |
|
|
|
# Add the current node to the path as a tuple (node, None) |
|
|
|
current_path.append((current_node, None)) |
|
|
|
|
|
|
|
@ -211,9 +230,90 @@ class DBController: |
|
|
|
current_path.pop() |
|
|
|
|
|
|
|
# Remove the initial node tuple when backtracking fully |
|
|
|
if is_root: |
|
|
|
current_path.pop() |
|
|
|
|
|
|
|
# Start traversal from the start_node |
|
|
|
traverse(start_node, []) |
|
|
|
traverse(start_node, [], True) |
|
|
|
|
|
|
|
return paths |
|
|
|
|
|
|
|
def get_full_evolution_paths(self, start_node): |
|
|
|
""" |
|
|
|
Get all evolution paths starting from a given node, including predecessors and successors. |
|
|
|
:param start_node: The starting node (e.g., a specific Pokemon form). |
|
|
|
:return: A dictionary containing predecessors and successors paths. |
|
|
|
""" |
|
|
|
full_paths = { |
|
|
|
"predecessors": [], |
|
|
|
"successors": [] |
|
|
|
} |
|
|
|
|
|
|
|
if self.graph.has_node(start_node) == False: |
|
|
|
return full_paths |
|
|
|
|
|
|
|
# Traverse predecessors |
|
|
|
def traverse_predecessors(current_node, current_path, is_root=False): |
|
|
|
#if not is_root: |
|
|
|
# Add the current node to the path |
|
|
|
#current_path.append(current_node) |
|
|
|
|
|
|
|
# Get predecessors of the current node |
|
|
|
predecessors = list(self.graph.predecessors(current_node)) |
|
|
|
|
|
|
|
if not predecessors: |
|
|
|
# If there are no predecessors, add the current path to the list |
|
|
|
full_paths["predecessors"].append(current_path.copy()) |
|
|
|
else: |
|
|
|
# Traverse each predecessor |
|
|
|
for predecessor in predecessors: |
|
|
|
method = self.graph[predecessor][current_node]["method"] |
|
|
|
# Add the edge metadata as a tuple (predecessor, method) |
|
|
|
current_path.append((predecessor, method)) |
|
|
|
|
|
|
|
# Recur for the predecessor |
|
|
|
traverse_predecessors(predecessor, current_path) |
|
|
|
|
|
|
|
# Backtrack (remove the last node and edge metadata) |
|
|
|
current_path.pop() |
|
|
|
#current_path.pop() |
|
|
|
|
|
|
|
# Traverse successors |
|
|
|
def traverse_successors(current_node, current_path, is_root=False): |
|
|
|
if is_root: |
|
|
|
# Add the current node to the path as a tuple (node, None) |
|
|
|
predecessor = next(self.graph.predecessors(current_node), None) |
|
|
|
if predecessor: |
|
|
|
method = self.graph[predecessor][current_node]["method"] |
|
|
|
current_path.append((current_node, method)) |
|
|
|
else: |
|
|
|
current_path.append((current_node, None)) |
|
|
|
|
|
|
|
# Get successors of the current node |
|
|
|
successors = list(self.graph.successors(current_node)) |
|
|
|
|
|
|
|
if not successors: |
|
|
|
# If there are no successors, add the current path to paths list |
|
|
|
full_paths["successors"].append(current_path.copy()) |
|
|
|
else: |
|
|
|
# Traverse each successor and add edge metadata |
|
|
|
for successor in successors: |
|
|
|
method = self.graph[current_node][successor]["method"] |
|
|
|
# Add the successor node and method as a tuple (successor, method) |
|
|
|
current_path.append((successor, method)) |
|
|
|
|
|
|
|
# Recur for the successor |
|
|
|
traverse_successors(successor, current_path) |
|
|
|
|
|
|
|
# Backtrack (remove the last node and edge metadata) |
|
|
|
current_path.pop() |
|
|
|
|
|
|
|
if is_root: |
|
|
|
# Remove the initial node tuple when backtracking fully |
|
|
|
current_path.pop() |
|
|
|
|
|
|
|
# Start traversal from the start_node for both predecessors and successors |
|
|
|
traverse_predecessors(start_node, [], True) |
|
|
|
traverse_successors(start_node, [], True) |
|
|
|
|
|
|
|
return full_paths |