Skip to content

Commit

Permalink
⚡ Made blitting/ truly blazingly fast
Browse files Browse the repository at this point in the history
  • Loading branch information
vishalpaudel committed Oct 27, 2023
1 parent 66fddb1 commit 450dab0
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 100 deletions.
Empty file added __init__.py
Empty file.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

[build-system]
requires = ["setuptools", "wheel"]
58 changes: 33 additions & 25 deletions src/searchViz/Game.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@


import pygame as pg
import time
import numpy as np

from .constants import SCR_SIZE, BG_COLOR, RED, WHITE, NODE_RADIUS, SEARCH_RATE


Expand All @@ -10,7 +13,7 @@


class Game:
def __init__(self, search_method: Search, num_nodes: int):
def __init__(self, search_method: Search, num_nodes: int) -> None:
pg.init()

# main attributes of the game
Expand All @@ -33,7 +36,7 @@ def __init__(self, search_method: Search, num_nodes: int):

print("🐼 searchViz has been initialized! 🎉")

def handle_events(self):
def handle_events(self) -> None:
for event in pg.event.get():
if event.type == pg.QUIT:
self.running = False
Expand All @@ -57,34 +60,39 @@ def handle_events(self):

return None

def draw_graph(self):
# unpacking frequently used variables
graph_surf = self.graph_surf
num_nodes = self.Graph.num_nodes
nodes = self.Graph.nodes
colors = self.Graph.colors
radius = self.Graph.radius
edges = self.Graph.edges

# need to use this when traversing
# edge_colors = self.Graph.edge_color
def draw_graph(self) -> None:
_start_time = time.time()
print("✏️\tDrawing the Graph")

# Draw nodes and their edges
# Unpack frequently used variables
graph_surf = self.graph_surf
num_nodes = self.Graph.N_num
nodes = self.Graph.N_locs
colors = self.Graph.N_colors
radius = self.Graph.N_radii
edges = self.Graph.edge_connections

# Draw nodes
# TODO: vectorization of this possible? Probably not
for i in range(num_nodes):
# Unique (uni-directional) edges
for j in range(i, num_nodes):
if edges[i, j]:
pg.draw.line(graph_surf, WHITE, nodes[i], nodes[j])

node = nodes[i]
pg.draw.circle(
graph_surf,
color=tuple(colors[i]),
center=node,
radius=radius[i],
graph_surf, color=colors[i], center=nodes[i], radius=radius[i]
)

def run(self):
# Draw edges
edge_indices = np.transpose(np.where(edges))
for i, j in edge_indices:
pg.draw.line(graph_surf, WHITE, nodes[i], nodes[j])

_end_time = time.time()
_elapsed_time = _end_time - _start_time
print("✏️\tCompleted the drawing!")

print(f"\t🕰️ Took {_elapsed_time:.3f} seconds.\n")

return None

def run(self) -> None:
last_time = pg.time.get_ticks()
step = 0
self.draw_graph()
Expand Down
53 changes: 28 additions & 25 deletions src/searchViz/Graph.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python

from .constants import NODES_X_DISTRIBUTION, NODES_Y_DISTRIBUTION
from .constants import EDGE_CONFIDENCE, RED, BLUE, NODE_RADIUS
from .constants import EDGE_CONFIDENCE, BLUE, NODE_RADIUS, WHITE

import numpy as np
import time
Expand All @@ -20,16 +20,25 @@ def __init__(self, id: np.uint16):


class Graph:
def __init__(self, num_nodes: int):
self.num_nodes = num_nodes
def __init__(self, n: int):
self.N_num = n

_start_time = time.time()
self.nodes, self.colors, self.radius = create_nodes(num_nodes)
self.edges, self.edge_colors = create_edges(self.nodes)

start_id, end_id = np.random.randint(0, self.num_nodes, size=2, dtype=np.uint16)
self.start_node = Node(start_id)
self.end_node = Node(end_id)
# start and end nodes
start, end = np.random.randint(0, self.N_num, size=2, dtype=np.uint16)
self.start_node = Node(start)
self.end_node = Node(end)

# Node stuff
self.N = [Node(np.uint16(i)) for i in range(self.N_num)]
self.N_locs = create_nodes(self.N_num)

self.N_colors = np.full((self.N_num, 4), BLUE, dtype=np.uint8)
self.N_radii = np.full((self.N_num,), NODE_RADIUS, dtype=np.uint8)

# Edge stuff
self.edge_connections, self.edge_colors = create_edges(self.N_locs)

_end_time = time.time()
_elapsed_time = _end_time - _start_time
Expand All @@ -47,12 +56,12 @@ def moveGen(self, state: Node) -> List[Node]:
neighbors = []

id = np.uint16(0)
while id < self.num_nodes:
if [id, state.id] == 1:
while id < self.N_num:
if self.edge_connections[id, state.id] == 1:
neighbors.append(Node(id))
id += 1

print()
print()
return neighbors

def goalTest(self, state: Node) -> bool:
Expand All @@ -76,48 +85,42 @@ def create_nodes(n: int):
x_values = NODES_X_DISTRIBUTION(n)
y_values = NODES_Y_DISTRIBUTION(n)

colors = np.full((n, 4), fill_value=BLUE, dtype=np.uint8)
radii = np.full((n,), fill_value=NODE_RADIUS, dtype=np.uint8)

# generating the goal node
goal_loc = np.random.randint(0, n, 1)
colors[goal_loc] = RED
radii[goal_loc] = 3 * NODE_RADIUS
node_locs = np.column_stack((x_values, y_values))

nodes = np.column_stack((x_values, y_values))
print("✅\tFinished creating nodes!\n")

return nodes, colors, radii
return node_locs


def create_edges(nodes: np.ndarray):
"""
Creates edges for the give nodes locations
"""
# TODO: need to seperate the threading or remove the animation
global done
done = threading.Event()

dot_thread = threading.Thread(target=animate_dots)
dot_thread.start()

n = len(nodes)
edges = np.zeros((n, n))
i, j = np.triu_indices(n, k=1)
edge_connections = np.zeros((n, n))
i, j = np.triu_indices(n, k=1) # only one way edges

_toss = np.random.rand(n, n)
_confidence = np.zeros((n, n))
_confidence[i, j] = EDGE_CONFIDENCE(nodes[i], nodes[j])

# confidence number of times there will be an edge
edges = _toss <= _confidence
edge_color = (edges).astype(int)
edge_connections = _toss <= _confidence
edge_colors = np.full((n, 4), fill_value=WHITE, dtype=np.uint8)

# Stop the dot animation
done.set()
dot_thread.join() # Wait for the animation thread to finish

print("\n\tFinished creating edges!\n")
return edges, edge_color
return edge_connections, edge_colors


# for animating while the edges get created
Expand Down
4 changes: 3 additions & 1 deletion src/searchViz/Search.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from .Graph import Node

import numpy as np


class Search:
def __init__(self, search: Callable[[Node], List[Node]], name: str):
Expand All @@ -26,5 +28,5 @@ def breadth_first_search(startState: Node) -> List[Node]:


if __name__ == "__main__":
startState = Node()
startState = Node(np.uint16(1))
dfs.search(startState)
Empty file added src/searchViz/__init__.py
Empty file.
1 change: 1 addition & 0 deletions src/searchViz/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@
RED = (255, 0, 0, 255)
BLUE = (0, 255, 255, 255)
WHITE = (255, 255, 255, 200)
YELLOW = (255, 255, 153, 200)
4 changes: 3 additions & 1 deletion src/searchViz/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

import numpy as np

import numpy.typing as npt


# distribution of nodes
def nodes_dist_wrapper(length: int, model: str):
def nodes_uniform(n: int):
def nodes_uniform(n: int) -> npt.NDArray[np.float64]:
# return np.random.normal(length / 2, length / 5, n)
return np.random.uniform(0, length, n)

Expand Down
48 changes: 0 additions & 48 deletions test.py

This file was deleted.

0 comments on commit 450dab0

Please sign in to comment.