compsci-assesment/main.py
casualhonk d455b8230f extremely struggling to make them queue at lights
Signed-off-by: casualhonk <casualhonk@Tomoe.nya>
2026-02-20 22:16:15 +11:00

219 lines
No EOL
5.5 KiB
Python

import random
import pygame
import sys
pygame.init()
# Window Setup
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Traffic Simulation")
FPS = 60
clock = pygame.time.Clock()
# Colours
ROAD = (60, 60, 60)
CAR = (200, 40, 40)
GREEN = (0, 200, 0)
YELLOW= (255, 180, 0)
RED = (200, 0, 0)
WHITE = (255, 255, 255)
UI_BG = (30, 30, 30)
#Classes
#Traffic Light Class
class TrafficLight:
def __init__(self, x, y):
self.x = x
self.y = y
self.states = ["green", "yellow", "red"]
self.current = "green"
self.timer = 0
self.cycle_time = 120
def update(self):
self.timer += 1
if self.timer > self.cycle_time:
self.timer = 0
idx = self.states.index(self.current)
self.current = self.states[(idx +1) % 3]
def draw(self, surf):
colour = GREEN if self.current == "green" else YELLOW if self.current == "yellow" else RED
pygame.draw.circle(surf, colour, (self.x, self.y), 12)
#Vehicle Class
class Vehicle:
def __init__(self, x, y, speed=2):
self.x = x
self.y = y
self.speed = speed
self.wait = 0
def update(self, lights, vehicles):
#check if car/light ahead
for other in vehicles:
if other is self:
continue
if abs(self.x - other.x) < 5:
if other.y > self.y:
dist = other.y - self.y
if dist < 60:
return # too close back up
for light in lights:
if abs(self.x - light.x) < 10:
if self.y < light.y < self.y + 40:
if light.current != "green":
return
self.y += self.speed
def draw(self, surf):
pygame.draw.rect(surf, CAR, (self.x - 10, self.y - 20, 20, 40))
#sim state
vehicles = []
lights = []
intersections = []
spawn_timer = 0
SPAWN_RATE = 60 #every second spawn one
placing_mode = "intersection"
#loop
running = True
while running:
clock.tick(FPS)
screen.fill((40, 140, 40))
#event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
mx, my = pygame.mouse.get_pos()
if event.button == 1:
if mx < 800: #sim area
if placing_mode == "intersection":
intersections.append((mx, my))
elif placing_mode == "light":
lights.append(TrafficLight(mx, my))
if event.type == pygame.MOUSEBUTTONDOWN:
mx, my = pygame.mouse.get_pos()
if placing_mode == "remove" and event.button == 1:
DEL_RADIUS = 25
intersections = [
(x, y) for (x, y) in intersections
if (mx - x) ** 2 + (my - y) ** 2 > DEL_RADIUS ** 2
]
lights = [
light for light in lights
if (mx - light.x) ** 2 + (my - light.y) ** 2 > DEL_RADIUS ** 2
]
# if event.type == pygame.MOUSEBUTTONDOWN: #delete things
# mx, my = pygame.mouse.get_pos()
# if event.button == 3: # right mouse
# if placing_mode == "intersection":
# #remove within 20px
# intersections = [
# (x, y) for (x, y) in intersections if not (abs(mx - x) < 20 and abs(my - y) < 20)
# ]
# if placing_mode == "light":
# lights = [
# light for light in lights if not (abs(mx - light.x) < 20 and abs(my - light.y) < 20)
# ]
#switch placing mode
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
placing_mode = "intersection"
if event.key == pygame.K_2:
placing_mode = "light"
if event.key == pygame.K_3:
placing_mode = "remove"
#roads
pygame.draw.rect(screen, ROAD, (380, 0, 240, HEIGHT))
#veichles
spawn_timer += 1
if spawn_timer > SPAWN_RATE:
spawn_timer = 0
vehicles.append(Vehicle(500, -20))
#update lights
for light in lights:
light.update()
light.draw(screen)
vehicles.sort(key=lambda v: v.y)
#update vehicles
for v in vehicles:
v.update(lights, vehicles)
v.draw(screen)
#remove dem
vehicles = [v for v in vehicles if v.y < HEIGHT + 50]
#draw intersections
for x, y in intersections:
pygame.draw.rect(screen, WHITE, (x - 20, y - 20, 40, 40), 2)
#ui
pygame.draw.rect(screen, UI_BG, (800, 0, 200, HEIGHT))
font = pygame.font.SysFont(None, 28)
# circle wowwwwww so prettyyy
if placing_mode == "remove":
mx, my = pygame.mouse.get_pos()
pygame.draw.circle(screen, RED, (mx, my), 25, 2, )
ui_text = [
"Placement Mode:",
f"{placing_mode.upper()}",
"",
"Press 1: Intersection",
"Press 2: Traffic Light",
"Press 3: Remove Tool",
"",
f"Cars: {len(vehicles)}",
f"Lights: {len(lights)}",
f"Intersections: {len(intersections)}",
]
y_offset = 20
for line in ui_text:
txt = font.render(line, True, WHITE)
screen.blit(txt, (820, y_offset))
y_offset += 30
pygame.display.flip()