Skip to content

Instantly share code, notes, and snippets.

@elcerdo
Created September 7, 2011 00:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save elcerdo/1199391 to your computer and use it in GitHub Desktop.
Save elcerdo/1199391 to your computer and use it in GitHub Desktop.
traffic jam
#include <cassert>
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <list>
using std::endl;
using std::cout;
static float slowdown = 0.35;
static float spawn = 0.8;
static const int speed_max = 6;
static const int road_length = 120;
static int carid = 0;
struct Car {
Car() {
position = 0;
speed = random()%speed_max;
id = carid++;
}
int position;
int speed;
int id;
};
std::ostream &operator<<(std::ostream &os, const Car &car) {
return os << "<car id=" << car.id << " speed=" << car.speed << " position=" << car.position << ">";
}
typedef std::list<Car> Cars;
void build_line(const Cars &cars, std::ostream &stream) {
stream << "|";
Cars::const_iterator iter = cars.begin();
for (size_t current_position=0; current_position<road_length; current_position++) {
if (iter==cars.end()) {
stream << " ";
continue;
}
assert(iter->position>=current_position);
if (iter->position==current_position) {
stream << (iter->id % 10);
iter++;
} else {
stream << " ";
}
}
stream << "|" << endl;
}
void update(Cars &cars) {
Cars::const_reverse_iterator iter_infront = cars.rend();
for (Cars::reverse_iterator iter=cars.rbegin(); iter!=cars.rend(); iter++) {
//cout << "--------------------" << endl << "updating " << *iter << endl;
// remove cars that are too far
if (iter->position>=road_length) {
assert(iter_infront==cars.rend());
assert(iter==cars.rbegin());
//cout << "removing " << *iter << endl;
cars.pop_back();
iter = cars.rbegin();
iter--;
continue;
}
// accelerate cars
if (iter->speed>0 && random()<slowdown*RAND_MAX) {
iter->speed--;
} else if (iter->speed<speed_max-1) {
iter->speed++;
}
// slow down in car blocks traffic
if (iter_infront!=cars.rend() && iter->speed>=(iter_infront->position - iter->position)) {
iter->speed = iter_infront->position - iter->position - 1;
//cout << " infront "<< *iter_infront << endl;
assert(iter_infront->position>iter->position);
}
iter_infront = iter;
iter->position += iter->speed;
//cout << "updated " << *iter << endl;
}
//cout << "moving cars" << endl;
//for (Cars::reverse_iterator iter=cars.rbegin(); iter!=cars.rend(); iter++) {
// // update position
// iter->position += iter->speed;
//}
}
int main(int argc,char * argv[])
{
srandom(time(NULL));
Cars cars;
while (true) {
if (cars.empty() || (!cars.empty() && cars.front().position!=0 && random()<spawn*RAND_MAX)) cars.push_front(Car());
build_line(cars,cout);
update(cars);
usleep(25000);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment