• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Programmierwettbewerb: Ampelschaltung

epiphora

aus Plastik
Veteran

Registriert
14 Juli 2013
Beiträge
3.894
Ort
DE-CIX
@theSplit: Sehe ich das richtig, das deine Ampeln jeweils eigene Timer haben, seperat von der Ampelschaltung? Das wäre ja mal ein interessanter Ansatz, aber in der Realität nicht ungefährlich. :D Hab Deinen Code aber auch nur kurz überflogen, muss ich zugeben! :)

@KaPiTN: Wow, das sieht wirklich beeindruckend aus! Bin sehr gespannt auf Deinen Code!
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@epiphora:

Moin, ja das stimmt - die Ampeln teilen sich nicht eine Schaltung, sondern jede Ampel hat eine eigene Phasenzeit und Wartezeit (nur alle initialisiert mit den gleichen Werten) :D
Wobei die Logik ob die Straße auch wirklich freigegeben wird sich an der gerade aktiven Ampel bemisst. Wenn für selbige die "Phase_Rot-Zusatz" Zeit abgelaufen ist, gibt die Ampel die Straße für die anderen Ampeln frei bzw. wird auf eine Ampel mit höherer Priorität zu wechseln erlaubt - die zwei "if" Abfragen im "Logik"-Bereich überprüfen das, Zeile 176 bis 188 in der Version ohne SDL und Zeile 209 (aktiveAmpel = -1).

Wenn die Ampel ausfallen würde, und die Straßen gesperrt bleiben weil diese nicht freigibt, wäre das allerdings fatal :)
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
TrafficLightControlledCrossroads.exe in C# hat 29KB


[X] alle 4 Ampeln schalten in regelmäßigen Abständen lt. normalen Verkehrsregeln
[X] Die Ampel verhält sich wie eine "offizielle" Ampel (unterschiedliches Timing für die einzelnen Phasen)
[_] Eine oder mehrere Ampel-Lampen können kaputt gehen, je nach Defekt wird "irgendwie" darauf reagiert (seid Kreativ) es darf nur kein Unfall passieren können.
[_] Autos fahren in regelmäßigen Abständen über die Kreuzung und fahren jeweils nur gerade aus.
[_] Autos fahren in regelmäßigen Abständen über die Kreuzung und biegen ab und an rechts ab.
[X] Autos fahren in unregelmäßigen Abständen über die Kreuzung und biegen auch(KaPiTn) rechts und links ab.
[X] Autos fahren in zufälligen Abständen und zufälligen Fluss-raten über die Kreuzung, die Ampeln reagieren darauf und schalten unterschiedlich lange Grün-Phasen
[X] Kollisionserkennung, 2 Autos dürfen keinen "Unfall" bauen und biegen nur ab, insofern genug Platz frei ist. Bis zu diesem Schwierigkeit-Grad dürfen sich Autos auch überlappen.

Dadurch, daß die Kommentare in deutsch sein sollen, ist die Beschreibung in der Doku/Kommentare bei mir nicht ganz stringent, da die Bezeichner englisch sind, die Begriffe der Kreuzung aber manchmal bei der Erklärung auf deutsch verwendet werden. So sind manchmal englische Begriffe, dann aber wieder die deutsche Entsprechung verwendet worden. Das stört mich persönlich etwas, aber es sollte die Verständlichkeit erhöhen.

Die Dokumentation findet sich hier (PW: ngb.to) : Download TrafficLightControlledCrossroadsDokumentation.rar



Brick:
[src=csharp]using System.Drawing;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Brick ist das Element, aus dem sich Road zusammensetzt
/// </summary>
public class Brick
{

/// <summary>
/// Abfrage der Koordinate der linken oberen Ecke
/// </summary>
/// <value>
/// Koordinate der linken oberen Ecke
/// </value>
public Point Location { get; private set; }


/// <summary>
/// Abfrage der Kantenlänge
/// </summary>
/// <value>
/// Kantenlänge
/// </value>
public int Edge { get; private set; }

/// <summary>
/// Setzen oder Holen eines Autos
/// </summary>
/// <value>
/// Ein Auto
/// </value>
public Car Car { get; set; }

/// <summary>
/// Ein Element der Straße
/// </summary>
/// <param name="location">Koordinate der linken oberen Ecke des Brick</param>
/// <param name="edge">Kantenlänge</param>
public Brick(Point location, int edge)
{
Location = location;
Edge = edge;
}

/// <summary>
/// Initialisiert eine neue Instanz von <see cref="Brick"/> class.
/// </summary>
/// <param name="location">Koordinaten der linken oberen Ecke des Steins.</param>
/// <param name="edge">Kantenlänge des Steins</param>
/// <param name="car">Das Auto, welches sich auf diesem Stein befindet</param>
public Brick(Point location, int edge, Car car)
{
Location = location;
Edge = edge;
Car = car;
}

}
}[/src]

Car
[src=csharp]using System.Drawing;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Die Klasse für das Auto, mit den Eigenschaften Farbe, Richtung nach der Kreuzung und Bewegungszustand
/// </summary>
public class Car
{
/// <summary>
/// Setzt oder liest die Farbe
/// </summary>
/// <value>
/// Die Farbe
/// </value>
public Color Color { get; private set; }

/// <summary>
/// Seztt oder list einen Wert , der angibt ob <see cref="Car"/> still steht
/// </summary>
/// <value>
/// <c>true</c> wenn stopped; ansonsten, <c>false</c>.
/// </value>
public bool Stopped { get; set; }

/// <summary>
/// Setzt oder liest die Fahrtrichtung
/// </summary>
/// <value>
/// Fahrrichtung
/// </value>
public Destination Destination { get; set; }

/// <summary>
/// Initialisiert eine neue Instanz von<see cref="Car"/> class.
/// qKonstruktor: Ein neues Auto bewegt sich nicht. Es bekommt eine Zufällige Farbe und die geplante
/// Fahrtrichtung an der Kreuzung wird zufällig ausgewählt.
/// </summary>
public Car()
{
Stopped = false;
CreateDestination();
CreateColor();
}

/// <summary>
/// generiert zufällig eine von 4 Lackfarben
/// </summary>
private void CreateColor()
{
int rnd = TlccRandom.GenerateRandomNumber(0, 4);
Color = TlccColors.Colors[rnd];
}

/// <summary>
/// legt die Richtung nach der Kreuzung für das Auto fest
/// </summary>
private void CreateDestination()
{
int rnd = TlccRandom.GenerateRandomNumber(0, 7);

if (rnd == 0) Destination = Destination.Left;

if (rnd > 0 && rnd < 3) Destination = Destination.Right;

if (rnd > 3) Destination = Destination.Straight;
}
}
}[/src]


