<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[random number]]></title><description><![CDATA[<p>Hallo Zusammen</p>
<p>Kann mir jemand bei meinem Problem helfen?</p>
<p>Ich habe ein Nasch-Modell (Verkehrssimulation) mit zellulären Automaten implementiert.<br />
Dabei möchte ich auf N Zellen zufällig VEHICLE Fahrzeuge positionieren (mit einer zufälligen Anfangsgeschwindigkeit).<br />
Wenn ich eine nicht so grosse Anzahl VEHICLE habe, funktioniert mein Code, wenn ich aber z.B. jede zweite Zelle besetzen möchte, funktioniert er nicht mehr, was ich eigentlich verstehe...<br />
Hier mal der Code: (Funktion mit int i als Parameter)</p>
<pre><code class="language-cpp">srand(time(0));
int v[N] = { 0 };   //Array mit Geschwindigkeiten 0=keine Geschwindigkeit
int car[VEHICLE] = { 0 };    //Array mit Position der Fahrzeuge
int N = 30;         //z.B.
int VEHICLE = 7;   //bei 4 funktionierts noch
int V_MAX = 6;
int done = 0;
int count = 0;

while (!done) 
{
		int b = (int)(((double)rand()/(double)RAND_MAX)*N);		//generate number between 0 and 299 for position (array starts with 0)
		int j = b;							//j is the position
		cout &lt;&lt; &quot;j= &quot; &lt;&lt; j &lt;&lt; endl;

		for (int k=0; k&lt;VEHICLE; k++)	//multiple numbers are possible
		{
			if (j != car[k]) 
				count++;
		}

		if (count == VEHICLE)			//in order that array gets full 
		{
			int a = rand() % (V_MAX);	//generate number between 0 and 5 for velocity
			v[j] = a + 1;				//assign a velocity to each car (v+1, because no car is zero and zero velocity is 1)
			car[i] = j;
			done = 1;
		}
		int c = rand() %(N-1);
		j = c;
	}
	return;
</code></pre>
<p>Wie funktioniert eigentlich dieses srand(time(0))? Wird da immer die gleiche Zahl verwendet? Kann mir jemand sagen, wie man random number generiert, die fast alle Integer in einem Intervall abdecken?</p>
<p>Schon mal danke<br />
und Liebe Grüsse<br />
Nijntje</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/296611/random-number</link><generator>RSS for Node</generator><lastBuildDate>Fri, 14 Aug 2026 15:24:16 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/296611.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 08 Dec 2011 12:11:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 12:11:25 GMT]]></title><description><![CDATA[<p>Hallo Zusammen</p>
<p>Kann mir jemand bei meinem Problem helfen?</p>
<p>Ich habe ein Nasch-Modell (Verkehrssimulation) mit zellulären Automaten implementiert.<br />
Dabei möchte ich auf N Zellen zufällig VEHICLE Fahrzeuge positionieren (mit einer zufälligen Anfangsgeschwindigkeit).<br />
Wenn ich eine nicht so grosse Anzahl VEHICLE habe, funktioniert mein Code, wenn ich aber z.B. jede zweite Zelle besetzen möchte, funktioniert er nicht mehr, was ich eigentlich verstehe...<br />
Hier mal der Code: (Funktion mit int i als Parameter)</p>
<pre><code class="language-cpp">srand(time(0));
int v[N] = { 0 };   //Array mit Geschwindigkeiten 0=keine Geschwindigkeit
int car[VEHICLE] = { 0 };    //Array mit Position der Fahrzeuge
int N = 30;         //z.B.
int VEHICLE = 7;   //bei 4 funktionierts noch
int V_MAX = 6;
int done = 0;
int count = 0;

while (!done) 
{
		int b = (int)(((double)rand()/(double)RAND_MAX)*N);		//generate number between 0 and 299 for position (array starts with 0)
		int j = b;							//j is the position
		cout &lt;&lt; &quot;j= &quot; &lt;&lt; j &lt;&lt; endl;

		for (int k=0; k&lt;VEHICLE; k++)	//multiple numbers are possible
		{
			if (j != car[k]) 
				count++;
		}

		if (count == VEHICLE)			//in order that array gets full 
		{
			int a = rand() % (V_MAX);	//generate number between 0 and 5 for velocity
			v[j] = a + 1;				//assign a velocity to each car (v+1, because no car is zero and zero velocity is 1)
			car[i] = j;
			done = 1;
		}
		int c = rand() %(N-1);
		j = c;
	}
	return;
</code></pre>
<p>Wie funktioniert eigentlich dieses srand(time(0))? Wird da immer die gleiche Zahl verwendet? Kann mir jemand sagen, wie man random number generiert, die fast alle Integer in einem Intervall abdecken?</p>
<p>Schon mal danke<br />
und Liebe Grüsse<br />
Nijntje</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154584</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154584</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 12:11:25 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 12:23:03 GMT]]></title><description><![CDATA[<p>nijntje schrieb:</p>
<blockquote>
<p>Wenn ich eine nicht so grosse Anzahl VEHICLE habe, funktioniert mein Code, wenn ich aber z.B. jede zweite Zelle besetzen möchte, funktioniert er nicht mehr, was ich eigentlich verstehe...</p>
</blockquote>
<p>Gehst du, wenn du krank bist auch zum Arzt und sagst ihm, dass du nicht mehr funktionierst?</p>
<blockquote>
<p>Wie funktioniert eigentlich dieses srand(time(0))? Wird da immer die gleiche Zahl verwendet?</p>
</blockquote>
<p>Nein, es wird time(0) benutzt. Wenn du nicht weißt, was eine funktion macht, dannschau in einer Referenz nach.</p>
<blockquote>
<p>Kann mir jemand sagen, wie man random number generiert, die fast alle Integer in einem Intervall abdecken?</p>
</blockquote>
<p>Was meinst du mit &quot;fast alle&quot;? Meinst du damit eine konkrete Verteilung oder ist das nur ungeschickt ausgedrückt für gleichverteilt auf allen Werten? Falls letzteres: Gleichverteilte Zufallszahl von 0 bis RAND_MAX ziehen (das mach rand), modulo Intervallgröße (die bei dieser Methode kleiner sein muss als RAND_MAX) rechnen, Intervalluntergrenze addieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154588</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154588</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 08 Dec 2011 12:23:03 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 14:00:19 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Gleichverteilte Zufallszahl von 0 bis RAND_MAX ziehen (das mach rand), modulo Intervallgröße (die bei dieser Methode kleiner sein muss als RAND_MAX) rechnen, Intervalluntergrenze addieren.</p>
</blockquote>
<p>Würde ich mir, je nach Simulation, nochmal überlegen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154624</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154624</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Thu, 08 Dec 2011 14:00:19 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 14:36:03 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Würde ich mir, je nach Simulation, nochmal überlegen.</p>
</blockquote>
<p>Ach, ich mache selber Simulationen, solange RAND_MAX &gt;&gt; Breite des Intervalls (also der Normalfall) ist das gut genug. Locker. Das einzige, was ich überlegen würde, ist vielleicht was anderes als rand() zu nehmen, da man da nie weiß, was man bekommt. Ich habe sogar schon mehrmals Implementierungen mit RAND_MAX = 2^15 oder 2^16 gesehen und dann ist die obige Bedingung nicht mehr unbedingt erfüllt. Von der unzuverlässigen Qualität und dem globalen Zustand ganz zu schweigen.</p>
<p>edit: @Threadersteller: Worüber wir hier reden ist, dass die genannte Methode einen sehr kleinen Bias hin zu kleinen Werten hat, sofern die Intervallbreite keine Zweierpotenz ist. Wenn es eine perfekte Gleichverteilung sein soll, dann zieh erst Zahlen bis zur nächsthöheren Zweierpotenz und schmeiß dann Werte über der Intervallobergrenze weg. Aber dann möchtest du wahrscheinlich sowieso nicht rand benutzen sondern einen professionellen Zufallsgenerator, die solche Transformationen normalerweise schon fertig mit dabei haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154637</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154637</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 08 Dec 2011 14:36:03 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 15:49:02 GMT]]></title><description><![CDATA[<p>Sorry, ich verstehe da immer noch etwas nicht:</p>
<p>Was stimmt jetzt genau nicht an meinem Generator?</p>
<p>Wieso bekomme ich nicht nach einer gewissen Zeit, alle Zahlen zwischen 0 und 300 resp. die gewünschte Anzahl VEHICLE im Intervall [0, 299]?</p>
<p>Wenn ich modulo N rechne, habe ich doch das gleiche Problem. Je nach Zeit im srand() bekomme ich entweder die gewünschte Anzahl ausgespuckt und der Code läuft oder unendlich viele j werden auf dem Terminal ausgegeben und ich muss gewaltsam unterbrechen..</p>
<p>(P.S ich bin nicht aus der Informatikwelt, deshalb funktioniert's oder halt nicht...)</p>
<p>Ich muss diese Zellen nur irgendwie belegen, ich könnte theoretisch je nach Dichte auch jede i. Zelle besetzen, aber mit Zufallsgenerator wäre es professioneller.</p>
<p>Ach und danke!!! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154680</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 15:49:02 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 16:08:00 GMT]]></title><description><![CDATA[<p>nijntje schrieb:</p>
<blockquote>
<pre><code class="language-cpp">srand(time(0));
int v[N] = { 0 };   //Array mit Geschwindigkeiten 0=keine Geschwindigkeit
int car[VEHICLE] = { 0 };    //Array mit Position der Fahrzeuge
int N = 30;         //z.B.
int VEHICLE = 7;   //bei 4 funktionierts noch
int V_MAX = 6;
int done = 0;
int count = 0;
</code></pre>
</blockquote>
<p>Mal eine Zwischenfrage: Stehen die Definitionen der Arrays genau so auch in deinem Quelltext? Und was meinst du mit &quot;mein Code funktioniert nicht&quot;? Bitte etwas genauer werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154683</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154683</guid><dc:creator><![CDATA[hmpf]]></dc:creator><pubDate>Thu, 08 Dec 2011 16:08:00 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 16:26:37 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;fstream&gt;

using namespace std;

const int N = 30;	//number of cells
const int V_MAX = 6;	//maximum velocity
const int VEHICLE = 8;	//number of cars

void initial (int, int*, int*);

int main () 
{	
    srand(33);			//set random generator (time(NULL))

	int v[N] = { 0 };	//speed of each vehicle on cell j
	int car[VEHICLE] = { 0 };		//cellnumber of vehicle number i
	int speed_car[VEHICLE] = { 0 };		//speed of car i
	int i;

	for (i=0; i&lt;VEHICLE; i++)  
		initial(i, v, car);	
return 0;
}

void initial (int i, int *v, int *car)		
{
	int done = 0;
	int count = 0;

	while (!done) 
	{
		int b = rand() %N;				//generate number between 0 and 299 for position (array starts with 0)
		int j = b;					//j is the position
		cout &lt;&lt; &quot;j= &quot; &lt;&lt; j &lt;&lt; endl;

		for (int k=0; k&lt;VEHICLE; k++)	//multiple numbers are possible
		{
			if (j != car[k]) 
				count++;
		}

		if (count == VEHICLE)			//in order that array gets full 
		{
			int a = rand() % (V_MAX);	//generate number between 0 and 5 for velocity
			v[j] = a + 1;			//assign a velocity to each car (v+1, because no car is zero and zero velocity is 1)
			car[i] = j;
			done = 1;
		}

	}
	return;						
}
</code></pre>
<p>Also wenn VEHICLE so wie hier gross ist im Vergleich zu N, dann muss ich das Terminal gewaltsam beenden. Mit cout lasse ich mir die Zufallszahlen zur Kontrolle ausdrucken, diese werden dann endlos ausgegeben. Ist VEHICLE klein (z.B 3), dann bekomme ich die gewünschten Zufallszahlen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154690</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154690</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 16:26:37 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 16:41:41 GMT]]></title><description><![CDATA[<p>Das hat nichts mit Zufallszahlen zu tun, dein Algorithmus ist schlichtweg falsch. Falls du die Bedingung <code>count == VEHICLE</code> verpasst, dann hat die Schleife keine Chance mehr, jemals zu beenden.</p>
<p>Wenn man nun wusste, was dein Programm überhaupt genau machen soll, könnte man die vielleicht sogar helfen, aber du machst da ja anscheinend ein Geheimnis raus. Und aus dem Programm selbst wird man dank verwirrender Bezeichner auch nicht schlau.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154692</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 08 Dec 2011 16:41:41 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 16:59:29 GMT]]></title><description><![CDATA[<p>Ich dachte ich hätte das ganz am Anfang beschrieben. sogar im Code steht was ich mache.<br />
Eigentlich ganz simpel:<br />
Auf N Zellen (einspurige Strasse) zufällig Fahrzeuge (VEHICLE) mit zufälliger Anfangsgeschwindigkeit setzen.<br />
Da ich noch Anfängerin bin, ist klar, dass nicht alles perfekt ist. Was ist genau verwirrend?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154697</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154697</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 16:59:29 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 17:31:27 GMT]]></title><description><![CDATA[<p>Irgendwelche Nebenbedingungen? Z.B. darf eine Zelle mehrfach besetzt sein? Bist du dir sicher mit dem Design, also Position und Geschwindigkeit der Autos getrennt zu halten und eine Zellenliste mit den Geschwindigkeiten zu haben? Ich finde das ungewöhnlich.</p>
<blockquote>
<p>Was ist genau verwirrend?</p>
</blockquote>
<p>Zum Beispiel, dass VEHICLE die Anzahl der Fahrzeuge ist und car die Position der Fahrzeuge.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154702</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154702</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 08 Dec 2011 17:31:27 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 18:03:41 GMT]]></title><description><![CDATA[<p>Nein, keine Nebenbedingungen. Die Zellen haben die Grösse, die ein Auto in einer Stausituation annehmen würde.</p>
<p>Ja, ich bin mir sicher mit dem Design, ich habe eigentlich schon alles implementiert. Man kann das sicher viel geschickter machen, aber dafür bin ich noch zu unerfahren.<br />
Erst beim Ändern der Anzahl Zellen bzw. Fahrzeuge habe ich diesen Fehler in der Initialisierung bemerkt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154708</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154708</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 18:03:41 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 22:50:49 GMT]]></title><description><![CDATA[<p>Ich zeige dir mal,wie man so etwas machen kann:</p>
<pre><code class="language-cpp">// so, machen wir das mal objektorientiert:

// Zunächst mal machen wir, dass Car/vehicle auch wirklich ein
// Auto sind und keine Geschwindigkeit. Aber sie haben eine
// Geschwindigkeit. 

class Car
{
  int speed;
};

// Einer Zelle kann ein Auto zugeordnet sein oder auch nicht.
class Cell
{
  Car *car;
};

// Eine Straße besteht aus vielen Zellen. Ich nehme mal periodische 
// Randbedingungen an. Damit wir die nicht von alleine ausrechnen müssen
// nehmen wir einen Ringpuffer. Da du vermutlich da drauf stehst, das Rad
// zum 543737377ten Mal neu zu erfinden, schreiben wir unseren eigenen:
#include &quot;circular_buffer.h&quot;
class Street
{
  CircularBuffer&lt;Cell&gt; cells;
};
</code></pre>
<p>circular_buffer.h:</p>
<pre><code class="language-cpp">#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H

// Wir schreiben natürlich nicht alles selbst. Die Haupt-
// arbeit übernimmt vector. Wir rechnen bloß die Indizes um.
#include &lt;vector&gt;

// Da wir nur einen Bruchteil der Funktionalität brauchen,
// machen wir mal kein vollständiges STL-kompatibles Interface.
// Wenn wir ambitioniert sind, können wir das nachholen, dann
// kann man den Puffer auch für andere Dinge benutzen.
template&lt;class ElementType&gt; class CircularBuffer
{
  std::vector&lt;ElementType&gt; data;
 public:
  // Als öffentliches Interface brauchen wir bloß Zugriffe und
  // die Größe.
  std::size_t size() const { return data.size(); }
  const ElementType&amp; operator[](std::size_t pos) const
  { return data[pos % size()]; }
  ElementType&amp; operator[](std::size_t pos)
  { return data[pos % size()]; }

  // Außerdem einen Konstruktor, bei dem wir die Größe angeben
  // können
 CircularBuffer(std::size_t size): data(size) {}

  // Und zu guter letzt ein paar Iteratoren, damit wir schöne
  // Algorithmen schreiben können
  class iterator
  {
    CircularBuffer &amp;buf;
    std::size_t pos;
  public:
    // Auch hier ein sehr abgespecktes Interface
    ElementType&amp; operator*() const { return buf[pos]; }
    ElementType* operator-&gt;() const { return &amp;buf[pos]; }
    iterator&amp; operator++() { ++pos; return *this; }
    iterator&amp; operator+=(std::size_t rhs) 
      { pos += rhs; return *this; }
    explicit iterator(CircularBuffer const&amp; buf, std::size_t pos=0)
      : buf(buf), pos(pos) {}
  };
  class const_iterator
  {
    CircularBuffer &amp;buf;
    std::size_t pos;
  public:
    // Auch hier ein sehr abgespecktes Interface
    const ElementType&amp; operator*() const { return buf[pos]; }
    const ElementType* operator-&gt;() const { return &amp;buf[pos]; }
    const_iterator&amp; operator++() {pos = (pos+1) % buf.size(); return *this;}
    const_iterator&amp; operator+=(std::size_t rhs) 
      { pos = (pos+rhs) % buf.size(); return *this; }
    explicit const_iterator(CircularBuffer const&amp; buf, std::size_t pos=0)
     : buf(buf), pos(pos) {}
  };
};

template&lt;class ElementType&gt; 
const CircularBuffer&lt;ElementType&gt;::iterator
operator+(CircularBuffer&lt;ElementType&gt;::iterator const &amp;lhs, std::size_t rhs)
{ 
  CircularBuffer&lt;ElementType&gt;::iterator tmp(lhs);
  tmp += rhs;
  return tmp;
}

template&lt;class ElementType&gt; 
const CircularBuffer&lt;ElementType&gt;::const_iterator
operator+(CircularBuffer&lt;ElementType&gt;::constiterator const &amp;lhs, std::size_t rhs)
{ 
  CircularBuffer&lt;ElementType&gt;::const_iterator tmp(lhs);
  tmp += rhs;
  return tmp;
}

// So, das sollte eigentlich schon reichen.

#endif
</code></pre>
<p>Zurück zum Hauptprogramm. Wie müssen irgendwie simulieren. Dazu müssen alle Objekte einen Zeitschritt weiter. Wir gehen das ganze von unten nach oben an und so sollte man das auch lesen:</p>
<pre><code class="language-cpp">// Das Include kommt nach oben, wie es sich gehört.
// Außerdem müssen die anderen Klassen auch sehen,
// wie ein Iterator aussieht.
#include &quot;circular_buffer.h&quot;
// Damit wir nicht so viel schreiben müssen, machen wir einen typedef.
// Das ist auch gut, wenn sich herausstellt, dass unsere Containerwahl
// nicht gut war.
typedef CircularBuffer&lt;Cell&gt; CellsType;

class Car
{
  int speed;
  // Führe eine Maximalgeschwindigkeit ein. Zunächst
  // einmal global. Vielleicht wird das später mal
  // für jedes Auto individuell.
  static int max_speed = 10;
public:
  void drive_forward(CellsType::iterator it)
  {
    // Auto fährt um bis zu speed Zellen weiter
    // Wenn in der Zelle vor ihm ein Auto ist,
    // wird gebremst. Wenn ungebremst gefahren wurde,
    // wird beschleunigt bis zur Maximalgeschwindigkeit.

  }
};

class Cell
{
  Car *car;
public:
  void advance_timestep(CellsType::iterator it)
  {
    // Wenn die Zelle ein Auto hat, dann soll das Auto weiterfahren
    if (car)
      {
        Car *old_car = car;
        car = 0; // Das Auto verlässt die Zelle
        old_car-&gt;drive_forward(it); // Und fährt weiter
      }
  }
};

#include &quot;circular_buffer.h&quot;
class Street
{
  CellsType cells;

public:
  // Nun der Kern der Simulation. Die Straße aktualisiert die Zellen
  void advance_timestep()
  {
    for (CellsType::iterator it = cells.begin(); it != cells.end(); ++it)
      {
        it-&gt;advance_timestep(it);
      }
  }
};
</code></pre>
<p>Nun laufen wir in ein Problem, da wir unser Projekt nicht sauber modularisiert haben, sondern alles in eine Datei geschrieben haben. Die Autos brauchen zum Update Zugriff auf die Methoden der Zellen. Teile daher das Projekt nun Deklarationen und Implementierung auf. Vorher compileren wir einmal, um zu sehen, ob wir was falsch gemacht haben:</p>
<pre><code>[b]$&gt; g++ test.cc -Wextra -Wall -Weffc++[/b]
In file included from test.cc:4:
circular_buffer.h:63: error: expected initializer before ‘operator’
circular_buffer.h:72: error: expected initializer before ‘operator’
test.cc:8: error: ‘Cell’ was not declared in this scope
test.cc:8: error: template argument 1 is invalid
test.cc:8: error: invalid type in declaration before ‘;’ token
test.cc:16: error: ISO C++ forbids in-class initialization of non-const static member ‘max_speed’
test.cc:18: error: ‘CellsType’ is not a class or namespace
test.cc:18: error: expected ‘,’ or ‘...’ before ‘it’
test.cc:18: warning: unused parameter ‘iterator’
test.cc:34: error: ‘CellsType’ is not a class or namespace
test.cc:34: error: expected ‘,’ or ‘...’ before ‘it’
test.cc: In member function ‘void Cell::advance_timestep(int)’:
test.cc:41: error: ‘it’ was not declared in this scope
test.cc: At global scope:
test.cc:34: warning: unused parameter ‘iterator’
test.cc: In member function ‘void Street::advance_timestep()’:
test.cc:58: error: expected initializer before ‘it’
test.cc:58: error: ‘it’ was not declared in this scope
test.cc:58: error: request for member ‘end’ in ‘((Street*)this)-&gt;Street::cells’, which is of non-class type ‘CellsType’
</code></pre>
<p>Ahh, ja:</p>
<pre><code>circular_buffer.h:63: error: expected initializer before ‘operator’
circular_buffer.h:72: error: expected initializer before ‘operator’
</code></pre>
<p>Bei den Operatoren haben wir vergessen, dass wir typename vor von Templates abgeleitete Typen schreiben müssen. Passiert. Einfach nachtragen. Aber eigentlich brauchen wir sowieso keine Konvertierungen. Daher ab als Memberfunktion, das spart Platz und Scherereien mit der Argumentenauflösung.</p>
<pre><code>test.cc:8: error: ‘Cell’ was not declared in this scope
test.cc:8: error: template argument 1 is invalid
test.cc:8: error: invalid type in declaration before ‘;’ token
</code></pre>
<p>Eine Äußerung des angesprochenen Problems.</p>
<pre><code>test.cc:16: error: ISO C++ forbids in-class initialization of non-const static member ‘max_speed’
</code></pre>
<p>Ups, klar, das muss const sein.</p>
<pre><code>[...]
</code></pre>
<p>Viele Folgefehler.</p>
<pre><code>test.cc:58: error: request for member ‘end’ in ‘((Street*)this)-&gt;Street::cells’, which is of non-class type ‘CellsType’
</code></pre>
<p>Und beim Ringpuffer haben wir begin und end vergessen. so, dann sortieren wir mal um. Außerdem werden wir die const_iteratoren niemals brauchen, daher kürze ich sie raus. Dann sieht das so aus und compiliert wunderbar, tut aber noch nix:</p>
<pre><code class="language-cpp">#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H

#include &lt;vector&gt;

template&lt;class ElementType&gt; class CircularBuffer
{
  std::vector&lt;ElementType&gt; data;
 public:
  std::size_t size() const { return data.size(); }
  const ElementType&amp; operator[](std::size_t pos) const
  { return data[pos % size()]; }
  ElementType&amp; operator[](std::size_t pos)
  { return data[pos % size()]; }

 CircularBuffer(std::size_t size): data(size) {}

  class iterator
  {
    CircularBuffer &amp;buf;
    std::size_t pos;
  public:
    ElementType&amp; operator*() const { return buf[pos]; }
    ElementType* operator-&gt;() const { return &amp;buf[pos]; }
    iterator&amp; operator++() { ++pos; return *this; }
    iterator&amp; operator+=(std::size_t rhs) 
      { pos += rhs; return *this; }
    // Noch ein kleiner Fehler hier, Referenz darf nicht const sein
    explicit iterator(CircularBuffer &amp; buf, std::size_t pos=0)
      : buf(buf), pos(pos) {}
    // Und den Operator != vergessen
    bool operator!=(const iterator&amp; rhs)
    { return &amp;buf != &amp;rhs.buf or pos != rhs.pos; }
    const  iterator operator+(std::size_t rhs) const
    { iterator tmp(*this); tmp += rhs; return tmp; }
  };

  iterator begin() { return iterator(*this); }
  iterator end() { return iterator(*this, size()); }
};

#endif
</code></pre>
<pre><code class="language-cpp">#include &quot;circular_buffer.h&quot;

class Cell;
typedef CircularBuffer&lt;Cell&gt; CellsType;

class Car
{
  int speed;
  static const int max_speed = 10;
public:
  void drive_forward(CellsType::iterator it);
};

class Cell
{
  Car *car;
public:
  void advance_timestep(CellsType::iterator it);
};

class Street
{
  CellsType cells;
public:
  void advance_timestep();
};

void Car::drive_forward(CellsType::iterator it)
{
}

void Cell::advance_timestep(CellsType::iterator it)
{
  // Wenn die Zelle ein Auto hat, dann soll das Auto weiterfahren
  if (car)
    {
      Car *old_car = car;
      car = 0; // Das Auto verlässt die Zelle
      old_car-&gt;drive_forward(it); // Und fährt weiter
    }
}

void Street::advance_timestep()
{
  for (CellsType::iterator it = cells.begin(); it != cells.end(); ++it)
    {
      it-&gt;advance_timestep(it);
    }
}
</code></pre>
<p>Eigentlich würde man ja stärker in einzelne Dateien trennen, aber das kommt im Forum nicht gut.</p>
<p>So, nun kann man den eigentlichen Algorithmus implementieren. Außerdem noch ein bisschen Boilerplatecode:</p>
<pre><code class="language-cpp">#include &quot;circular_buffer.h&quot;

class Cell;
typedef CircularBuffer&lt;Cell&gt; CellsType;

class Car
{
  int speed;
  static const int max_speed = 10;
public:
  void drive_forward(CellsType::iterator it);
  Car(int speed = 0);
};

class Cell
{
  Car *car;
public:
  void advance_timestep(CellsType::iterator it);
  bool is_empty() const;
  void set_car(Car* new_car);
  Cell();
};

class Street
{
  CellsType cells;
public:
  void advance_timestep();
  void set_car(Car * car, std::size_t pos);
  Street(std::size_t length);
};

void Car::drive_forward(CellsType::iterator it)
{
  // Suche letztes freies Feld in Reichweite
  for (int current_speed = 0; current_speed &lt;= speed; ++current_speed)
    {
      if (!(it+current_speed+1)-&gt;is_empty()) 
        {
          // Im Feld vor uns ist ein Auto. Passe Geschwindigkeit an
          speed = current_speed;
          // Und setze unser Auto auf das Feld davor
          (it+speed)-&gt;set_car(this);
          return;
        }
    }
  // Kein anderes Auto gesehen: Umsetzen und Beschleunigen
  (it+speed)-&gt;set_car(this);
  if (speed &lt; max_speed) ++speed;
}
Car::Car(int speed): speed(speed) {}

void Cell::advance_timestep(CellsType::iterator it)
{
  // Wenn die Zelle ein Auto hat, dann soll das Auto weiterfahren
  if (car)
    {
      Car *old_car = car;
      car = 0; // Das Auto verlässt die Zelle
      old_car-&gt;drive_forward(it); // Und fährt weiter
    }
}
bool Cell::is_empty() const { return !car; }
void Cell::set_car(Car *new_car) {car = new_car;}
Cell::Cell(): car(0) {}

void Street::advance_timestep()
{
  for (CellsType::iterator it = cells.begin(); it != cells.end(); ++it)
    {
      it-&gt;advance_timestep(it);
    }
}
void Street::set_car(Car * car, std::size_t pos) {cells[pos].set_car(car);}
Street::Street(std::size_t length): cells(length) {}
</code></pre>
<p>Außerdem sollte der Konstruktor des Ringpuffers natürlich explicit sein, wie mir aber erst hier auffiel. So, Zeit ein kleines Testprogramm zu schreiben. Dazu werden noch ein paar Ausgabeoperatoren geschrieben und ein kleines Beispiel aufgesetzt:</p>
<pre><code class="language-cpp">// Diese Funktionen sind allesamt Friends der jeweiligen Klasse:
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Car&amp; rhs)
{ return out &lt;&lt; rhs.speed; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Cell&amp; rhs)
{ if (!rhs.is_empty()) out &lt;&lt; *rhs.car; else out &lt;&lt; ' '; return out; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Street&amp; rhs)
{
  out &lt;&lt; '|';
  for(std::size_t i=0; i &lt; rhs.cells.size(); ++i) out &lt;&lt; rhs.cells[i];
  out &lt;&lt; '|';
  return out; 
}

int main()
{
  std::vector&lt;Car&gt; cars(2);
  Street street(70);
  street.set_car(&amp;cars[0],0);
  std::cout &lt;&lt; street &lt;&lt; '\n';
  for (int i = 0; i &lt; 10; ++i)
    {
      street.advance_timestep();
      std::cout &lt;&lt; street &lt;&lt; '\n';
    }
}
</code></pre>
<p>So, und nun der große Augenblick, auf den wir alle gewartet haben:</p>
<pre><code>|0                                                                     |
|1                                                                     |
|  9                                                                   |
|    9                                                                 |
|      9                                                               |
|        9                                                             |
| 9                                                                    |
|   9                                                                  |
|     9                                                                |
|       9                                                              |
|9                                                                     |
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f621.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--pouting_face"
      title=":rage:"
      alt="😡"
    /></p>
<p>Das war wohl nix.</p>
<p>Ok, kurz mit dem Debugger drüber. Wenn ein Auto weiterfährt, wird es auch vom Update der nächsten Zelle erfasst, wodurch es immer weiter fährt. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /> Das war auch eine Murksiddee, das so zu machen. <strong>Eine Straße fährt kein Auto, ein Auto fährt auf der Straße!</strong> Dafür bekommt das Auto nun eine Position. Eigentlich hatte ich das gleich so vor, aber ich wollte mich möglichst an dein ursprüngliches Design halten. Aber das war wohl nicht so gut. Noch ein paar kleine Änderungen am Ringpuffer (zeige ich am Ende) und das Programm sieht so aus:</p>
<pre><code class="language-cpp">class Car
{
  int speed;
  CellsType::iterator pos;
  static const int max_speed = 9;
public:
  void drive_forward();
  void hit_the_road();
  Car(int speed, CellsType::iterator pos);
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Car&amp;);
};

class Cell
{
  Car *car;
public:
  bool is_empty() const;
  void set_car(Car* new_car);
  Cell();
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Cell&amp;);
};

