package use_trafficintersection.algorithm;
import java.awt.Color;
import java.util.ArrayList;
import use_trafficintersection.*;
/*
From here the algorithm and the Renderer interface
The renderer controls the program and calls three functions of Main
- The constructor, allowing the algorithm the setitself up.
- Loop, where the algorithm does its job.
- Draw, where the renderer gets told where the cars are and what else to draw.
BTW: The renderer loves uneven numbers.
Almost everything gets displayed better if their size is uneven.
*/
public class Main {
// Other objects
public static Renderer renderer;
public static Lights lights;
// Cars and peds lists
public ArrayList<Car> cars = new ArrayList<>();
public ArrayList<Ped> peds = new ArrayList<>();
// Debug value that get displayed by the renderer
public int debugInt = Renderer.DEBUG_INT_NOSHOW;
public String debug = "";
// Time spent
public long timeSpent = 0; // Gets displayed by renderer
public final ArrayList<Long> timeSpentList = new ArrayList<>();
// Constants
public static final int PED_SIZE = 7;
public static final int CAR_WIDTH = Renderer.CAR_MAX_WIDTH;
public static final int CAR_LENGHT = CAR_WIDTH*3/2;
public static final int PED_TIMER_BASE = 5;
public static final int PED_TIMER = 30;
public static final int CAR_TIMER_BASE = 30;
public static final int CAR_TIMER = 100;
public static final int TIME_SPENT_LIST_MAX_SIZE = 100;
// ------------------------------------
public Main(Renderer r,Lights l){
// Place a reference to renderer and lights into main class.
// We are going to need this to draw things on screen.
renderer = r;
lights = l;
/*
Setup algorithm function
Do not use renderer or anything graphical inside this function
*/
debug = "TWO TURN LANE TEST";
}
static int discoInt = 0;
public void loop(){
/*
Have the algorithm calculate and simulate the next step
*/
discoInt++;
if(discoInt > 250){
discoInt = 0;
lights.disco();
}
carSpawner();
pedSpawner();
Car car;
for(int i = cars.size()-1; i >= 0; i--){
car = cars.get(i);
car.step();
if(car.isDone){
addTimeSpent(renderer.loopCount - car.loopSpawned);
cars.remove(i);
}
}
Ped ped;
for(int i = peds.size()- 1; i >= 0; i--){
ped = peds.get(i);
ped.step();
if(ped.isDone){
peds.remove(i);
}
}
}
public void draw(){
/*
Draw the vehicles
- Drawing the world already has been done
- Drawing the top bar will be done after this
*/
Car car;
for(int i = 0; i < cars.size(); i++){
car = cars.get(i);
renderer.drawCar((int) car.x,(int) car.y, car.w, car.h, car.c, car.rotation);
}
Ped ped;
for(int i = 0; i < peds.size(); i++){
ped = peds.get(i);
renderer.drawPed(ped.x(), ped.y(), ped.r, ped.c);
}
}
public void reset(){
cars.clear();
peds.clear();
timeSpentList.clear();
timeSpent = 0;
}
// --------------------------------
// MEASURING
// --------------------------------
private void addTimeSpent(long time){
timeSpentList.add(time);
// Keep list at reasonable length
if(timeSpentList.size() > TIME_SPENT_LIST_MAX_SIZE){
timeSpentList.remove(0);
}
// Recalc average
long sum = 0;
for(int i = 0; i < timeSpentList.size(); i ++){
sum += timeSpentList.get(i);
}
timeSpent = sum/timeSpentList.size();
}
// --------------------------------
// SPAWNERS
// --------------------------------
private int carSpawner_timer = 0;
private void carSpawner(){
float spawnrate = renderer.getCars();
if( spawnrate < 1.0f )
return;
carSpawner_timer++;
if( carSpawner_timer < CAR_TIMER_BASE + (int)(CAR_TIMER * (100.0f - spawnrate) ) / 100 )
return;
carSpawner_timer = 0;
int rand;
// Starting direction
rand = (int)(Math.random() * 4 );
int dir_start;
switch (rand) {
case 0:
dir_start = Dir.UP;
break;
case 1:
dir_start = Dir.DOWN;
break;
case 2:
dir_start = Dir.RIGHT;
break;
default:
dir_start = Dir.LEFT;
break;
}
// Relative direction
rand = (int)(Math.random() * 3);
int dir_rel;
switch (rand) {
case 0:
dir_rel = Dir.GO_LEFT;
break;
case 1:
dir_rel = Dir.GO_RIGHT;
break;
default:
dir_rel = Dir.GO_FORWARD;
break;
}
dir_rel = Dir.GO_FORWARD;
// Is auto
boolean isAuto = (Math.random() < (renderer.getAutos()/100.0f));
cars.add(new Car(lights,CAR_WIDTH,CAR_LENGHT,dir_start,dir_rel,isAuto,renderer.loopCount));
}
private int pedSpawner_timer = 0;
private void pedSpawner(){
float spawnrate = renderer.getPeds();
if( spawnrate < 1.0f )
return;
pedSpawner_timer++;
if( pedSpawner_timer < PED_TIMER_BASE + (int)(PED_TIMER * (100.0f - spawnrate) ) / 100 )
return;
pedSpawner_timer = 0;
int rand;
// Starting direction
rand = (int)(Math.random() * 4);
int dir_start;
switch (rand) {
case 0:
dir_start = Dir.UP;
break;
case 1:
dir_start = Dir.DOWN;
break;
case 2:
dir_start = Dir.RIGHT;
break;
default:
dir_start = Dir.LEFT;
break;
}
// Relative direction
rand = (int)(Math.random() * 3);
int dir_rel;
switch (rand) {
case 0:
dir_rel = Dir.GO_LEFT;
break;
case 1:
dir_rel = Dir.GO_RIGHT;
break;
default:
dir_rel = Dir.GO_FORWARD;
break;
}
peds.add(new Ped(lights, PED_SIZE,dir_start, dir_rel));
}
}