0

I'm coding a small simulation of an intersection in python and I am trying to have a graph of the number of cars in ordinate and in abscissa the time each car took to get from its starting point to its ending point.

I try to collect departure time of each car, the number of car is initialise in nb_voitures, but I end up with thousands of values whereas I just want nb_voitures values, and my code work for the list end_time but not for the list start_time and i don't understand why.

import pygame
import random
import time
import matplotlib.pyplot as plt

# Initialisation de Pygame
pygame.init()

# Dimensions de la fenêtre
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600

# Dimensions de la voie
ROAD1_WIDTH = 650
ROAD1_HEIGHT = 100

# Dimensions de la seconde voie
ROAD2_WIDTH = 400
ROAD2_HEIGHT = 100

# Dimensions de la voie à sens unique
ROAD3_WIDTH = 50
ROAD3_HEIGHT = 800

# Création de la fenêtre
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

# Définition des couleurs
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
GARDEN = (55, 210, 122)

# Classe pour représenter la voiture
class Car:
    def __init__(self, x, y, speed, direction, color):
        self.x = x
        self.y = y
        self.speed = speed
        self.direction = direction
        self.change_direction = False
        self.reached_460 = False
        self.color = color

    def move(self):
        if self.direction == "horizontal":
            self.x += self.speed
            if self.x >= 600 and not self.change_direction:
                self.direction = random.choices(["horizontal", "vertical"], weights=[0.8, 0.2])[0]
                self.change_direction = True
                if self.direction == "vertical":
                    self.speed = -self.speed
            elif self.y > 410 and self.direction == "horizontal" and self.speed < 0:
                self.y = 410
            elif self.y > 410 and self.direction == "horizontal" and not self.reached_460:
                if self.y > 460:
                    self.y = 460
                    self.reached_460 = True
                else:
                    self.y += self.speed


        elif self.direction == "vertical":
            self.y += self.speed
            if self.y >= 410 and not self.change_direction:
                self.direction = "horizontal"
                self.change_direction = True
                self.speed = random.choices([self.speed, -self.speed], weights=[0.8, 0.2])[0]


    def draw(self, surface):
        pygame.draw.rect(surface, self.color, (self.x, self.y, 30, 30))

# Création de la voiture

nb_voiture = 10

start_time = [] #stock les temps de départ de chaque voiture
end_time = [] #stock les temps d'arrivée de chaque voiture

cars = []

for i in range(nb_voiture):
    car1 = Car(0, 460, 3, "horizontal", BLUE)
    car2 = Car(560, 0, 3, "vertical", GREEN)
    cars.append(car1)
    cars.append(car2)


# Variables pour enregistrer les coordonnées des voitures
car1_x = []
car1_y = []

car2_x = []
car2_y = []

# Boucle principale
running = True
clock = pygame.time.Clock()

while running:
    #pygame.time.delay(1000) # 50ms entre chaque tours de boucles

    # Gestion des événements
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # Effacer l'écran
    win.fill(GARDEN)

    # Dessiner la voie
    pygame.draw.rect(win, BLACK, (0, 400, ROAD1_WIDTH, ROAD1_HEIGHT))
    pygame.draw.rect(win, BLACK, (550, 0, ROAD2_HEIGHT, ROAD2_WIDTH))
    pygame.draw.rect(win, BLACK, (0, 450, ROAD3_HEIGHT, ROAD3_WIDTH))
    pygame.draw.rect(win, RED, (650, 450, 10, 50))
    #pygame.draw.rect(win, RED, (100, 450, 10, 50))
    #pygame.draw.rect(win, RED, (550, 100, 50, 10))

    # Dessiner et déplacer les voitures

    t = 0

    for car in cars:
        if pygame.time.get_ticks() >= t * 500:
            car.draw(win)
            car.move()
            t += 1
        if car.direction == "vertical" and car.x == 560 and car.y == 0:
            start_time.append(pygame.time.get_ticks()) # ajout du temps de départ de chaque voiture dans start_time
        timedep=False
        if car.direction == "horizontal" and car.x == 0 and car.y == 460:
            start_time.append(pygame.time.get_ticks()) # ajout du temps de départ de chaque voiture dans start_time
        if car.direction == "horizontal" and car.x == 650 and car.y == 460:
            end_time.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time

    # Mettre à jour l'affichage
    pygame.display.update()

    # Limiter la vitesse de la boucle
    clock.tick(60)

# Quitter Pygame
pygame.quit()

print(start_time)
print(len(start_time))
print(end_time)
print(len(end_time))
Rabbid76
  • 202,892
  • 27
  • 131
  • 174

2 Answers2

1

In your example, every frame all cars that have not yet started moving, are added into the start_date. Until the car starts, it has already added hundreds values to start_date.

You can try something like this: Add started field to Car class (initialized to False) and then update it at most once per car:

for car in cars:
    if pygame.time.get_ticks() >= t * 500:
        if not car.started:
            car.started = True
            start_time.append(pygame.time.get_ticks())
        car.draw(win)
        car.move()
        t += 1
    if car.direction == "horizontal" and car.x == 650 and car.y == 460:
        end_time.append(pygame.time.get_ticks()) # ajout du temps d'arrivée de chaque voiture dans end_time
astasiak
  • 790
  • 1
  • 6
  • 13
0

Maybe my solution is not perfect, because I am not expert in pygame, but it is really simple:

...
class Car:
    def __init__(self, x, y, speed, direction, color):
        self.x = x
        self.y = y
        self.speed = speed
        self.direction = direction
        self.change_direction = False
        self.reached_460 = False
        self.color = color

        self.started: bool = False
        self.finished: bool = False
        self.time = None

    def move(self):

        if not self.started:
            self.started = True
            self.time = time.time()
        
        if (
            self.x > 650 or
            self.x < 0 or
            self.y < 0
        ) and not self.finished:
            self.finished = True
            self.time = time.time() - self.time


        if self.direction == "horizontal":
            self.x += self.speed
            ...

...
   for event in pygame.event.get():
       if event.type == pygame.QUIT:

            time_list = [x.time for x in cars if x.finished]

                running = False
...
zer0deck
  • 1
  • 2