CrossRoadField
[src=csharp]using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace TrafficLightControlledCrossroads
{
internal class CrossRoadField
{
private Road _northRoad;
private Road _southRoad;
private Road _eastRoad;
private Road _westRoad;
private const int BrickSize = 15;
private const int TurnRightBrickIndex = 20;
private const int TurnLeftBrickIndex = 21;
private readonly List<TrafficLight> _trafficLights = new List<TrafficLight>();

/// <summary>
/// Gibt die NorthRoad zurück.
/// </summary>
/// <value>
/// Die NorthRoad
/// </value>
public Road NorthRoad
{
get { return _northRoad; }
}

/// <summary>
///Gibt die SouthRoad zurück.
/// </summary>
/// <value>
/// Die SouthRoad
/// </value>
public Road SouthRoad
{
get { return _southRoad; }
}

/// <summary>
/// Gibt die WestRoad zurück.
/// </summary>
/// <value>
/// Die WestRoad
/// </value>
public Road WestRoad
{
get { return _westRoad; }
}

/// <summary>
/// Gibt die EastRoad zurück.
/// </summary>
/// <value>
/// Die EastRoad
/// </value>
public Road EastRoad
{
get { return _eastRoad; }
}

public List<TrafficLight> TrafficLights
{
get { return _trafficLights; }
}

private TrafficLight _trafficLightNorthDirection;
private TrafficLight _trafficLightSouthDirection;
private TrafficLight _trafficLightWestDirection;
private TrafficLight _trafficLightEastDirection;

private readonly IntPtr _hwnd;

/// <summary>
/// Initalisierte eine neue Instanz von <see cref="CrossRoadField"/> class.
/// </summary>
/// <param name="hwnd">Das Handle für das Control auf das gezeichnet werden soll</param>
public CrossRoadField(IntPtr hwnd)
{
_hwnd = hwnd;
CreateRoads();
InitializeTrafficLights(hwnd);
}

/// <summary>
/// Initialisiert eine Ampel, setzt die Startkoordinaten und den Startstatus
/// </summary>
/// <param name="hwnd">Das Handle für das Controll, auf dem gezeichnet wird</param>
private void InitializeTrafficLights(IntPtr hwnd)
{
_trafficLightNorthDirection = new TrafficLight(406, 403);
_trafficLightSouthDirection = new TrafficLight(254, 194);
_trafficLightWestDirection = new TrafficLight(406, 194);
_trafficLightEastDirection = new TrafficLight(254, 403);

_trafficLightNorthDirection.TrafficLightStatus = TrafficLightStatus.Green;
_trafficLightSouthDirection.TrafficLightStatus = TrafficLightStatus.Green;
_trafficLightWestDirection.TrafficLightStatus = TrafficLightStatus.Red;
_trafficLightEastDirection.TrafficLightStatus = TrafficLightStatus.Red;

_trafficLightNorthDirection.Name = "NORTH";
_trafficLightSouthDirection.Name = "SOUTH";
_trafficLightEastDirection.Name = "EAST";
_trafficLightWestDirection.Name = "WEST";

TrafficLights.Add(_trafficLightNorthDirection);
TrafficLights.Add(_trafficLightSouthDirection);
TrafficLights.Add(_trafficLightWestDirection);
TrafficLights.Add(_trafficLightEastDirection);

Control control = Control.FromHandle(hwnd);
control.Controls.Add(_trafficLightNorthDirection);
control.Controls.Add(_trafficLightSouthDirection);
control.Controls.Add(_trafficLightEastDirection);
control.Controls.Add(_trafficLightWestDirection);
}

/// <summary>
/// Zeichnet den Bereich, wo sich die Bricks der verschieden Roads überschneiden
/// </summary>
/// <param name="interSection">Der Bereich, wo sich die Bricks der verschieden Roads überschneiden </param>
public void DrawInterSection(InterSection interSection)
{
var square = new Square(_hwnd);
foreach (var brick in interSection.Bricks)
{
square.SetSquare(brick);
}
}

/// <summary>
/// Zeichnet den Bereich, wo sich die Bricks der verschieden Roads überschneiden
/// </summary>
public void DrawInterSection()
{
var square = new Square(_hwnd);
var interSection = SetIntersectionBricks();
foreach (var brick in interSection.Bricks)
{
square.SetSquare(brick);
}
}

/// <summary>
/// Erzeugt die 4 Fahrspuren der Kreuzung
/// </summary>
private void CreateRoads()
{
_northRoad = new Road(new Point(357, 697), Direction.North, BrickSize,
new TrafficVolumeExtensions(TrafficVolume._5_Normal));
_southRoad = new Road(new Point(340, 0), Direction.South, BrickSize,
new TrafficVolumeExtensions(TrafficVolume._5_Normal));
_eastRoad = new Road(new Point(0, 357), Direction.East, BrickSize,
new TrafficVolumeExtensions(TrafficVolume._3_Low));
_westRoad = new Road(new Point(697, 340), Direction.West, BrickSize,
new TrafficVolumeExtensions(TrafficVolume._3_Low));
}

/// <summary>
/// Zeichnet die 4 Fahrspuren der Kreuzung unter Ausslassung der Überschneidung
/// </summary>
public void DrawRoads()
{
var square = new Square(_hwnd);
for (var i = 41; i >= 0; i--)
{
if (i == TurnRightBrickIndex || i == TurnLeftBrickIndex) continue;
square.SetSquare(_northRoad.Bricks);
square.SetSquare(_southRoad.Bricks);
square.SetSquare(_westRoad.Bricks);
square.SetSquare(_eastRoad.Bricks);
}
DrawInterSection();
}

/// <summary>
/// Setzt die Steine der Überschneidung der Fahrspuren
/// </summary>
/// <returns>Gibt die berechnete Überschneidung zurück</returns>
private InterSection SetIntersectionBricks()
{
Brick firstIntersectionBrickOfNorthRoad = _northRoad.Bricks[TurnRightBrickIndex];

if (_eastRoad.Bricks[TurnLeftBrickIndex].Car != null)
{
firstIntersectionBrickOfNorthRoad = _eastRoad.Bricks[TurnLeftBrickIndex];
}

Brick firstIntersectionBrickOfSouthRoad = _southRoad.Bricks[TurnRightBrickIndex];

if (_westRoad.Bricks[TurnLeftBrickIndex].Car != null)
{
firstIntersectionBrickOfSouthRoad = _westRoad.Bricks[TurnLeftBrickIndex];
}

Brick firstIntersectionBrickOfWestRoad = _westRoad.Bricks[TurnRightBrickIndex];

if (_northRoad.Bricks[TurnLeftBrickIndex].Car != null)
{
firstIntersectionBrickOfWestRoad = _northRoad.Bricks[TurnLeftBrickIndex];
}

Brick firstIntersectionBrickOfEastRoad = _eastRoad.Bricks[TurnRightBrickIndex];

if (_southRoad.Bricks[TurnLeftBrickIndex].Car != null)
{
firstIntersectionBrickOfEastRoad = _southRoad.Bricks[TurnLeftBrickIndex];
}

return new InterSection(firstIntersectionBrickOfNorthRoad, firstIntersectionBrickOfSouthRoad,
firstIntersectionBrickOfWestRoad, firstIntersectionBrickOfEastRoad);
}
}
}[/src]


Destination
[src=csharp]namespace TrafficLightControlledCrossroads
{
/// <summary>
/// die drei Möglichen Richtungen an einer Kreuzung
/// </summary>
public enum Destination
{
Straight, Right, Left
}
}[/src]

Direction
[src=csharp]namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Die 4 möglichen Richtungen der Straßen
/// </summary>
public enum Direction
{
North=1,South=2,East=3,West=4
}
}[/src]

FormMain
[src=csharp]using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using TrafficLightControlledCrossroads.Properties;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Das Hauptfenster der Anwendung
/// </summary>
public partial class FormMain : Form
{
private Simulation _sim;
private Timer _timer;
private int _cycle;

/// <summary>
/// Initialisiert eine neue Instanz von <see cref="FormMain"/> class.
/// </summary>
public FormMain()
{
InitializeComponent();
Text = Resources.FormMain_FormMain_TrafficLightControlledCrossroads_ + Application.ProductVersion +
Resources.FormMain_FormMain____ + Environment.UserDomainName + @"\" + Environment.UserName +
Resources.FormMain_FormMain____ + Environment.MachineName;
}

public override sealed string Text
{
get { return base.Text; }
set { base.Text = value; }
}

/// <summary>
/// Handler für das Laden der Form. Wir initialisieren hier den Timer der Simulation.
/// </summary>
/// <param name="sender">Auslöser des Events</param>
/// <param name="e">The <see cref="EventArgs"/>Instanz, die die Daten des Event enthält</param>
private void FormMain_Load(object sender, EventArgs e)
{
_timer = new Timer {Interval = 250};
_timer.Tick += timer_Tick;
CreateBackRoundImage();
_sim = new Simulation(tlccPanel.Handle);
}

/// <summary>
/// Erzeugen des Hintergrund,bzw. des Nichtstraßenbereichs
/// </summary>
private void CreateBackRoundImage()
{
var bitMap = new Bitmap(713, 713);
using (var g = Graphics.FromImage(bitMap))
using (var blackBrush = new SolidBrush(Color.Green))
{
g.FillRectangle(blackBrush, new Rectangle(0, 0, 339, 339));
g.FillRectangle(blackBrush, new Rectangle(374, 374, 339, 339));
g.FillRectangle(blackBrush, new Rectangle(0, 374, 339, 339));
g.FillRectangle(blackBrush, new Rectangle(374, 0, 339, 339));
}

tlccPanel.BackgroundImage = bitMap;
tlccPanel.Invalidate();
}

/// <summary>
/// Initiiert einen weiteren Simulationszyklus
/// </summary>
/// <param name="sender">Auslöser des Events</param>
/// <param name="e">The <see cref="EventArgs"/>Instanz, die die Daten des Event enthält</param>
private void timer_Tick(object sender, EventArgs e)
{
_sim.Simulate();
label1.Text = (_cycle++).ToString(CultureInfo.InvariantCulture);
}

/// <summary>
/// Einstellen der Simulationsgeschwindigkeit
/// </summary>
/// <param name="sender">Ereignissender</param>
/// <param name="e">Ereignisdaten</param>
private void trackBar_Speed_ValueChanged(object sender, EventArgs e)
{
_timer.Interval = (trackBar_Speed.Maximum - trackBar_Speed.Value) + 1;
}

/// <summary>
/// Starten und Stoppen der Simulation
/// </summary>
/// <param name="sender">Auslöser des Events</param>
/// <param name="e">The <see cref="EventArgs"/>Instanz, die die Daten des Event enthält</param>
private void button_StartStop_Click(object sender, EventArgs e)
{
_timer.Enabled = !_timer.Enabled;
}

/// <summary>
/// Führt einen einzelnen Zyklus der Simulation aus
/// </summary>
/// <param name="sender">Auslöser des Events</param>
/// <param name="e">The <see cref="EventArgs"/>Instanz, die die Daten des Event enthält</param>
private void button_Step_Click(object sender, EventArgs e)
{
_sim.Simulate();
label1.Text = (_cycle++).ToString(CultureInfo.InvariantCulture);
}
}
}[/src]

InterSection
[src=csharp]using System.Collections.Generic;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// InterSection besteht aus 4 Fahrspuren
/// </summary>
internal class InterSection
{
/// <summary>
/// Gibt die Bricks der Überschneidung zurück
/// </summary>
/// <value>
/// Die Steine (Bricks)
/// </value>
public List<Brick> Bricks
{
get { return _bricks; }
}

/// <summary>
/// Die bricks der Überschneidung
/// </summary>
private readonly List<Brick> _bricks = new List<Brick>();

/// <summary>
/// InterSection besteht aus 4 Fahrspuren
/// </summary>
/// <param name="firstIntersectionBrickOfNorthRoad">erster Brick der nach Norden führenden Fahrspur</param>
/// <param name="firstIntersectionBrickOfSouthRoad">erster Brick der nach Süden führenden Fahrspur</param>
/// /// <param name="firstIntersectionBrickOfWestRoad">erster Brick der nach Westen führenden Fahrspur</param>
/// <param name="firstIntersectionBrickOfEastRoad">erster Brick der nach Osten führenden Fahrspur</param>
public InterSection(Brick firstIntersectionBrickOfNorthRoad, Brick firstIntersectionBrickOfSouthRoad,
Brick firstIntersectionBrickOfWestRoad, Brick firstIntersectionBrickOfEastRoad)
{
Bricks.Add(firstIntersectionBrickOfNorthRoad);
Bricks.Add(firstIntersectionBrickOfSouthRoad);
Bricks.Add(firstIntersectionBrickOfWestRoad);
Bricks.Add(firstIntersectionBrickOfEastRoad);
}
}
}[/src]

Program
[src=csharp]using System;
using System.Windows.Forms;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Startklasse
/// </summary>
static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}
[/src]

Road
[src=csharp]using System;
using System.Collections.Generic;
using System.Drawing;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Eine Fahrspur
/// </summary>
internal class Road
{
/// <summary>
/// Initialisiert eine neue Instanz von <see cref="Road"/> class.
/// </summary>
/// <summary>
/// Die Elemente der Fahrspur
/// </summary>
public List<Brick> Bricks
{
get { return _bricks; }
}

/// <summary>
/// Setzt oder liest die TrafficVolumeExtensions
/// </summary>
/// <value>
/// TrafficVolumeExtensions
/// </value>
public TrafficVolumeExtensions TrafficVolumeExtensions { get; set; }

private readonly List<Brick> _bricks = new List<Brick>();

/// <summary>
/// Berechnet die Elemente einer Fahrspur
/// </summary>
/// <param name="startPosition">Die Koordinate des ersten Bricks</param>
/// <param name="direction">Fahrtrichtung der Fahrspur</param>
/// <param name="brickSize">Größe der Fahrspurelemente und Breite der Spur</param>
/// <param name="trafficVolumeExtensions">Enthält Informationen zur Verkehrsdichte und zur Wahrscheinlichkeit des Auftretens</param>
public Road(Point startPosition, Direction direction, int brickSize,
TrafficVolumeExtensions trafficVolumeExtensions)
{
TrafficVolumeExtensions = trafficVolumeExtensions;
var brick = new Brick(startPosition, brickSize);
_bricks.Add(brick);
var currentPosition = startPosition;
for (int i = 1; i < 42; i++)
{
var nextPosition = NextPosition(currentPosition, direction, brickSize);
brick = new Brick(nextPosition, brickSize);
_bricks.Add(brick);
currentPosition = nextPosition;
}
}

/// <summary>
/// Berechnet die Lage des nächsten Fahrspurelements
/// </summary>
/// <param name="current">Koordinaten des aktuellen Bricks</param>
/// <param name="direction">Fahrtrichtung</param>
/// <param name="brickSize">Größe des Fahrspurelements</param>
/// <returns>Position des nächsten Bricks</returns>
private Point NextPosition(Point current, Direction direction, int brickSize)
{
switch (direction)
{
case Direction.North:
current.Y -= (Int32) (brickSize*1.15);
break;
case Direction.South:
current.Y += (Int32) (brickSize*1.15);
break;
case Direction.East:
current.X += (Int32) (brickSize*1.15);
break;
case Direction.West:
current.X -= (Int32) (brickSize*1.15);
break;
}
return current;
}
}
}[/src]
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
Simulation
[src=csharp]using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Die Simulationslogik
/// </summary>
internal class Simulation
{
private readonly Road _northRoad;
private readonly Road _southRoad;
private readonly Road _eastRoad;
private readonly Road _westRoad;
private readonly TrafficLight _trafficLightNorthDirection;
private readonly TrafficLight _trafficLightSouthDirection;
private readonly TrafficLight _trafficLightWestDirection;
private readonly TrafficLight _trafficLightEastDirection;
private const int LastBrick = 41;
private const int TurnLeftBrick = 21;
private const int TurnRightBrick = 20;
private const int StopBrick = 19;
private const int InductionLoop = 9;
private const int InductionLoopOffSet = 5;
private const int FirstBrick = 0;
private readonly CrossRoadField _crossRoadField;

/// <summary>
/// Initialisiert eine neue Instanz von <see cref="Simulation"/> class.
/// </summary>
/// <param name="hwnd">Handle für das Controll auf dem gezeichnet werden soll</param>
public Simulation(IntPtr hwnd)
{
_crossRoadField = new CrossRoadField(hwnd);

_northRoad = _crossRoadField.NorthRoad;
_southRoad = _crossRoadField.SouthRoad;
_eastRoad = _crossRoadField.EastRoad;
_westRoad = _crossRoadField.WestRoad;
_trafficLightNorthDirection = _crossRoadField.TrafficLights.Find(x => x.Name == "NORTH");
_trafficLightSouthDirection = _crossRoadField.TrafficLights.Find(x => x.Name == "SOUTH");
_trafficLightWestDirection = _crossRoadField.TrafficLights.Find(x => x.Name == "WEST");
_trafficLightEastDirection = _crossRoadField.TrafficLights.Find(x => x.Name == "EAST");

_trafficLightNorthDirection.PropertyChanged += TrafficLightNorthDirection_PropertyChanged;
}

/// <summary>
/// behandelt den PropertyChanged-Event des TrafficLightNorthDirection-Controls.
/// </summary>
/// <param name="sender">Auslöser des Events</param>
/// <param name="e">The <see cref="EventArgs"/>Instanz, die die Daten des Event enthält</param>
private void TrafficLightNorthDirection_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//Da alle Ampeln gleichzeitig Umschalten, reicht die Abfrage bei einer Ampel
if (
_trafficLightNorthDirection.TrafficLightStatus ==
TrafficLightStatus.Green || _trafficLightNorthDirection.TrafficLightStatus == TrafficLightStatus.Red)
{
_northRoad.TrafficVolumeExtensions = GetNewRandomTrafficVolume();
_southRoad.TrafficVolumeExtensions = GetNewRandomTrafficVolume();
_westRoad.TrafficVolumeExtensions = GetNewRandomTrafficVolume();
_eastRoad.TrafficVolumeExtensions = GetNewRandomTrafficVolume();
}
}

