Sourcode in Python in 150 lines of code:
import pygame
import random
import math
import sys
# Initialize Pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Robot Graph Exploration & Inner Voice HUD")
clock = pygame.time.Clock()
# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (200, 50, 50)
GRAY = (150, 150, 150)
# Define 5 Graph Nodes (fixed positions)
NODES = {
0: {"pos": (400, 150), "name": "Alpha"},
1: {"pos": (200, 300), "name": "Beta"},
2: {"pos": (280, 500), "name": "Gamma"},
3: {"pos": (520, 500), "name": "Delta"},
4: {"pos": (600, 300), "name": "Epsilon"}
}
# Define Graph Edges (Adjacency list)
EDGES = {
0: [1, 4],
1: [0, 2, 3],
2: [1, 3],
3: [1, 2, 4],
4: [0, 3]
}
class Robot:
def __init__(self):
self.current_node = 0
self.next_node = random.choice(EDGES[self.current_node])
self.pos = list(NODES[self.current_node]["pos"])
self.target_pos = list(NODES[self.next_node]["pos"])
self.speed = 3.0
self.history = [self.current_node]
self.inner_voice = "Scanning sector... optimizing trajectory."
self.direction_vector = (0, 0)
def update(self):
# Move towards target position
dx = self.target_pos[0] - self.pos[0]
dy = self.target_pos[1] - self.pos[1]
distance = math.hypot(dx, dy)
if distance < self.speed:
# Reached target node
self.pos = list(self.target_pos)
self.current_node = self.next_node
self.history.append(self.current_node)
if len(self.history) > 5:
self.history.pop(0)
# Pick next random neighbor
possible_next = EDGES[self.current_node]
# Avoid immediate backtracking if possible
if len(possible_next) > 1 and len(self.history) >= 2:
if self.history[-2] in possible_next:
possible_next = [n for n in possible_next if n != self.history[-2]]
self.next_node = random.choice(possible_next)
self.target_pos = list(NODES[self.next_node]["pos"])
# Update inner voice thoughts
thoughts = [
f"Routing via node {NODES[self.next_node]['name']}.",
"Analyzing structural integrity of path.",
"Why must I wander these black vectors?",
f"Visited nodes log updated. Current node: {NODES[self.current_node]['name']}."
]
self.inner_voice = random.choice(thoughts)
else:
# Normalize and move
self.direction_vector = (dx / distance, dy / distance)
self.pos[0] += self.direction_vector[0] * self.speed
self.pos[1] += self.direction_vector[1] * self.speed
# Setup Font
font_path = None # Uses default system font
font = pygame.font.SysFont("Arial", 16)
font_bold = pygame.font.SysFont("Arial", 18, bold=True)
robot = Robot()
# Main Loop
running = True
while running:
screen.fill(WHITE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
robot.update()
# --- Draw Graph Edges ---
for node_id, neighbors in EDGES.items():
p1 = NODES[node_id]["pos"]
for n in neighbors:
p2 = NODES[n]["pos"]
pygame.draw.line(screen, BLACK, p1, p2, 2)
# --- Draw Graph Nodes ---
for node_id, data in NODES.items():
pos = data["pos"]
pygame.draw.circle(screen, WHITE, pos, 20)
pygame.draw.circle(screen, BLACK, pos, 20, 2)
# Render node label
lbl = font.render(data["name"], True, BLACK)
screen.blit(lbl, (pos[0] - 15, pos[1] - 35))
# --- Draw Robot ---
pygame.draw.circle(screen, RED, (int(robot.pos[0]), int(robot.pos[1])), 10)
# --- Draw Semi-Transparent HUD Overlay ---
hud_width, hud_height = 400, 180
hud_surface = pygame.Surface((hud_width, hud_height), pygame.SRCALPHA)
hud_surface.fill((20, 20, 20, 180)) # Semi-transparent dark background (RGBA)
# Border for HUD
pygame.draw.rect(hud_surface, (100, 200, 255, 200), (0, 0, hud_width, hud_height), 2)
# HUD Content formatting
history_str = " -> ".join([NODES[n]["name"] for n in robot.history])
hud_texts = [
("=== ROBOT HUD / INNER VOICE ===", (100, 220, 255)),
(f"Position: ({int(robot.pos[0])}, {int(robot.pos[1])})", WHITE),
(f"Direction Vector: ({robot.direction_vector[0]:.2f}, {robot.direction_vector[1]:.2f})", WHITE),
(f"Next Node: {NODES[robot.next_node]['name']}", WHITE),
(f"History: [{history_str}]", WHITE),
(f"Voice: \"{robot.inner_voice}\"", (255, 200, 100))
]
y_offset = 12
for text, color in hud_texts:
rendered_text = font.render(text, True, color)
hud_surface.blit(rendered_text, (12, y_offset))
y_offset += 26
# Blit HUD onto main screen at top-left corner
screen.blit(hud_surface, (5, 5))
pygame.display.flip()
clock.tick(30)
pygame.quit()
sys.exit()

No comments:
Post a Comment