Mainjava2016groep2

From Control Systems Technology Group
Jump to navigation Jump to search
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));
    }
}