/// <summary>
/// Auswahl eines neuen zufälligen Verkehrsaufkommens.
/// </summary>
/// <returns>Eine neues Verkehrsaufkommen, ergänzt durch Ergänzungen zur Aufkommenswahrscheinlichkeit</returns>
private TrafficVolumeExtensions GetNewRandomTrafficVolume()
{
int temp = 0;
var boundaries = new List<int>();
var trafficVolumeExtensionsList = new List<TrafficVolumeExtensions>();
for (int i = 0; i < Enum.GetNames(typeof (TrafficVolume)).Length; i++)
{
var trafficVolumeExtensions = new TrafficVolumeExtensions((TrafficVolume) i);
boundaries.Add(temp + trafficVolumeExtensions.ProbabilityForThisTrafficVolumeSizeRange);
trafficVolumeExtensionsList.Add(trafficVolumeExtensions);
temp += trafficVolumeExtensions.ProbabilityForThisTrafficVolumeSizeRange;
}
int highestBoundery = temp;

int rnd = TlccRandom.GenerateRandomNumber(1, highestBoundery);

for (int i = 0; i < boundaries.Count; i++)
{
if (rnd <= boundaries)
{
return trafficVolumeExtensionsList;
}
}
return null;
}

/// <summary>
/// Ein Auto am Ende der Straße muß uns verlassen.
/// </summary>
/// <param name="brick">The brick.</param>
private void LeaveRoad(Brick brick)
{
brick.Car = null;
}

/// <summary>
/// Prüft die Ampel und ob der Gegenverkehr sich bewegt.
/// </summary>
/// <param name="brick">Der Aktuelle Brick.</param>
/// <param name="nextBrick">Der nächste Brick.</param>
/// <param name="overNextBrick">Der übernächste Brick.</param>
/// <param name="leftRoadTurnLeftBrick">Der brick auf der von links kommenden Spur, wo ein Linksabbiegerauto anhält.</param>
/// <param name="trafficLight">Die Ampel</param>
private void CheckVelocityAndTrafficLight(Brick brick, Brick nextBrick, Brick overNextBrick,
Brick leftRoadTurnLeftBrick,
TrafficLight trafficLight)
{
if (brick.Car != null)
{
if (brick.Car.Stopped)
{
if (trafficLight.TrafficLightStatus == TrafficLightStatus.Green && overNextBrick.Car == null &&
leftRoadTurnLeftBrick.Car == null)
{
brick.Car.Stopped = false;
GoStraightOn(brick, nextBrick, overNextBrick);
}
}
else
{
if (trafficLight.TrafficLightStatus == TrafficLightStatus.Green &&
(nextBrick.Car == null && leftRoadTurnLeftBrick.Car == null) &&
(overNextBrick.Car == null || !overNextBrick.Car.Stopped) ||
brick.Car.Destination == Destination.Right)
{
GoStraightOn(brick, nextBrick, overNextBrick);
}
else
{
brick.Car.Stopped = true;
}
}
}
}


/// <summary>
/// Turns the right.
/// </summary>
/// <param name="brick">Der Aktuelle Brick.</param>
/// <param name="nextBrick">Der nächste Brick.</param>
/// <param name="overNextBrick">Der übernächste Brick.</param>
/// <param name="rightBrick">Der nächste Brick beim Reechtsabbiegen </param>
private void TurnRight(Brick brick, Brick nextBrick, Brick overNextBrick, Brick rightBrick)
{
if (brick.Car != null)
{
if (brick.Car.Destination == Destination.Right)
{
if (rightBrick.Car == null)
{
brick.Car.Stopped = false;
rightBrick.Car = brick.Car;
brick.Car = null;
}
else
{
brick.Car.Stopped = true;
}
}
else
{
GoStraightOn(brick, nextBrick, overNextBrick);
}
}
}


/// <summary>
/// Prüft, ob eine gewisse Anzahl von Autos vor der Ampel stehen, so daß Priorität gewährt werden sollte.
/// Aber nur, wenn in den beiden kreuzenden Fahrspuren bis zur Grünphase nicht auch dieser Zustand
/// zu erwarten ist
/// </summary>
/// <param name="currentInductionBrick">The induction brick der aktuellen Fahrspur. Dort wo auf Stau geprüft wird.</param>
/// <param name="leftInductionBrick">The induction brick der von links kommenden Fahrspur.Dort wo auf Stau geprüft wird.</param>
/// <param name="leftExtraCheckPointBrick">Ein zusätzlicher Prüfstein für Verkehr auf der von links kommenden Fahrspur direkt vor dem off sett Brick</param>
/// <param name="leftOffSetBrick">Ein Prüfstein mit festem Versatz zum induction Brick auf der von links kommenden Fahrspur</param>
/// <param name="rightInductionBrickBrick">The induction brick der von rechts kommenden Fahrspur.Dort wo auf Stau geprüft wird.</param>
/// <param name="rightExtraCheckPointBrick">Ein zusätzlicher Prüfstein für Verkehr auf der von rechts kommenden Fahrspur direkt vor dem off sett Brick</param>
/// <param name="rightOffSetBrick">Ein Prüfstein mit festem Versatz zum induction Brick auf der von rechts kommenden Fahrspur</param>
/// <returns></returns>
private bool PriorityNeeded(Brick currentInductionBrick, Brick leftInductionBrick,
Brick leftExtraCheckPointBrick, Brick leftOffSetBrick, Brick rightInductionBrickBrick,
Brick rightExtraCheckPointBrick, Brick rightOffSetBrick)
{
// Ein stehendes Auto bedeutet Stau, im Gegensatz zu kein Auto oder in Bewegung
if (currentInductionBrick.Car != null && currentInductionBrick.Car.Stopped &&
(leftInductionBrick.Car == null || !leftInductionBrick.Car.Stopped) &&
(leftExtraCheckPointBrick.Car == null) &&
(leftOffSetBrick.Car == null) &&
(rightInductionBrickBrick.Car == null || !rightInductionBrickBrick.Car.Stopped) &&
(rightExtraCheckPointBrick.Car == null) &&
(rightOffSetBrick.Car == null)
)
{
return true;
}
return false;
}

/// <summary>
/// Prüft ob sich auf einem Stein ein Auto mit Linksabbiegerabsicht befindet.
/// </summary>
/// <param name="brick">Der aktuelle Stein</param>
/// <returns>Einen Wert, der angibt, ob der Wagen asl Linskabbieger markiert ist, oder nicht. </returns>
private bool MarkedForTurnLeft(Brick brick)
{
return (brick.Car != null && brick.Car.Destination == Destination.Left);
}

/// <summary>
/// Linksabbiegen
/// </summary>
/// <param name="brick">Der Aktuelle Stein</param>
/// <param name="leftBrick">Der Stein, auf den das Auto bein Linksabbiegen auf die andere Fahrspuhr begibt.</param>
/// <param name="contraflow">Die Gegenverkehrfahrspur</param>
private void TurnLeft(Brick brick, Brick leftBrick, Road contraflow) //old
{
if (contraflow.Bricks[TurnRightBrick].Car == null &&
(contraflow.Bricks[StopBrick].Car == null || contraflow.Bricks[StopBrick].Car.Stopped))
{
brick.Car.Destination = Destination.Straight;
brick.Car.Stopped = false;
leftBrick.Car = brick.Car;
brick.Car = null;
}
else
{
brick.Car.Stopped = true;
}
}

