/* Constructs a Trains object and triggers simulation */ private void StartSimulation() { /* Constructing a Train object for simulating */ Trains train = new Trains(m, n, vM); SignalConsole.Text = ""; InfoConsole.AppendText("\r\nSignalling Simulation Started!\r\n"); ExpectedTimeLabel.Text = (totalTime / 3600).ToString("00") + ":" + ((totalTime / 60) % 60).ToString("00") + ":" + (totalTime % 60).ToString("00"); /* Constructing a Timer to run the simulator every second */ System.Timers.Timer timer2 = new System.Timers.Timer(intTimer); timer2.Elapsed += (sender, e) => TickEvent2(train, sender, e); timer2.Enabled = true; }
/* Handler for Timer tick event */ private void TickEvent2(Trains train, object sender, ElapsedEventArgs e) { currentTime = e.SignalTime.ToString("HH:mm:ss"); System.Timers.Timer timer = (System.Timers.Timer)sender; counter++; UpdateProgressBar(); if (stop == true) { timer.Stop(); InfoConsole.AppendText("\r\n\r\nSignalling Simulation Stopped!"); train.PrintOnStop(m, this); Stop.Enabled = false; UpdateControls(true); } if (stop == false) { train.Simulate(m, n, counter, gap, currentTime, train, speedTimer, this, vM, vR, sD); finished = train.Finished(m, n, sD); crashed = train.Crashed(m, n, this, sD); /* If the simulation finishes */ if (finished) { timer.Stop(); train.PrintTime(m, this); Stop.Enabled = false; UpdateControls(true); } /* If the simulation fails due to a crash between trains */ if (crashed) { timer.Stop(); Console.Beep(); train.PrintOnStop(m, this); Stop.Enabled = false; UpdateControls(true); } } }
/* Method to perform the simulation */ public void Simulate(int m, int n, int counter, int gap, string currentTime, Trains train, int speedTimer, Form1 form, double vM, double vR, double sD) { double p = 0; Form1 form1 = form; PrintCurrentTime(form1); PrintElapsedTime(form1, counter); /* If the train at the front finishes */ try { if (distance[tc] >= (sD * (n + 1))) { tc = tc + 1; start = start + 1; var = 0; UpdateInfoConsole(form1, "\r\nTrain " + (tc + 1) + " covered the stretch."); } } catch (Exception e) { Console.Beep(); UpdateInfoConsole(form1, "\r\n\r\nError ! : " + e.Message); } /* All the signals ahead of the train at the front are given Proceed */ try { int u = (int)(distance[tc] / sD); for (int i = u; i < n; i++) { signal[i] = 3; } } catch (Exception e) { Console.Beep(); UpdateInfoConsole(form1, "\r\n\r\nError ! : " + e.Message); } /* Speed, Time and Distance Calculation for the train at the front and not yet finished */ if (distance[tc] <= (sD * (n + 1))) { /* If the train at the train has just become the train at the front and its velocity is not 60 km/hr */ if (velocity[tc] != vM) { if (var == 0) { v = velocity[tc]; t = (int)((3600 * 2 * sD) / (v + vM)); count[tc] = 0; var++; } if (count[tc] != t) { velocity[tc] = velocity[tc] + (((vM - v) * (vM + v)) / (double)(7200 * sD)); s[tc] = (velocity[tc] / 3600) + (((vM - v) * (vM + v)) / (double)(sD * 7200 * 3600)); distance[tc] = distance[tc] + s[tc]; time[tc] = time[tc] + 1; count[tc]++; } if (count[tc] == t) { velocity[tc] = vM; } } /* If the velocity is or has become 60 km/hr */ if (velocity[tc] == vM) { for (int j = 1; j <= n; j++) { if (Math.Abs((sD * j) - distance[tc]) < 0.007) { UpdateInfoConsole(form1, "\r\nTrain " + (tc + 1) + " just passed Signal " + (j) + " with a speed of " + (velocity[tc]) + " km/hr."); } } distance[tc] = distance[tc] + (velocity[tc] / 3600); time[tc] = time[tc] + 1; } } /* For making trains enter the stretch after every 'user input' number of seconds later */ if ((counter % (gap + 1)) == 0) { if (temp < m) { temp++; UpdateInfoConsole(form1, "\r\nTrain " + (temp) + " just entered the stretch."); } } /* Speed, Time and Distance calculation for all trains leaving the train at the front */ for (int i = start; i < temp; i++) { hasReached[i] = 0; for (int j = 1; j <= n; j++) { /* Checking if the train reaches any signal */ if (Math.Abs((sD * j) - distance[i]) < 0.007) { sg[i] = j; hasReached[i] = 1; /* Calculating distance of the train from the train ahead of it */ p = distance[i - 1] - distance[i]; /* Cases depending on the gap between the two trains */ if (p > 0 && p < sD) { try { signal[j - 1] = 0; } catch (Exception e) { UpdateInfoConsole(form1, "\nError! : " + e.Message); } } if (p > sD && p < (sD * 2)) { /* If the train ahead completed the track */ if (j == n) { signal[j - 1] = 3; } else { try { signal[j - 1] = 1; signal[j] = 0; } catch (Exception e) { UpdateInfoConsole(form1, "\nError! : " + e.Message); } } } if (p > (sD * 2) && p < (sD * 3)) { /* If the train ahead completed the track */ if (j == (n - 1)) { signal[n - 2] = 3; signal[n - 1] = 3; } else { try { signal[j - 1] = 2; signal[j] = 1; signal[j + 1] = 0; } catch (Exception e) { UpdateInfoConsole(form1, "\nError! : " + e.Message); } } } if (p > (sD * 3)) { int k = (int)(distance[i - 1] / sD); try { /* If the train ahead completed the track */ if (k == (n + 1)) { for (int l = j - 1; l < k - 1; l++) { signal[l] = 3; } } else { signal[k - 1] = 0; signal[k - 2] = 1; signal[k - 3] = 2; for (int l = k - 4; l >= j - 1; l--) { signal[l] = 3; } } } catch (Exception e) { UpdateInfoConsole(form1, "\nError! : " + e.Message); } } /* Attention and velocity = vM km/hr */ if (signal[j - 1] == 2 && (vM - velocity[i]) < 0.21) { count[i] = 0; flag[i] = 1; special[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vR - vM) * (vR + vM) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vR - vM) * (vR + vM) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now decrease from " + vM + " km/hr to " + vR + " km/hr in the next " + sD + " kms."); } /* Attention and velocity = vR km/hr */ if (signal[j - 1] == 2 && velocity[i] < (vR + 1) && (vR - velocity[i]) < 0.11) { count[i] = 0; flag[i] = 2; special[i] = 0; time[i] = time[i] + 1; count[i]++; s[i] = (velocity[i] / 3600); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now remain constant at " + vR + " km/hr for the next " + sD + " kms."); } /* Attention and velocity = 0 km/hr */ if (signal[j - 1] == 2 && (velocity[i] - 0) < 0.11) { count[i] = 0; special[i] = 1; flag[i] = 5; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vR * vR) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vR * vR) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now increase from 0 km/hr to " + vR + " km/hr in the next " + sD + " kms."); } /* Caution and velocity = vM km/hr */ if (signal[j - 1] == 1 && (vM - velocity[i]) < 0.021) { count[i] = 0; flag[i] = 3; special[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] - ((double)(vM * vM) / (7200 * sD)); s[i] = (velocity[i] / 3600) - ((double)(vM * vM) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now decrease from " + vM + " km/hr to 0 km/hr in the next " + sD + " kms."); } /* Caution and velocity = vR km/hr */ if (signal[j - 1] == 1 && velocity[i] < (vR + 1) && (vR - velocity[i]) < 0.11) { count[i] = 0; flag[i] = 4; special[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] - ((double)(vR * vR) / (7200 * sD)); s[i] = (velocity[i] / 3600) - ((double)(vR * vR) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now decrease from " + vR + " km/hr to 0 km/hr in the next " + sD + " kms."); } /* Caution and velocity = 0 km/hr */ if (signal[j - 1] == 1 && (velocity[i] - 0) < 0.11) { count[i] = 0; special[i] = 1; flag[i] = 5; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vR * vR) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vR * vR) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now increase from 0 km/hr to " + vR + " km/hr in the next " + sD + " kms."); } /* Proceed and velocity = vM km/hr */ if (signal[j - 1] == 3 && (vM - velocity[i]) < 0.021) { count[i] = 0; flag[i] = 6; special[i] = 0; time[i] = time[i] + 1; count[i]++; s[i] = (velocity[i] / 3600); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now remain constant at " + vM + " km/hr for the next " + sD + " kms."); } /* Proceed and velocity = vR km/hr */ if (signal[j - 1] == 3 && velocity[i] < (vR + 1) && (vR - velocity[i]) < 0.11) { count[i] = 0; flag[i] = 7; special[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vM - vR) * (vR + vM) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vM - vR) * (vR + vM) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now increase from " + vR + " km/hr to " + vM + " km/hr in the next " + sD + " kms."); } /* Proceed and velocity = 0 km/hr */ if (signal[j - 1] == 3 && (velocity[i] - 0) < 0.11) { count[i] = 0; special[i] = 1; flag[i] = 5; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vR * vR) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vR * vR) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now increase from 0 km/hr to " + vM + " km/hr in the next " + sD + " kms."); } /* Stop and velocity = vM km/hr */ if (signal[j - 1] == 0 && (vM - velocity[i]) < 0.021) { count[i] = 0; flag[i] = 8; special[i] = 0; d[i] = p; fs[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] - ((double)(vM * vM) / (7200 * p)); s[i] = (velocity[i] / 3600) - ((double)(vM * vM) / (p * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + " and Train " + (i) + " are on the same block section."); UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now decrease from " + (velocity[i]) + " km/hr to 0 km/hr in the next " + (p) + " kms and will wait for 1 minute."); } /* Stop and velocity = vR km/hr */ if (signal[j - 1] == 0 && velocity[i] < (vR + 1) && (vR - velocity[i]) < 1) { count[i] = 0; flag[i] = 9; special[i] = 0; d[i] = p; fs[i] = 0; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] - ((double)(vR * vR) / (7200 * p)); s[i] = (velocity[i] / 3600) - ((double)(vR * vR) / (p * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + " and Train " + (i) + " are on the same block section."); UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now decrease from " + (velocity[i]) + " km/hr to 0 km/hr in the next " + (p) + " kms and will wait for 1 minute."); } /* Stop and velocity = 0 km/hr */ if (signal[j - 1] == 0 && (velocity[i] - 0) < 0.11) { count[i] = 0; special[i] = 1; flag[i] = 5; time[i] = time[i] + 1; count[i]++; velocity[i] = velocity[i] + ((double)(vR * vR) / (7200 * sD)); s[i] = (velocity[i] / 3600) + ((double)(vR * vR) / (sD * 7200 * 7200)); distance[i] = distance[i] + s[i]; UpdateInfoConsole(form1, "\r\nTrain " + (i + 1) + "'s speed will now increase from 0 km/hr to " + vR + " km/hr in the next " + sD + " kms."); } if (special[i] == 1) { Increment(i, vM, vR, sD); } } } if (hasReached[i] == 0) { Increment(i, vM, vR, sD); } } if ((counter % speedTimer) == 0) { PrintSignals(n, form1); PrintParameters(m, form1); } }