//FOR 4 GATES
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<string>
using namespace std;


const double MAX_HEIGHT =  4.0;
const double Y_MIN      = -0.75;
const double Y_MAX      =  0.75;
const double ROBOT_RADIUS = 0.203;
//const double IDEAL_LENGTH = 4.3376;
const double OVERLAP    = 0.8;
double rand(double a, double b){
  return a+double(rand())/double(RAND_MAX)*(b-a);
}
//rounds to _num_ to the nearest _unit_
double round(double num, double unit){
  return rint(num/unit)*unit;
}
void gen_course(double &x1, double &y1,
		double &x2, double &y2,
		double &x3, double &y3,
		double &x4, double &y4){

  x1=1;
  //  double a2=rand(0,0.75);
  //x2=x1+0.75+a2;
  //x3=x2+0.75+rand(0,0.75-a2);
  //x4=rand(x3+0.75,MAX_HEIGHT);

  //split the 0.75m of free space randomly
  // 0                       0.75(15x0.05)
  // |--------'------'-------|
  //          m1     m2
  //          t1     t2      
  int t1=rand()%15+1;
  int t2=rand()%15+1;
  if(t2<t1) swap(t2,t1);
  double m1=t1*0.05;
  double m2=t2*0.05;
  //  double m1=rand(0,0.75);
  //double m2=rand(0,0.75);
  //if(m2<m1) swap(m2,m1);
  
  x2= x1+0.75+m1;
  x3= x2+0.75+m2-m1;
  x4= 4.0;

  y1=rand(-0.3,0.3);
  y2=rand(max( y1-0.5 , Y_MIN ), 
	  min( y1+0.5 , Y_MAX ));
  y3=rand(max( y2-0.5 , Y_MIN ), 
	  min( y2+0.5 , Y_MAX ));
  y4=rand(max( y3-0.5 , Y_MIN+0.25 ),   //0.25 is to ensure there is space
	  min( y3+0.5 , Y_MAX-0.25 ));  //for the final gate

  y1=round(y1,0.05);
  y2=round(y2,0.05);
  y3=round(y3,0.05);
  y4=round(y4,0.125);
}
double dist(double x1, double y1,
	    double x2, double y2){
  return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}

double y_overlap(double x1, double y1,
		 double x2, double y2,
		 double x3, double y3,
		 double x4, double y4){
  double sign=-1.0;
  if(y1>0) sign =1.0;
  double overlap=0.0;
  overlap=sign*y1; sign*=-1;
  overlap+=sign*(y2-y1); sign*=-1;
  overlap+=sign*(y3-y2); sign*=-1;
  overlap+=sign*(y4-y3); sign*=-1;

  return overlap;
}
/*double course_len(double x1, double y1,
		  double x2, double y2,
		  double x3, double y3,
		  double x4, double y4){

  double sign=1;

  if(y1<0) sign=-1;
  y1+=sign*ROBOT_RADIUS; sign*=-1;
  y2+=sign*ROBOT_RADIUS; sign*=-1;
  y3+=sign*ROBOT_RADIUS; sign*=-1;
  return dist(0,0,x1,y1)+
    dist(x1,y1,x2,y2)+
    dist(x2,y2,x3,y3)+
    dist(x3,y3,x4,y4);    
  
}*/

void convert_xy(double x, double y, int& xb, int&yb){
  xb=int(x*10);
  yb=int((y+1)*20);
}
void draw(double x1, double y1,
	  double x2, double y2,
	  double x3, double y3,
	  double x4, double y4){
  int xb1, yb1, xb2, yb2, xb3, yb3, xb4, yb4;
  convert_xy(x1,y1,xb1,yb1);
  convert_xy(x2,y2,xb2,yb2);
  convert_xy(x3,y3,xb3,yb3);
  convert_xy(x4,y4,xb4,yb4);

  vector<string> buffer= vector<string>(41,string(41,' '));

  int dir=1;
  if(y1<0) dir=-1;
  for(int i=0;i<=40;i++){
    buffer[0][i]='#'; 
    buffer[i][0]='#'; 
    buffer[40][i]='#';
    buffer[i][40]='#';
  }

  if(dir==1) for(int i=0; i<=yb1;i++) buffer[xb1][i]='*'; 
  else for(int i=40; i>=yb1;i--) buffer[xb1][i]='*'; 
  dir*=-1;

  if(dir==1) for(int i=0; i<=yb2;i++) buffer[xb2][i]='*'; 
  else for(int i=40; i>=yb2;i--) buffer[xb2][i]='*'; 
  dir*=-1;

  if(dir==1) for(int i=0; i<=yb3;i++) buffer[xb3][i]='*'; 
  else for(int i=40; i>=yb3;i--) buffer[xb3][i]='*'; 
  dir*=-1;


  for(int i=0; i<=yb4-7;i++) buffer[xb4][i]='*'; //g4
  for(int i=40; i>=yb4+7;i--) buffer[xb4][i]='*'; //g4
  for(int i=yb4-7; i<=yb4+7;i++) buffer[xb4][i]=' '; //out 
  buffer[0][20]='0';
  reverse(buffer.begin(),buffer.end());
  for(int i=0;i<buffer.size();i++)
    cout<<buffer[i]<<endl;
  cout<<endl;
}
int main(int argc, char *argv[]){

  if(argc>=2)
    srand(atoi(argv[1]));
  else srand(time(0));
  
  double x1,x2,x3,x4,y1,y2,y3,y4;
  double len;
  double overlap;
  do{
    gen_course(x1,y1,x2,y2,x3,y3,x4,y4);
    //len=course_len(x1,y1,x2,y2,x3,y3,x4,y4);
    overlap=y_overlap(x1,y1,x2,y2,x3,y3,x4,y4);
    //}while(fabs(len-IDEAL_LENGTH)>IDEAL_LENGTH*0.01);
  }while(fabs(overlap-OVERLAP)>=0.05);

  
  draw(x1,y1,x2,y2,x3,y3,x4,y4);
  cout<<endl;
  cout<<"G4: "<<x4<<" , "<<y4<<endl
      <<"G3: "<<x3<<" , "<<y3<<endl
      <<"G2: "<<x2<<" , "<<y2<<endl
      <<"G1: "<<x1<<" , "<<y1<<endl;


  //  cout<<"Course length: "<<len<<endl;
  cout<<"Course y_overlap: "<<overlap<<endl;
  //  cout<<y_overlap(0,1,0,0,0,-1,0,0)<<endl;
  return 0;
}