/// <summary>
/// Vorwärtsfahren
/// </summary>
/// <param name="brick">Der Aktuelle Stein</param>
/// <param name="nextBrick">Der nächste Stein der Fahrspur.</param>
/// <param name="overNextBrick">Der übernächste Stein der Fahrspur.</param>
private void GoStraightOn(Brick brick, Brick nextBrick, Brick overNextBrick)
{
if (brick.Car != null)
{
if (nextBrick.Car == null && (overNextBrick.Car == null || overNextBrick.Car.Stopped))

{
brick.Car.Stopped = false;
nextBrick.Car = brick.Car;

brick.Car = null;
}
else
{
brick.Car.Stopped = true;
}
}
}

/// <summary>
/// Entscheidet nach Zufall und Wahrscheinlichkeitsparameter, ob ein neues Auto erscheint.
/// </summary>
/// <param name="trafficVolumeExtensions">Erweiterung von de Aufzählung der Verkehrsaufkommen,
/// welches Informationen über Verkehrswahrscheinlichkeiten speichert</param>
/// <returns>Einen Wert, der angibt, ob ein neues Auto auf der Fahrspur erscheint, oder aber nicht.</returns>
private bool DoWeWantNewCar(TrafficVolumeExtensions trafficVolumeExtensions)
{
var rnd = TlccRandom.GenerateRandomNumber(1, 101);
return rnd < trafficVolumeExtensions.ProbabilityOfNewCar;
}

/// <summary>
/// Setzt ein neues Auto auf die Fahrspur.
/// </summary>
/// <param name="road">Die aktuelle Fahrspur</param>
private void NewCarToTheRoad(Road road)
{
if (road.Bricks[FirstBrick].Car == null &&
(road.Bricks[FirstBrick + 1].Car == null || road.Bricks[FirstBrick + 1].Car.Stopped) &&
DoWeWantNewCar(road.TrafficVolumeExtensions))
{
road.Bricks[FirstBrick].Car = new Car();
}
}

/// <summary>
/// Ein Simulationszyklus
/// </summary>
public void Simulate()
{
for (var i = LastBrick; i >= 0; i--)
{
switch (i)
{
#region Kommentar

//

#endregion

case LastBrick:
LeaveRoad(_northRoad.Bricks);
LeaveRoad(_southRoad.Bricks);
LeaveRoad(_westRoad.Bricks);
LeaveRoad(_eastRoad.Bricks);
break;
case (LastBrick - 1):

#region Kommentar

//Trick. Der 3.Parameter sollte eigentlich der übernächste Brick sein. Der liegt aber in diesem Fall außerhalb der Range, wird aber hier eh nicht benötigt, also bestücken wir
//ihn anders(mit dem aktuellen brick)
//Alternativ müßte man GoStraightOn extra überladen.

#endregion

GoStraightOn(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks);
GoStraightOn(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks);
GoStraightOn(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks);
GoStraightOn(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks);
break;

case TurnLeftBrick:

#region Kommentar

//

#endregion

if (MarkedForTurnLeft(_northRoad.Bricks))
{
TurnLeft(_northRoad.Bricks, _westRoad.Bricks[TurnRightBrick], _southRoad);
}
else
{
GoStraightOn(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks[i + 2]);
}

if (MarkedForTurnLeft(_southRoad.Bricks))
{
TurnLeft(_southRoad.Bricks, _eastRoad.Bricks[TurnRightBrick], _northRoad);
}
else
{
GoStraightOn(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks[i + 2]);
}

if (MarkedForTurnLeft(_westRoad.Bricks))
{
TurnLeft(_westRoad.Bricks, _southRoad.Bricks[TurnRightBrick], _eastRoad);
}
else
{
GoStraightOn(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks[i + 2]);
}

if (MarkedForTurnLeft(_eastRoad.Bricks))
{
TurnLeft(_eastRoad.Bricks, _northRoad.Bricks[TurnRightBrick], _westRoad);
}
else
{
GoStraightOn(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks[i + 2]);
}
break;
case TurnRightBrick:

#region Kommentar

//

#endregion

TurnRight(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks[i + 2],
_eastRoad.Bricks[i + 2]);
TurnRight(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks[i + 2],
_westRoad.Bricks[i + 2]);
TurnRight(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks[i + 2],
_northRoad.Bricks[i + 2]);
TurnRight(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks[i + 2],
_southRoad.Bricks[i + 2]);
break;
case StopBrick:

#region Kommentar

//

#endregion

CheckVelocityAndTrafficLight(_northRoad.Bricks, _northRoad.Bricks[i + 1],
_northRoad.Bricks[i + 2], _eastRoad.Bricks[TurnLeftBrick], _trafficLightNorthDirection);
CheckVelocityAndTrafficLight(_southRoad.Bricks, _southRoad.Bricks[i + 1],
_southRoad.Bricks[i + 2], _westRoad.Bricks[TurnLeftBrick], _trafficLightSouthDirection);
CheckVelocityAndTrafficLight(_westRoad.Bricks, _westRoad.Bricks[i + 1],
_westRoad.Bricks[i + 2], _northRoad.Bricks[TurnLeftBrick], _trafficLightWestDirection);
CheckVelocityAndTrafficLight(_eastRoad.Bricks, _eastRoad.Bricks[i + 1],
_eastRoad.Bricks[i + 2], _southRoad.Bricks[TurnLeftBrick], _trafficLightEastDirection);
break;
case InductionLoop: //+222://( +222 = deaktiviert)

if (PriorityNeeded(_northRoad.Bricks, _westRoad.Bricks[InductionLoop],
_westRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_westRoad.Bricks[InductionLoop + InductionLoopOffSet],
_eastRoad.Bricks[InductionLoop], _eastRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_eastRoad.Bricks[InductionLoop + InductionLoopOffSet]) &&
_trafficLightNorthDirection.TrafficLightStatus == TrafficLightStatus.Red)
{
ForcePhaseChange();
}

GoStraightOn(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks[i + 2]);

if (PriorityNeeded(_southRoad.Bricks, _eastRoad.Bricks[InductionLoop],
_eastRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_eastRoad.Bricks[InductionLoop + InductionLoopOffSet],
_westRoad.Bricks[InductionLoop], _westRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_westRoad.Bricks[InductionLoop + InductionLoopOffSet]) &&
_trafficLightSouthDirection.TrafficLightStatus == TrafficLightStatus.Red)
{
ForcePhaseChange();
}

GoStraightOn(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks[i + 2]);

if (PriorityNeeded(_westRoad.Bricks, _southRoad.Bricks[InductionLoop],
_southRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_southRoad.Bricks[InductionLoop + InductionLoopOffSet],
_northRoad.Bricks[InductionLoop], _northRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_northRoad.Bricks[InductionLoop + InductionLoopOffSet]) &&
_trafficLightWestDirection.TrafficLightStatus == TrafficLightStatus.Red)
{
ForcePhaseChange();
}

GoStraightOn(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks[i + 2]);

if (PriorityNeeded(_eastRoad.Bricks, _northRoad.Bricks[InductionLoop],
_northRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_northRoad.Bricks[InductionLoop + InductionLoopOffSet],
_southRoad.Bricks[InductionLoop], _southRoad.Bricks[InductionLoop + InductionLoopOffSet - 1],
_southRoad.Bricks[InductionLoop + InductionLoopOffSet]) &&
_trafficLightEastDirection.TrafficLightStatus == TrafficLightStatus.Red)
{
ForcePhaseChange();
}

GoStraightOn(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks[i + 2]);

break;
case FirstBrick:

#region Kommentar

//

#endregion

GoStraightOn(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks[i + 2]);
NewCarToTheRoad(_northRoad);
GoStraightOn(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks[i + 2]);
NewCarToTheRoad(_southRoad);
GoStraightOn(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks[i + 2]);
NewCarToTheRoad(_westRoad);
GoStraightOn(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks[i + 2]);
NewCarToTheRoad(_eastRoad);

# if DEBUG

//TODO: entfernen nach Testphase:
// Die Farbe der Autos "im Debug Modus" wird überschrieben. Jeweils mit dem Wert für
//alle Wagen aus der gleichen Richtung um das Abbiegeverhalten zum Testen sichtbar zu machen.
//

if (_northRoad.Bricks[FirstBrick].Car != null)
{
_northRoad.Bricks[FirstBrick].Car.Color = TlccColors.Blue;
}
if (_southRoad.Bricks[FirstBrick].Car != null)
{
_southRoad.Bricks[FirstBrick].Car.Color = TlccColors.Green;
}
if (_westRoad.Bricks[FirstBrick].Car != null)
{
_westRoad.Bricks[FirstBrick].Car.Color = TlccColors.Red;
}
if (_eastRoad.Bricks[FirstBrick].Car != null)
{
_eastRoad.Bricks[FirstBrick].Car.Color = TlccColors.Yellow;
}
#endif
break;
default:

#region Kommentar

//

#endregion

GoStraightOn(_northRoad.Bricks, _northRoad.Bricks[i + 1], _northRoad.Bricks[i + 2]);
GoStraightOn(_southRoad.Bricks, _southRoad.Bricks[i + 1], _southRoad.Bricks[i + 2]);
GoStraightOn(_westRoad.Bricks, _westRoad.Bricks[i + 1], _westRoad.Bricks[i + 2]);
GoStraightOn(_eastRoad.Bricks, _eastRoad.Bricks[i + 1], _eastRoad.Bricks[i + 2]);
break;
}
}

#region Kommentar

//

#endregion

_crossRoadField.DrawRoads();
_crossRoadField.DrawInterSection();
TriggerLights();
}