class Street
{
  CellsType cells;
public:
  Street(std::size_t length);
  CellsType::iterator get_pos(std::size_t pos);
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Street&amp;);
};

void Car::drive_forward()
{
  pos-&gt;set_car(0);
  int current_speed = 0;
  for (; current_speed &lt;= speed; ++current_speed)
    {
      if (!(pos+current_speed+1)-&gt;is_empty()) 
        {
          speed = current_speed-1;
          break;  
        }
    }
  pos+=current_speed;
  hit_the_road();
  if (speed &lt; max_speed) ++speed;
}
void Car::hit_the_road() { pos-&gt;set_car(this); }
Car::Car(int speed, CellsType::iterator pos): speed(speed), pos(pos) {}

bool Cell::is_empty() const { return !car; }
void Cell::set_car(Car *new_car) {car = new_car;}
Cell::Cell(): car(0) {}

Street::Street(std::size_t length): cells(length) {}
CellsType::iterator Street::get_pos(std::size_t pos) { return cells.begin()+pos; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Car&amp; rhs)
{ return out &lt;&lt; rhs.speed; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Cell&amp; rhs)
{ if (!rhs.is_empty()) out &lt;&lt; *rhs.car; else out &lt;&lt; ' '; return out; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Street&amp; rhs)
{
  out &lt;&lt; '|';
  for(std::size_t i=0; i &lt; rhs.cells.size(); ++i) out &lt;&lt; rhs.cells[i];
  out &lt;&lt; '|';
  return out; 
}

