Need help with large traffic light controller project

I am in the process of making a traffic light controller for all of my traffic lights. I have 8 total right now and getting more as I go, its a strange hobby I agree lol. I am wanting to create a typical intersection like one would see in the US. I could buy a real controller but all total its around 900 bucks and huge so I am giving this a go. I am new to the arduino world so if I don't know what I am doing or you know of a better way just tell me I would rather learn from the experts on here :)

I have a total of 4 lanes each North south East and west both sides with 2 traffic lights each some with turn arrows. Here is the code I had started its nowhere near done but I feel there is a better way of doing what I need, so any ideas should I not use all the delays? If you notice I still have more sides to build with more traffic lights on each and I am keeping them all separate so I can control timing on each side differently if needed,

/*
  Traffic Light Intersection
  Code for a 4 lane multiple traffic light intersection

  
 */
   int NdoghouseRed =12; //assign North CH dog house
   int NdoghouseYel = 11;
   int NdoghouseGrn = 10;
   int NdoghouseGrnArw = 9;
   int NdoghouseYelArw = 8;
   int N3lightRed = 7;  //assign North CH 3 light
   int N3lightYel = 6;
   int N3lightGrn = 5;
   int EdoghouseRed = 4;  //assign South 3m Doghouse
   int EdoghouseYel = 3;
   int EdoghouseGrn = 2;
   int EdoghouseGrnArw = 1;
   int EdoghouseYelArw = 0;
   int crosstime = 120000; //time for sequence
   
   void setup()  {
     pinMode (NdoghouseRed, OUTPUT);
     pinMode (NdoghouseYel, OUTPUT);
     pinMode (NdoghouseGrn, OUTPUT);
     pinMode (NdoghouseGrnArw, OUTPUT);
     pinMode (NdoghouseYelArw, OUTPUT);
     pinMode (N3lightRed, OUTPUT);
     pinMode (N3lightYel, OUTPUT);
     pinMode (N3lightGrn, OUTPUT);
     pinMode (EdoghouseRed, OUTPUT);
     pinMode (EdoghouseYel, OUTPUT);
     pinMode (EdoghouseGrn, OUTPUT);
     pinMode (EdoghouseGrnArw, OUTPUT);
     pinMode (EdoghouseYelArw, OUTPUT);
     
     //initalize the lights
     digitalWrite (NdoghouseRed, HIGH);
     digitalWrite (N3lightRed, HIGH);
     digitalWrite (EdoghouseGrn, HIGH);
     digitalWrite (EdoghouseGrnArw, HIGH);
}
  void loop()  {
    delay (15000); 
    
    digitalWrite (EdoghouseGrnArw, LOW);
    digitalWrite (EdoghouseYelArw, HIGH);
    delay (5000);
    digitalWrite (EdoghouseYelArw, LOW);
    delay (35500);
    digitalWrite (EdoghouseGrn, LOW);
    digitalWrite (EdoghouseYel, HIGH);
    delay (5000);
    digitalWrite (EdoghouseYel, LOW);
    digitalWrite (EdoghouseRed, HIGH);
    delay (2000);
    digitalWrite (NdoghouseRed, LOW);
    digitalWrite (N3lightRed, LOW);
    digitalWrite (NdoghouseGrn, HIGH);
    digitalWrite (NdoghouseGrnArw, HIGH);
    digitalWrite (N3lightGrn, HIGH);
    delay (15000);
    digitalWrite (NdoghouseGrnArw, LOW);
    digitalWrite (NdoghouseYelArw, HIGH);
    delay (5000);
    digitalWrite (NdoghouseYelArw, LOW);
    delay (35500);
    digitalWrite (NdoghouseGrn, LOW);
    digitalWrite (N3lightGrn, LOW);
    digitalWrite (NdoghouseYel, HIGH);
    digitalWrite (N3lightYel, HIGH);
    delay (5000);
    digitalWrite (NdoghouseYel, LOW);
    digitalWrite (N3lightYel, LOW);
    digitalWrite (NdoghouseRed, HIGH);
    digitalWrite (N3lightRed, HIGH);
    delay (2000);
    digitalWrite (EdoghouseRed, LOW);
    digitalWrite (EdoghouseGrn, HIGH);
    digitalWrite (EdoghouseGrnArw, HIGH);
    
}

Pins 0 and 1 are your serial pins. If you want to use the serial monitor you will need to move those lights to your analog/digital pins or any other available spots.

int EdoghouseGrnArw = 1;
   int EdoghouseYelArw = 0;

Straight out of the "blink without delay example" your delays can be removed. Define these variables:

long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
long interval = 1000; //you can define other intervals such as long interval 2,3,4,5  if you need other time choices

Put this at the top of the loop() unsigned long currentMillis = millis();

Everywhere you have a delay, replace it with this:

  if(currentMillis - previousMillis > interval) {
 ////////turn the lights off or on here////////
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

}

awesome i shall give that a try!

how does one specify multiple current mills with different lengths for each light in each section, could you give me an example?

Here are three adjustable times for events to happen. The only differences include interval(X) and previousMillis(X) so that each one has a slightly different name but, they are easy to recognized at a glance.

              long interval2 = 1000;//one second
          long interval3 = 2353; // two point three something seconds.. just a wild number to type
          long interval4 = 5000;//5 seconds

          previousMillis2 = 1000; //these 3x previousMillis variables may need adjusted to work correctly the first time through the sketch
          previousMillis3 = 2353; 
          previousMillis4 = 5000;
  if(currentMillis - previousMillis2 > interval2) {
 ////////turn the lights off or on here////////
    // save the last time you blinked the LED 
    previousMillis2 = currentMillis;   

}
  if(currentMillis - previousMillis3 > interval3) {
 ////////turn the lights off or on here////////
    // save the last time you blinked the LED 
previousMillis3 = currentMillis; 
    

}
  if(currentMillis - previousMillis4 > interval4) {
 ////////turn the lights off or on here////////
    // save the last time you blinked the LED 
previousMillis4 = currentMillis; 
     
}