/// <summary>
/// Triggert die Ampeln
/// </summary>
private void TriggerLights()
{
foreach (var trafficLight in _crossRoadField.TrafficLights)
{
trafficLight.Tick();
}
}

/// <summary>
/// Forciert bei den Wechsel bei Rot, bzw. für Grün auf den kreuzenden Fahrspuren.
/// </summary>
private void ForcePhaseChange()
{
foreach (var trafficLight in _crossRoadField.TrafficLights)
{
switch (trafficLight.TrafficLightStatus)
{
case TrafficLightStatus.Green:
trafficLight.BeginStopPhase();
break;
case TrafficLightStatus.Red:
trafficLight.BeginGoPhase();
break;
}
}
}
}
}[/src]


Square
[src=csharp]using System;
using System.Drawing;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Klasse zum Zeichnen eines Bricks
/// </summary>
internal class Square
{
private readonly IntPtr _hwnd;

/// <summary>
/// Initialisiert eine neue Instanz von <see cref="Square"/> class.
/// </summary>
/// <param name="hwnd">Das Handle für das Controll, auf dem gezeichnet werden soll.</param>
public Square(IntPtr hwnd)
{
_hwnd = hwnd;
}

/// <summary>
/// Zeichet einen Brick. Entweder als Stück Straße, oder als Representation eines daruf fahrenden Cars
/// </summary>
/// <param name="brick">Die Einheit für das Stück Straße, auf der sich ein Car befinden kann</param>
public void SetSquare(Brick brick)
{
var surface = Graphics.FromHwnd(_hwnd);
var rectangle = new Rectangle(brick.Location.X, brick.Location.Y, brick.Edge, brick.Edge);
Color color = brick.Car == null ? TlccColors.White : brick.Car.Color;
surface.FillRectangle(new SolidBrush(color), rectangle);
}
}
}[/src]

TlccColors
[src=csharp]using System.Drawing;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Die Farben, die in TrafficLightControlledCrossroads zur verfügung stehen sollen.
/// </summary>
public static class TlccColors
{
/// <summary>
/// Gibt alle TlccColors zurück
/// </summary>
/// <value>
/// Die Tlcc Farben
/// </value>
public static Color[] Colors
{
get { return new[] {Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.White}; }
}

/// <summary>
/// GGibt die Tlcc Fabe Rot zurück
/// </summary>
/// <value>
/// Rot
/// </value>
public static Color Red
{
get { return Colors[0]; }
}

/// <summary>
/// GGibt die Tlcc Fabe Gelb zurück
/// </summary>
/// <value>
/// Gelb
/// </value>
public static Color Yellow
{
get { return Colors[1]; }
}

/// <summary>
/// GGibt die Tlcc Fabe Grün zurück
/// </summary>
/// <value>
/// Grün
/// </value>
public static Color Green
{
get { return Colors[2]; }
}

/// <summary>
/// GGibt die Tlcc Fabe Blau zurück
/// </summary>
/// <value>
/// Blau
/// </value>
public static Color Blue
{
get { return Colors[3]; }
}

/// <summary>
/// GGibt die Tlcc Fabe Weiß zurück
/// </summary>
/// <value>
/// Weiß
/// </value>
public static Color White
{
get { return Colors[4]; }
}
}
}[/src]

TlccRandom
[src=csharp]using System;
using System.Security.Cryptography;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Klasse zur Erzeugung von Zufallszahlen
/// </summary>
internal static class TlccRandom
{
/// <summary>
/// Generiert eine zufällige Zahl innerhalt einer angegebenen Spanne
/// </summary>
/// <param name="min">Die inkluive unere Grenze</param>
/// <param name="max">Die exklusive obere Grenze</param>
/// <returns>Einen zufälligen Ganzzahlwert innerhalb der gewählten Grenzen</returns>
public static int GenerateRandomNumber(int min, int max)
{
var c = new RNGCryptoServiceProvider();
// Ein integer benötigt 4 Byte
var randomNumber = new byte[4];
// Auffüllen mit einer kryptographisch starken Folge an zufälligen Werten
c.GetBytes(randomNumber);
// Umwandlung Byte-Array in Integer
int result = Math.Abs(BitConverter.ToInt32(randomNumber, 0));
// Setzen der inklusiven Grenzen
return result%max + min;
}
}
}[/src]