int main()
{
  std::vector&lt;Car&gt; cars;
  Street street(70);
  cars.push_back(Car(7,street.get_pos(0)));
  cars.push_back(Car(0,street.get_pos(5)));

  for (std::size_t i=0; i &lt; cars.size(); ++i)
    cars[i].hit_the_road();

  std::cout &lt;&lt; street &lt;&lt; '\n';
  for (int i = 0; i &lt; 20; ++i)
    {
      for (std::size_t i=0; i &lt; cars.size(); ++i)
        cars[i].drive_forward();
      std::cout &lt;&lt; street &lt;&lt; '\n';
    }
}
</code></pre>
<pre><code>|7    0                                                                |
|    4 1                                                               |
|     1  2                                                             |
|       2   3                                                          |
|          3    4                                                      |
|              4     5                                                 |
|                   5      6                                           |
|                         6       7                                    |
|                                7        8                            |
|                                        8         9                   |
|                                                 9          9         |
|9                                                          9          |
|          9                                                          9|
|         9          9                                                 |
|                   9          9                                       |
|                             9          9                             |
|                                       9          9                   |
|                                                 9          9         |
|9                                                          9          |
|          9                                                          9|
|         9          9                                                 |
</code></pre>
<p>Sieht doch schon sehr gut aus. Aber das gibt nur Kolonnenfahren, deswegen mache ich die Höchstgeschwindigkeit variabel, aber das zeige ich jetzt nicht explizit. <strong>Nun zu deiner Ursprungsfrage, wie man so ein System aufsetzen kann</strong>. Nun, eigentlich hat sich die Frage durch gutes Design bereits erledigt, weil wir nun trivial Autos auf der Straße verteilen können. Das Ziehen der Positionen entspricht dem Ziehen von N aus M Zahlen ohne Zurücklegen. Da ich aber gerade faul bin, mische ich einfach M Karten und nehme die obersten N. Da das ganze nur einmal am Anfang des Programms geschieht, ist Performance dafür herzlich egal.</p>
<pre><code class="language-cpp">#include &lt;algorithm&gt;
#include &lt;ctime&gt;
#include &lt;cstdlib&gt;
using namespace std;
int main()
{
  srand(time(0));
  const size_t street_length = 80;  
  const size_t num_cars = 18;

  std::vector&lt;int&gt; positions(street_length);
  for(size_t i=0; i &lt; street_length; ++i) positions[i]=i;
  random_shuffle(positions.begin(), positions.end());

  std::vector&lt;Car&gt; cars;
  Street street(street_length);
  for(size_t i=0; i &lt; num_cars; ++i)
    cars.push_back(Car(rand()%4,street.get_pos(positions[i]), rand()%4+4));

 // und weiter wie oben
</code></pre>
<p>Mal sehen:</p>
<pre><code>|     0     3   2 3 33   10       1    3 3     2  3              33        3 3  3|
|   4  1       3  21   330 1        2      4 4    3   4              44       32 |
|33   2  2       2  22 00 1  2         3        54    4    5              44     |
|   33  2   3      2 11 11  2   3          4        44     5     5             44|
| 33  22   3    4   1 11  22   3    4           5        55      5     5         |
|   22   33    4    41  22   33    4     5            6        66      5     5   |
|  5   33    44    4  22   33    44     4      5             6       66      5   |
|  5  3    44    44  2   33    44     55     4       5              6      66    |
|66      54    44  22   3    44     55     55     4        5               6     |
| 6    66    44  22   33    4     55     55     55     4         5               |
|        6 44  22   33    44     5     55     55     55     4          5         |
|           322   33    44     55     5     55     55     55     4           5   |
|  5           333    44     44     55     5     55     55     55     4          |
|        5         444     55     44     55     5     55     55     55     4     |
|              5        555     55     44     55     5     55     55     55     4|
|    4               5       555     55     44     55     5     55     55     55 |
|  55     4                5      555     55     44     55     5     55     55   |
|55     55     4                 5     555     55     44     55     5     55     |
|     55     55     4                 5     555     55     44     55     5     55|
|   55     55     55     4                 5     555     55     44     55     5  |
|  5     55     55     55     4                 5     555     55     44     55   |
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /> :xmas1:<br />
Das ist doch hübsch. Erst gibt's einen kleinen Stau, dann passen alle ihre Geschwindigkeit an und fahren in Kolonne. So wie man es auf der Autobahn machen sollte. Jetzt müsste man noch spielen und unterschiedlich aggressive Fahrer einbauen, die trotzdem Gas geben. Und mehrere Spuren. Aber das ist dein Projekt. Hier mal das ganze Programm, damit du da drauf aufbauen kannst. Kommentare sind in dieser letzten Fassung größtenteils draußen, in diesem Post ist hoffentlich genug erklärt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> .</p>
<p>circular_buffer.h (Kein Ruhmesblatt, da fehlte Entwicklungszeit. Nimm vielleicht besser was fertiges):</p>
<pre><code class="language-cpp">#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H

#include &lt;vector&gt;

template&lt;class ElementType&gt; class CircularBuffer
{
  std::vector&lt;ElementType&gt; data;
 public:
  std::size_t size() const { return data.size(); }
  const ElementType&amp; operator[](std::size_t pos) const
  { return data[pos % size()]; }
  ElementType&amp; operator[](std::size_t pos)
  { return data[pos % size()]; }

  // Dieser Konstruktor sollte explicit sein
 explicit CircularBuffer(std::size_t size): data(size) {}

  class iterator
  {
    // Nehme einen Zeiger, damit man das Objekt trivial kopieren kann
    CircularBuffer *buf;
    std::size_t pos;
  public:
    ElementType&amp; operator*() const { return (*buf)[pos]; }
    ElementType* operator-&gt;() const { return &amp;(*buf)[pos]; }
    iterator&amp; operator++() { ++pos; return *this; }
    iterator&amp; operator+=(std::size_t rhs) 
      { pos+=rhs; return *this; }
    explicit iterator(CircularBuffer * buf, std::size_t pos=0)
      : buf(buf), pos(pos) {}
    bool operator!=(const iterator&amp; rhs)
    { return buf != rhs.buf or pos != rhs.pos; }
    const  iterator operator+(std::size_t rhs) const
    { iterator tmp(*this); tmp += rhs; return tmp; }
 };

  iterator begin() { return iterator(this); }
  iterator end() { return iterator(this, size()); }
};

#endif
</code></pre>
<p>Und das Hauptprogramm (alles an einem Stück. Naja, nicht gerade übersichtlich, macht es aber dem Compiler einfach zu optimieren, wenn du mal lange Läufe (ohne Ausgabe zwischendrin machst):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

#include &quot;circular_buffer.h&quot;

class Cell;
typedef CircularBuffer&lt;Cell&gt; CellsType;

class Car
{
  int speed;
  CellsType::iterator pos;
  int max_speed;
public:
  void drive_forward();
  void hit_the_road();
  Car(int speed, CellsType::iterator pos, int max_speed);
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Car&amp;);
};

class Cell
{
  Car *car;
public:
  bool is_empty() const;
  void set_car(Car* new_car);
  Cell();
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Cell&amp;);
};

