import random import time import threading import pygame import sys # Default values of signal timers defaultGreen = {0: 10, 1: 10, 2: 10, 3: 10} defaultRed = 150 defaultYellow = 5 signals = [] noOfSignals = 4 currentGreen = 0 # Indicates which signal is green currently nextGreen = (currentGreen + 1) % noOfSignals # Indicates which signal will turn green next currentYellow = 0 # Indicates whether the yellow signal is on or off speeds = {'car': 2.25, 'bus': 1.8, 'truck': 1.8, 'bike': 2.5} # average speeds of vehicles # Coordinates of vehicles' start x = {'right': [0, 0, 0], 'down': [755, 727, 697], 'left': [1400, 1400, 1400], 'up': [602, 627, 657]} y = {'right': [348, 370, 398], 'down': [0, 0, 0], 'left': [498, 466, 436], 'up': [800, 800, 800]} vehicles = {'right': {0: [], 1: [], 2: [], 'crossed': 0}, 'down': {0: [], 1: [], 2: [], 'crossed': 0}, 'left': {0: [], 1: [], 2: [], 'crossed': 0}, 'up': {0: [], 1: [], 2: [], 'crossed': 0}} vehicleTypes = {0: 'car', 1: 'bus', 2: 'truck', 3: 'bike'} directionNumbers = {0: 'right', 1: 'down', 2: 'left', 3: 'up'} # Coordinates of signal image, timer, and vehicle count signalCoods = [(530, 230), (810, 230), (810, 570), (530, 570)] signalTimerCoods = [(530, 210), (810, 210), (810, 550), (530, 550)] # Coordinates of stop lines stopLines = {'right': 590, 'down': 330, 'left': 800, 'up': 535} defaultStop = {'right': 580, 'down': 320, 'left': 810, 'up': 545} pygame.init() simulation = pygame.sprite.Group() class TrafficSignal: def __init__(self, red, yellow, green): self.red = red self.yellow = yellow self.green = green self.signalText = "" class Vehicle(pygame.sprite.Sprite): def __init__(self, lane, vehicleClass, direction_number, direction): pygame.sprite.Sprite.__init__(self) self.lane = lane self.vehicleClass = vehicleClass self.speed = speeds[vehicleClass] self.direction_number = direction_number self.direction = direction self.x = x[direction][lane] self.y = y[direction][lane] self.crossed = 0 vehicles[direction][lane].append(self) self.index = len(vehicles[direction][lane]) - 1 path = "images/" + direction + "/" + vehicleClass + ".png" self.image = pygame.image.load(path) if (len(vehicles[direction][lane]) > 1 and vehicles[direction][lane][self.index - 1].crossed == 0): if (direction == 'right'): self.stop = vehicles[direction][lane][self.index - 1].stop - \ vehicles[direction][lane][self.index - 1].image.get_rect().width - stoppingGap elif (direction == 'left'): self.stop = vehicles[direction][lane][self.index - 1].stop + \ vehicles[direction][lane][self.index - 1].image.get_rect().width + stoppingGap elif (direction == 'down'): self.stop = vehicles[direction][lane][self.index - 1].stop - \ vehicles[direction][lane][self.index - 1].image.get_rect().height - stoppingGap elif (direction == 'up'): self.stop = vehicles[direction][lane][self.index - 1].stop + \ vehicles[direction][lane][self.index - 1].image.get_rect().height + stoppingGap else: self.stop = defaultStop[direction] if (direction == 'right'): temp = self.image.get_rect().width + stoppingGap x[direction][lane] -= temp elif (direction == 'left'): temp = self.image.get_rect().width + stoppingGap x[direction][lane] += temp elif (direction == 'down'): temp = self.image.get_rect().height + stoppingGap y[direction][lane] -= temp elif (direction == 'up'): temp = self.image.get_rect().height + stoppingGap y[direction][lane] += temp simulation.add(self) def render(self, screen): screen.blit(self.image, (self.x, self.y)) def move(self): if (self.direction == 'right'): if (self.crossed == 0 and self.x + self.image.get_rect().width > stopLines[self.direction]): self.crossed = 1 if ((self.x + self.image.get_rect().width <= self.stop or self.crossed == 1 or ( currentGreen == 0 and currentYellow == 0)) and ( self.index == 0 or self.x + self.image.get_rect().width < ( vehicles[self.direction][self.lane][self.index - 1].x - movingGap))): self.x += self.speed elif (self.directi 'down'): if (self.crossed == 0 and self.y + self.image.get_rect().height > stopLines[self.direction]): self.crossed = 1 if ((self.y + self.image.get_rect().height <= self.stop or self.crossed == 1 or ( currentGreen == 1 and currentYellow == 0)) and ( self.index == 0 or self.y + self.image.get_rect().height < ( vehicles[self.direction][self.lane][self.index - 1].y - movingGap))): self.y += self.speed elif (self.directi 'left'): if (self.crossed == 0 and self.x < stopLines[self.direction]): self.crossed = 1 if ((self.x >= self.stop or self.crossed == 1 or (currentGreen == 2 and currentYellow == 0)) and ( self.index == 0 or self.x > ( vehicles[self.direction][self.lane][self.index - 1].x + vehicles[self.direction][self.lane][ self.index - 1].image.get_rect().width + movingGap))): self.x -= self.speed elif (self.direction == 'up'): if (self.crossed == 0 and self.y < stopLines[self.direction]): self.crossed = 1 if ((self.y >= self.stop or self.crossed == 1 or (currentGreen == 3 and currentYellow == 0)) and ( self.index == 0 or self.y > ( vehicles[self.direction][self.lane][self.index - 1].y + vehicles[self.direction][self.lane][ self.index - 1].image.get_rect().height + movingGap))): self.y -= self.speed # Initialization of signals with default values def initialize(): ts1 = TrafficSignal(0, defaultYellow, defaultGreen[0]) signals.append(ts1) ts2 = TrafficSignal(ts1.red + ts1.yellow + ts1.green, defaultYellow, defaultGreen[1]) signals.append(ts2) ts3 = TrafficSignal(defaultRed, defaultYellow, defaultGreen[2]) signals.append(ts3) ts4 = TrafficSignal(defaultRed, defaultYellow, defaultGreen[3]) signals.append(ts4) repeat() def repeat(): global currentGreen, currentYellow, nextGreen while (signals[currentGreen].green > 0): updateValues() time.sleep(1) currentYellow = 1 for i in range(0, 3): for vehicle in vehicles[directionNumbers[currentGreen]][i]: vehicle.stop = defaultStop[directionNumbers[currentGreen]] while (signals[currentGreen].yellow > 0): updateValues() time.sleep(1) currentYellow = 0 signals[currentGreen].green = defaultGreen[currentGreen] signals[currentGreen].yellow = defaultYellow signals[currentGreen].red = defaultRed currentGreen = nextGreen nextGreen = (currentGreen + 1) % noOfSignals signals[nextGreen].red = signals[currentGreen].yellow + signals[currentGreen].green repeat() def updateValues(): for i in range(0, noOfSignals): if (i == currentGreen): if (currentYellow == 0): signals[i].green -= 1 else: signals[i].yellow -= 1 else: signals[i].red -= 1 def generateVehicles(): while True: vehicle_type = random.randint(0, 3) lane_number = random.randint(1, 2) temp = random.randint(0, 99) direction_number = 0 dist = [25, 50, 75, 100] if temp < dist[0]: directi elif temp < dist[1]: directi elif temp < dist[2]: directi elif temp < dist[3]: directi Vehicle(lane_number, vehicleTypes[vehicle_type], direction_number, directionNumbers[direction_number]) time.sleep(1) class Main: thread1 = threading.Thread(name="initialization", target=initialize, args=()) thread1.daem thread1.start() # Colors black = (0, 0, 0) white = (255, 255, 255) # Screen size screenWidth = 1400 screenHeight = 800 screenSize = (screenWidth, screenHeight) # Setting background image i.e. image of the intersection background = pygame.image.load('images/intersection.png') screen = pygame.display.set_mode(screenSize) pygame.display.set_caption("SIMULATION") # Loading signal images and font redSignal = pygame.image.load('images/signals/red.png') yellowSignal = pygame.image.load('images/signals/yellow.png') greenSignal = pygame.image.load('images/signals/green.png') f 30) thread2 = threading.Thread(name="generateVehicles", target=generateVehicles, args=()) thread2.daem thread2.start() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.blit(background, (0, 0)) for i in range(0, noOfSignals): if (i == currentGreen): if (currentYellow == 1): signals[i].signalText = signals[i].yellow screen.blit(yellowSignal, signalCoods[i]) else: signals[i].signalText = signals[i].green screen.blit(greenSignal, signalCoods[i]) else: if (signals[i].red <= 10): signals[i].signalText = signals[i].red else: signals[i].signalText = "---" screen.blit(redSignal, signalCoods[i]) signalTexts = ["", "", "", ""] for i in range(0, noOfSignals): signalTexts[i] = font.render(str(signals[i].signalText), True, white, black) screen.blit(signalTexts[i], signalTimerCoods[i]) for vehicle in simulation: screen.blit(vehicle.image, [vehicle.x, vehicle.y]) vehicle.move() pygame.display.update() Main()