TrafficLight
[src=csharp]using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Eine Ampel
/// </summary>
public partial class TrafficLight : UserControl, INotifyPropertyChanged
{
private TrafficLightStatus _trafficLightStatus;
private int _tickCount;
private const int YelloYellowRedPhaseLength = 5;
private const int RedPhaseLenght = 20;
private const int GreenPhaseLenght = 20;
private int _phaseLenght = 20;

/// <summary>
/// Ruft den Namen des Steuerelements ab oder legt diesen fest.
/// </summary>
public new string Name { get; set; }

/// <summary>
/// Tritt ein, wenn sich ein Eigenschaftenwert ändert.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Setzen oder lesen des Ampelstatus
/// </summary>
/// <value>
/// Der Status der Ampel.
/// </value>
public TrafficLightStatus TrafficLightStatus
{
get { return _trafficLightStatus; }
set
{
_trafficLightStatus = value;
// Wenn die Eigenschaft sich ändert, OnPropertyChanged aufrufen
OnPropertyChanged("TrafficLightStatus");
}
}

/// <summary>
/// Initializiert eie neue Instanz von <see cref="TrafficLight"/> class.
/// </summary>
public TrafficLight()
{
InitializeComponent();
SetPhase();
SetLights();
}

/// <summary>
/// Initializiert eie neue Instanz von <see cref="TrafficLight"/> class.
/// </summary>
/// <param name="x">X-Koordinate der linken oberen Ecke</param>
/// <param name="y">Y-Koordinate der rechten oberen Ecke</param>
public TrafficLight(int x, int y)
{
InitializeComponent();
Location = new Point(x, y);

_trafficLightStatus = TrafficLightStatus;

SetPhase();
SetLights();
}

/// <summary>
/// Triggert diese Ampelinstanz
/// </summary>
public void Tick()
{
if (_tickCount == _phaseLenght)
{
_trafficLightStatus = SwitchTrafficLightStatus(_trafficLightStatus);
SetPhase();
OnPropertyChanged("TrafficLightStatus");
_tickCount = 0;
}
_tickCount++;
}

/// <summary>
/// Gebinnt die Go-Phase mit dem Schalten auf Gelb
/// </summary>
public void BeginGoPhase()
{
_trafficLightStatus = TrafficLightStatus.RedYellow;
_tickCount = 0;
SetLights();
}

/// <summary>
/// Gebinnt die Stop-Phase mit dem Schalten auf RotGelb
/// </summary>
public void BeginStopPhase()
{
_trafficLightStatus = TrafficLightStatus.Yello;
_tickCount = 0;
SetLights();
}

/// <summary>
/// Schaltet die Ampel eine Phase weiter
/// </summary>
/// <param name="trafficlightstatus">The trafficlightstatus.</param>
/// <returns>Der neue Status der Ampel</returns>
private TrafficLightStatus SwitchTrafficLightStatus(TrafficLightStatus trafficlightstatus)
{
_tickCount = 0;
return (TrafficLightStatus) (((int) (trafficlightstatus + 1))%4);
}

/// <summary>
/// Wird aufgreufen bei [property changed].
/// </summary>
/// <param name="name">Name der Property</param>
private void OnPropertyChanged(string name)
{
SetLights();
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}

/// <summary>
/// Setzt die Phaselänge gemäß des Status
/// </summary>
private void SetPhase()
{
switch (_trafficLightStatus)
{
case TrafficLightStatus.Green:
_phaseLenght = GreenPhaseLenght;
break;
case TrafficLightStatus.Yello:
_phaseLenght = YelloYellowRedPhaseLength;
break;
case TrafficLightStatus.Red:
_phaseLenght = RedPhaseLenght;
break;
case TrafficLightStatus.RedYellow:
_phaseLenght = YelloYellowRedPhaseLength;
break;
}
}

/// <summary>
/// Schalten die Lichter gemäß dem Status
/// </summary>
private void SetLights()
{
switch (_trafficLightStatus)
{
case TrafficLightStatus.Green:
pictureBox_green.BackColor = Color.Lime;
pictureBox_yellow.BackColor = Color.Black;
pictureBox_red.BackColor = Color.Black;
break;
case TrafficLightStatus.Yello:
pictureBox_green.BackColor = Color.Black;
pictureBox_yellow.BackColor = Color.Yellow;
pictureBox_red.BackColor = Color.Black;
break;
case TrafficLightStatus.Red:
pictureBox_green.BackColor = Color.Black;
pictureBox_yellow.BackColor = Color.Black;
pictureBox_red.BackColor = Color.Red;
break;
case TrafficLightStatus.RedYellow:
pictureBox_green.BackColor = Color.Black;
pictureBox_yellow.BackColor = Color.Yellow;
pictureBox_red.BackColor = Color.Red;
break;
}
}
}
}[/src]

TrafficLightStatus
[src=csharp]namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Die vier möglichen Ampelstatus
/// </summary>
public enum TrafficLightStatus
{
Green,
Yello,
Red,
RedYellow
}
}[/src]

TrafficVolume
[src=csharp]namespace TrafficLightControlledCrossroads
{
/// <summary>
/// Verkehrsaufkommen
/// </summary>
public enum TrafficVolume
{
#region Kommentar

//Entspricht nicht Regel für Enum-Namen, aber ich möchte die Sortierung in VisualStudio-IntelliSense, welche
//alphabetisch ist, genauso haben wie hier. Daher die Zahlen, welche aber nicht zu beginn stehen dürfen.
//Daher die Unterstriche
//Choose your poison

#endregion

_1_CricketChirping,
_2_VeryLow,
_3_Low,
_4_SubNormal,
_5_Normal,
_6_SuperNormal,
_7_High,
_8_VeryHigh
}

/// <summary>
/// Erweiterung, die Informationen für die Zufallsgenerierung spiechert. Wie wahrscheinlich ist das Aufkommen
/// eines bestimmten Verkehrsaufkommens (verschiedene Größen) und wie hoch ist bei einem bestimmten Verkehrsaufkommen die
/// Wahrscheinlickeit eines weiteren Autos (in Prozent).
/// </summary>
internal class TrafficVolumeExtensions
{
private int _probabilityForThisTrafficVolumeSizeRange;
private int _probabilityOfNewCar;

/// <summary>
/// Größenbereich für die Wahrscheinlichkeit dieses Verkehrsaufkommens
/// </summary>
/// <value>
/// Der Größenbereich
/// </value>
public int ProbabilityForThisTrafficVolumeSizeRange
{
get { return _probabilityForThisTrafficVolumeSizeRange; }
}

/// <summary>
/// Die Wahrscheinlichkeit für ein neues Auto in %
/// </summary>
/// <value>
/// Der Prozentwert
/// </value>
public int ProbabilityOfNewCar
{
get { return _probabilityOfNewCar; }
}

/// <summary>
/// Initialisiert eine neue Instanz von <see cref="TrafficVolumeExtensions"/> class.
/// </summary>
/// <param name="name">Name des Verkehrsaufkommens</param>
internal TrafficVolumeExtensions(TrafficVolume name)
{
Name = name;
}


/// <summary>
/// Bei der Auswahl des Verkehrsaufkommens über den Namen werden Wahrscheinlickeiten für das Aufkommen
/// an sich und die Wahscheinlickeit von Autos für das Aufkommen gesetzt.
/// </summary>
private TrafficVolume Name
{
set
{
switch (value)
{
case TrafficVolume._1_CricketChirping:
_probabilityForThisTrafficVolumeSizeRange = 5;
_probabilityOfNewCar = 0;
break;
case TrafficVolume._2_VeryLow:
_probabilityForThisTrafficVolumeSizeRange = 10;
_probabilityOfNewCar = 10;
break;
case TrafficVolume._3_Low:
_probabilityForThisTrafficVolumeSizeRange = 20;
_probabilityOfNewCar = 15;
break;
case TrafficVolume._4_SubNormal:
_probabilityForThisTrafficVolumeSizeRange = 40;
_probabilityOfNewCar = 20;
break;
case TrafficVolume._5_Normal:
_probabilityForThisTrafficVolumeSizeRange = 80;
_probabilityOfNewCar = 25;
break;
case TrafficVolume._6_SuperNormal:
_probabilityForThisTrafficVolumeSizeRange = 10;
_probabilityOfNewCar = 35;
break;
case TrafficVolume._7_High:
_probabilityForThisTrafficVolumeSizeRange = 5;
_probabilityOfNewCar = 50;
break;
case TrafficVolume._8_VeryHigh:
_probabilityForThisTrafficVolumeSizeRange = 5;
_probabilityOfNewCar = 100;
break;
}
}
}
}
}[/src]

http://www2.zippyshare.com/v/gNiewWZk/file.html
 
Zuletzt bearbeitet:

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.752
Ort
in der Zukunft
Servus zusammen - Wie schaut es bei euch aus?
Mein NAS ist leider seit über 4 Wochen in Reperatur und ich komme an meine Alt-Daten nicht gut ran... daher keine vb6 Beispiele.
Für meine vb.net möglichkeit war im letzten Monat zu viel los.

Gibt es noch mehr die die Möglichkeit hätten in nächster Zeit eine Lösung zu posten oder die noch weiter machen wollen - oder sollen wir es wie geplant einfach in 2 Tagen beenden?
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
Huch. Ich muß noch ne exe hochladen. Aber der 19. ist doch erst Freitag, oder wie war das mit 2 Monaten gemeint?
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Verfolge diesen Thread noch mit! :)

Habe aber auch nicht mehr weiter an meiner Lösung gearbeitet. War in letzter Zeit zu faul und unkreativ zum programmieren :dozey:

Wäre aber daran interessiert bei einem neuen Thema mitzumachen falls es eines gibt :T
 

Der3Geist

always feed the fish

Registriert
14 Juli 2013
Beiträge
2.702
Ort
Hessen
Ursprünglich hatte ich ja auch zugesagt, aber konnte leider durch das gute wetter und entsprechend viel Arbeit kaum etwas an meinem Programm werkeln.
Sofern der Wettbewerb weitergemacht wird, schaffe ich es sicherlich auchmal an dem ein oder anderen Thema mitzumachen.
 