class Street
{
  CellsType cells;
public:
  Street(std::size_t length);
  CellsType::iterator get_pos(std::size_t pos);
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Street&amp;);
};

void Car::drive_forward()
{
  pos-&gt;set_car(0);
  int current_speed = 0;
  for (; current_speed &lt;= speed; ++current_speed)
    {
      if (!(pos+current_speed+1)-&gt;is_empty()) 
        {
          speed = current_speed-1;
          break;  
        }
    }
  pos+=current_speed;
  hit_the_road();
  if (speed &lt; max_speed) ++speed;
}
void Car::hit_the_road() { pos-&gt;set_car(this); }
Car::Car(int speed, CellsType::iterator pos, int max_speed)
  : speed(speed), pos(pos), max_speed(max_speed) {}

bool Cell::is_empty() const { return !car; }
void Cell::set_car(Car *new_car) {car = new_car;}
Cell::Cell(): car(0) {}

Street::Street(std::size_t length): cells(length) {}
CellsType::iterator Street::get_pos(std::size_t pos) { return cells.begin()+pos; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Car&amp; rhs)
{ return out &lt;&lt; rhs.speed; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Cell&amp; rhs)
{ if (!rhs.is_empty()) out &lt;&lt; *rhs.car; else out &lt;&lt; ' '; return out; }

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Street&amp; rhs)
{
  out &lt;&lt; '|';
  for(std::size_t i=0; i &lt; rhs.cells.size(); ++i) out &lt;&lt; rhs.cells[i];
  out &lt;&lt; '|';
  return out; 
}

