0

I am making a car traffic simulation using python. I don't know how I will add a delay on the start of each car. I need to put a delay on the start of each car every time they move after a stop or red light.

import random

class Car:
    counter = 0

    def __init__(self, position, latency, back_position, length):
        self.position = position
        self.latency = latency
        self.back_position = back_position
        self.length = length
        self.allowed_to_move = True
        Car.counter += 1
        self.name = f"car{Car.counter}"  #car namer

num_cars = int(input("How many cars do you want to generate? "))

cars = []
for i in range(num_cars):
    if i == 0:
        position = 0
    else:
        position = cars[i-1].back_position - 1

    latency = 3
    length = random.randint(3, 5)
    back_position = position - length
    car = Car(position, latency, back_position, length)
    cars.append(car)

print(f"Generated {num_cars} cars with random positions, latencies, and lengths:")
for car in cars:
    print(f"{car.name} at position {car.position} with latency {car.latency} and length {car.length}")

position = 0
timer = 0

while True:
    # Checker ng track kung lahat nakalampas na
    if all(car.position >= 100 for car in cars):
        print("All cars have reached the end of the track!")
        break

    position += 1
    timer += 1

    colors = [1] * 10 + [2] * 2 + [3] * 10 + [2] * 2
    color = colors[timer % len(colors)]
    if color == 1:
        traffic_color = "red"
    elif color == 2:
        traffic_color = "orange"
    else:
        traffic_color = "green"
    print(f"Number: {timer}, Traffic color: {traffic_color}")

    for i, car in enumerate(cars):
        if car.position >= 100:
            continue

        # Check traffic light color at kung may kotse sa harap
        if position % 10 == 0 and position != 100:
            while traffic_color != "green":
                print(f"Number: {timer}, Waiting for green light...")
                timer += 1
                color = colors[timer % len(colors)]
                if color == 1:
                    traffic_color = "red"
                elif color == 2:
                    traffic_color = "orange"
                else:
                    traffic_color = "green"
                print(f"Number: {timer}, Traffic color: {traffic_color}")

            if traffic_color == "green":
                if i == 0:
                    cars[i].allowed_to_move = True
                    cars[i+1].allowed_to_move = True
                elif i == len(cars) - 1:
                    cars[i].allowed_to_move = True
                    cars[i-1].allowed_to_move = True
                else:
                    cars[i].allowed_to_move = True
                    if cars[i-1].back_position != cars[i+1].position + 1:
                        cars[i-1].allowed_to_move = True
                        cars[i+1].allowed_to_move = True
                    else:
                        cars[i-1].allowed_to_move = False
                        cars[i+1].allowed_to_move = False
        else:
            cars[i].allowed_to_move = True

        if cars[i].allowed_to_move:
            cars[i].position += 1
            cars[i].back_position += 1
            print(f"{car.name} moved to position {car.position}")
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Eneru
  • 1

1 Answers1

0

Introducing a delay is not difficult. You can run the following program to see.
Be sure to use a terminal with a line length of more that 100 characters.
I did change a few things:

  • removal of back_position (it's easier to calculate that position)
  • time offset in traffic light sequences (it's more realistic)
  • I simplified the color handling
  • I increased the distance between traffic lights to 20 because 10 is short when car length is 3
# There are cars on a single-lane track.
# The track is 100 units long.
# There is a traffic light at each multiple of 10 units.
# There is a minimum distance of 1 unit between cars.
# When it is running, a car has a fixed speed.
# Traffic lights have a synchronized sequence but the  is a time offset for each light.
cars = [] # list of cars
tick = 0  # iteration number
nCars= 15 # number of cars 

def getLightColor( pos):
  colors = (['green']*10 + ['yellow']*2 + ['red']*10 + ['orange']*2) # color sequence for traffic light
  offsets = (0,6,12,18,24,30,36,42,48,54) # skew of sequences

  # 20 units between traffic lights
  if (pos % 20 != 0) or (pos>=100): return None # no traffic light here
  num = pos // 20 # index of traffic light
  color = colors[ (tick + offsets[num]) % len(colors)]
  return color

class Car():
  counter = 0
  def __init__( self):
    from random import randint
    self.seq = Car.counter
    self.latency = randint( 0, 2)
    self.length = randint( 1, 3)
    self.state = 'stopped' # 3 states: stopped, waiting, running
    if self.seq == 0:
      self.pos = 0
    else:
      prev = cars[self.seq-1] # get previous car
      self.pos = prev.pos - prev.length - 1 # keep 1 unit between 2 cars
    Car.counter += 1
    
  def logic( self=True):
    color = getLightColor( self.pos)
    green = color in ('green', None)

    if self.seq == 0:
      clear = True
    else:
      prev = cars[ self.seq-1]
      clear = prev.pos - prev.length - self.pos > 1 # keep 1 unit between cars

    if not (green and clear): self.state = 'stopped'
    
    elif self.state == 'running':
      self.pos += 1

    elif (self.state == 'stopped') and green:
      self.state = 'waiting'
      self.tstamp = tick

    if (self.state == 'waiting') and (tick >= (self.tstamp + self.latency)):
      self.state = 'running'

for n in range( nCars):
  car = Car()
  cars.append( car)

line1 = '|                   ' * 5
print( line1)
while cars[-1].pos < 100:   # last car ended?
  for n in range( nCars):
    cars[n].logic() # simulate
  # animate
  tb = [' '] * 100
  for car in cars:
    pos = car.pos
    if (pos >= 0) and (pos < 100):
      tb[pos] = '█'
      pos2 = pos-1
      while( pos2 >= 0) and (pos2 > (pos - car.length)):
        tb[pos2] = '▄'
        pos2 -= 1
  line2 = ''.join( tb)
  print( '\r' + line2, end='')
  import time
  time.sleep( 0.8) # slow down for animation
  tick += 1
print( f"\nDuration: {tick} ticks for {nCars} cars")

Some more improvements are possible:

  • unequal distances between traffic lights.
  • use floating-point for positions to enable finer changes in length and latency.

If you need help to improve it, just ask.

user3435121
  • 633
  • 4
  • 13