MSX

Retro-Nerd-Hippie

Registriert
14 Juli 2013
Beiträge
15.087
Ort
v01d
Dem schließe ich mich in etwa an. Kamen ein paar umfangreichere Rechnerprobleme und anderes dazwischen. Gern entweder das hier noch weiter, oder was anderes.
Immerhin hatte Kugelfisch auch keine Zeit und alle mit einem Einzeiler weggesteckt. ;-)
 

Larius

OutOfOrder

Registriert
12 Juli 2013
Beiträge
5.792
  • Thread Starter Thread Starter
  • #31
Nachdem ich bis am 4 Juli auf urlaub bin würde ich vorschlagen, das wir einfach bis dahin mit dem Bewerb weiter machen wie geplant. Danach werde ich mich wohl um eine kleine Auswertung kümmern und mir Gedanken um die nächste Veranstaltung machen :)

Lg
 

0xFADED

$coffee->toCode();

Registriert
26 Juni 2015
Beiträge
115
Ort
XFxFQVJUSA==
Dachte mir ich steig auf die letzten paar Tage mal mit ein.
Meine Version wird in NodeJS sein, da ich damit schon immer mal anfangen wollte.

Hier mal ein Bild vom Status heute (nach etwa 30min. Arbeit :D).
Denkt ihr das ist so ok, oder muss ich Ampeln/Straßen deutlicher machen ?

LG :coffee:

72ja32W.png
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Ich meine auch, sieht gut aus :T - Mittelstreifen könntest du aber eventuell noch mit einbauen. :)
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
[..] und mir Gedanken um die nächste Veranstaltung machen

Da möchte ich als Anregung mal Blockly in den Raum werfen. Das ist im Gegensatz zu irgend welchen Mindmaps imo noch nahe dran an Programmierung, aber braucht keine speziellen Programmierkenntnisse. Alleine die Anzahl generierter JS Zeilen könnte schon ein objektives Bewertungskriterium darstellen.

OT
Ich bin darauf gestoßen, als ich letzte Woche ein paar Preteenagern erklären wollte, was Programmierer so machen. Nämlich in der Regel kein GTA. Entgegen meiner Erwartung erzielte ich Interesse. Das Konzept ist also spielerisch genug. Und ich muß selber gestehen, daß ich hier Spaß dran hatte.
 

flawless

gesperrt

Registriert
2 Dez. 2014
Beiträge
3.964
Ort
NR01GOLF11
@drfuture: Meine CD läuft zwar nur auf win. Aber ich schaue mal nach ClassicLadder. Damit müsste ich es noch hinbekommen, mit etwas Recherge.

--- [2015-06-30 12:26 CEST] Automatisch zusammengeführter Beitrag ---



Hab mich für diese Schaltung entschieden.

#code folgt

bin schon bei Netzwerk 8
 

flawless

gesperrt

Registriert
2 Dez. 2014
Beiträge
3.964
Ort
NR01GOLF11
------------------------------------------------------------------------------

OB1: Baustellen-Ampel

------------------------------------------------------------------------------
Netzwerk 1: Initalisierung
------------------------------------------------------------------------------

UN "Schalter" M1.0 --EIN/AUS_Schalter
S M 10.0
U M 10.0
R M 10.1
R M 10.2
R M 10.3
R M 10.4
R M 10.5
R M 10.6
R M 10.7
R "H1" A0.0 --Ampel 1 Grün
R "H2" A0.1 --Ampel 2 Grün
R "H3" A0.2 --Ampel 1 Rot
R "H4" A0.3 --Ampel 2 Rot


------------------------------------------------------------------------------
Netzwerk 2: Ampelschaltung
------------------------------------------------------------------------------

U M 10.0
U "Schalter" M1.0 --Ein/AUS_Schalter
S M 10.1
R M 10.0
U M 10.1
S "H4" A0.3 --Ampel 2 Rot
S "H3" A0.2 --Ampel 1 Rot

------------------------------------------------------------------------------
Netzwerk 3: Ampel 1 Initiator 1 Rot-Phase
------------------------------------------------------------------------------

U M 10.1
U "Initiator 1" M1.1 --Initiator 1
S M10.2
R M10.1
U M10.2
L S5T#9s
SV T 1
L T 1
S "H4" A0.3 --Ampel 2 Rot
S "H3" A0.2 --Ampel 1 Rot
R "H1" A0.0 --Ampel 1 Grün
R "H2" A0.1 --Ampel 2 Grün

------------------------------------------------------------------------------
Netzwerk 4: Ampel 1 Initiator 1 Grün_Phase
------------------------------------------------------------------------------

UN T 1
U M 10.2
S M 10.3
R M 10.2
U M 10.3
L S5T#23S
SV T 2
L T 2
S "H1" A0.0 --Ampel 1 Grün
S "H4" A0.3 --Ampel 2 Rot
R "H3" A0.2 --Ampel 1 Rot
R "H2" A0.1 --Ampel 2 Grün

------------------------------------------------------------------------------
Netzwerk 5: Ampel 1 Dauergrün
------------------------------------------------------------------------------

Un T 2
U M 10.3
S M 10.4
R M 10.3
U M 10.4
S "H1" A0.0 --Ampel 1 Grün
S "H4" A0.3 --Ampel 2 Rot
R "H3" A0.2 --Ampel 1 Rot
R "H2" A0.1 --Ampel 2 Grün

------------------------------------------------------------------------------
Netzwerk 6: Ampel 1 Ausschaltung
------------------------------------------------------------------------------

UN "Schalter" M1.0 --EIN/AUS_Schalter
U M 10.4
S M 10.0
R M 10.4

------------------------------------------------------------------------------
Netzwerk 7: Ampel 2 Initiator 2 Rot-Phase
------------------------------------------------------------------------------

U M 10.1
U "Initiator 2" M1.2 --Initiator 2
S M 10.5
R M 10.1
U M 10.5
L S5T#10S
SV T 3
L T 3
S "H4" A0.3 --Ampel 2 Rot
S "H3" A0.2 --Ampel 1 Rot
R "H1" A0.0 --Ampel 1 Grün
R "H2" A0.1 --Ampel 2 Grün

------------------------------------------------------------------------------
Netzwerk 8: Ampel 2 Initiator 2 Grün_Phase
------------------------------------------------------------------------------

UN T 3
U M 10.5
S M 10.6
R M 10.5
U M 10.6
L S5T#33S
SV T 4
L T 4
S "H2" A0.1 --Ampel 2 Grün
S "H3" A0.2 --Ampel 1 Rot
R "H1" A0.0 --Ampel 1 Grün
R "H4" A0.3 --Ampel 2 Rot

------------------------------------------------------------------------------
Netzwerk 9: Ampel 2 dauergrün
------------------------------------------------------------------------------

UN T 4
U M 10.6
S M 10.7
R M 10.6
U M 10.7
S "H2" A0.1 --Ampel 2 Grün
S "H3" A0.2 --Ampel 1 Rot
R "H1" A0.0 --Ampel 1 Grün
R "H4" A0.3 --Ampel 2 Rot

------------------------------------------------------------------------------
Netzwerk 10: Ausschaltung Ampel 2
------------------------------------------------------------------------------

UN "Schalter" M1.0 --EIN/AUS_Schalter
U M 10.7
S M 10.0
R M 10.7

------------------------------------------------------------------------------

Netzwerk 11: Initiantor 2 Auslösung Ampel 2

------------------------------------------------------------------------------

U "Initiantor 2" M1.2 --Initiator 2
U M 10.4
S M 10.5
R M 10.4

------------------------------------------------------------------------------

Netzwerk 12: Initiator 1 Auslösung Ampel 1

------------------------------------------------------------------------------

U "Initiator 1" M1.1 --Initiator 1
U M 10.7
S M 10.2
R M 10.7

Ok ich hatte den Code schon in der Schublade. Allerdings hab ich jetzt die Rot-, bzw. Grünphasen etwas verlägert.
Orange kommt nicht vor, da Baustellenampel :D
 
Oben