#include &lt;algorithm&gt;
#include &lt;ctime&gt;
#include &lt;cstdlib&gt;
using namespace std;
int main()
{
  srand(time(0));
  const size_t street_length = 80;  
  const size_t num_cars = 18;

  std::vector&lt;int&gt; positions(street_length);
  for(size_t i=0; i &lt; street_length; ++i) positions[i]=i;
  random_shuffle(positions.begin(), positions.end());

  std::vector&lt;Car&gt; cars;
  Street street(street_length);
  for(size_t i=0; i &lt; num_cars; ++i)
    cars.push_back(Car(rand()%4,street.get_pos(positions[i]), rand()%4+4));

  for (std::size_t i=0; i &lt; cars.size(); ++i)
    cars[i].hit_the_road();

  std::cout &lt;&lt; street &lt;&lt; '\n';
  for (int i = 0; i &lt; 20; ++i)
    {
      for (std::size_t i=0; i &lt; cars.size(); ++i)
        cars[i].drive_forward();
      std::cout &lt;&lt; street &lt;&lt; '\n';
    }
}
</code></pre>
<p>Zu beachten ist noch, dass irgendwann der Index vom Ringpuffer überlaufen wird, da dieser absolut gespeichert wird. Das ist zwar einerseits gut, da du so feststellen kannst, wie viele Runden ein Auto gefahren ist. Aber du kannst das Programm nicht Ewigkeiten durchlaufen lassen - irgendwann hat ein Rechner dann nämlich auch mal ausgezählt. Je nach Maximalgeschwindigkeit müssten bei einem 64-Bit Wert aber mehrere Jahrzehnte drin. Bei einem 32-Bit System wird das aber wesentlich eher überlaufen. Und ich mag gerade nicht analysieren, was dann passiert. Da alles unsigned ist, könnte das sogar gut gehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154786</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154786</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 08 Dec 2011 22:50:49 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Thu, 08 Dec 2011 23:33:52 GMT]]></title><description><![CDATA[<p>Wow, vielen dank. Werde mir das morgen nochmal genauer ansehen. Ist ja ein richtiger Kurs. Das hast du dir in dieser zeit schnell aus dem Ärmel geschüttelt?! Super...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2154799</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2154799</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Thu, 08 Dec 2011 23:33:52 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Fri, 16 Dec 2011 13:14:59 GMT]]></title><description><![CDATA[<p>Hallo Seppj</p>
<p>zuerst möchte ich mich nochmal bedanken, dass du dir die zeit genommen hast mir das alles zu erklären.</p>
<p>darf ich dazu nochwas fragen?? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>aus dem main() am schluss:</p>
<blockquote>
<pre><code class="language-cpp">for(size_t i=0; i &lt; street_length; ++i) positions[i]=i; 
  random_shuffle(positions.begin(), positions.end()); 

  std::vector&lt;Car&gt; cars; 
  Street street(street_length); 
  for(size_t i=0; i &lt; num_cars; ++i) 
    cars.push_back(Car(rand()%4,street.get_pos(positions[i]), rand()%4+4)); 
  
  for (std::size_t i=0; i &lt; cars.size(); ++i) 
    cars[i].hit_the_road();
</code></pre>
</blockquote>
<p>woher hast du dieses random_shuffle?<br />
kann ich das immer nehmen, wenn ich zufallszahlen brauche (ohne zurücklegen)?</p>
<p>was meinst du mit hit_the_road?</p>
<p>und:</p>
<blockquote>
<pre><code class="language-cpp">cars.push_back(Car(rand()%4,street.get_pos(positions[i]), rand()%4+4));
</code></pre>
</blockquote>
<p>hier verstehe ich eigentlich die ganze zeile nicht.<br />
(wieso modulo4, woher kommt push_back)</p>
<p>grüsse<br />
nijntje</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2157681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2157681</guid><dc:creator><![CDATA[nijntje]]></dc:creator><pubDate>Fri, 16 Dec 2011 13:14:59 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Fri, 16 Dec 2011 13:16:38 GMT]]></title><description><![CDATA[<p>push_back ist eine Memberfunktion von std::vector, sie fügt ein Element hinten an. random_shuffle, oder mit vollem Namen std::random_shuffle ist ein Algorithmus aus der Standardbibliothek, der einen Bereich von Elementen zufällig mischt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2157683</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2157683</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Fri, 16 Dec 2011 13:16:38 GMT</pubDate></item><item><title><![CDATA[Reply to random number on Fri, 16 Dec 2011 13:42:50 GMT]]></title><description><![CDATA[<p>Die magische Zahl 4 ist nur für das Beispiel. Ich möchte eine Anfangsgeschwindigkeit von 0 bis 3 und eine Maximalgeschwindigkeit von 4 bis 7. Das kamen mir wie gute Werte für ein übersichtliches Beispiel vor.</p>
<p>Die hit_the_road Funktion macht, dass die Autos sich mal bei der Zelle melden, in der sie gerade sind. Meinetwegen sei in jeder Zelle ein Sensor, so könnte man das erklären. Zweck der Geschichte ist, dass man dann die Straße in einem Rutsch zeichnen kann, anstatt erst die Straße und dann die Autos da drauf, wie es natürlicher wäre. Aber das zeichnen von Autos an eine bestimmte Position ist in C++ etwas, was über ein schnelles Beispielprogramm hinausgeht, daher habe ich das nicht so gemacht. Außerdem kann man so die Kollisionsabfrage sehr vereinfachen, da man gucken kann, ob die Zelle vor dem Auto frei ist, anstatt zu gucken, welches Auto vor einem fährt und wie weit es noch weg ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2157700</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2157700</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 16 Dec 2011 13:42:50 GMT</pubDate></item></channel></rss>