【Processing】【AI】ProcessingでサッカーゲームのAIシミュレーションアプリを作る　ソース

http://qiita.com/66zaha_9su/items/de5dff79f2be21a1db1f
↑のソースになっております。↑

#ソース

```processing:soccer_ai.pde
long frame =0;
float eb_xPos;
float eb_yPos;
boolean kicked=false;
int b_point=0;
int p_point=0;

float[] dist;

Player[] players =new Player[22];
Ball ball =new Ball();
 
void setup() {
  size(400, 800);  
  background(255);
  smooth();
  noStroke();
  fill(0);
  frameRate(-60);
  
  dist=new float[players.length];
  
  for (int i = 0; i < players.length; i++) players[i] = new Player();
  for (int j = 0; j < players.length; j++) players[j].P_initialize(j);
  for (int k = 0; k < players.length; k++)dist[k]=9999.9;
  
  ball=new Ball();
  ball.B_initialize();
}
 
void draw() {
  background(255);
  frame++;
  
  
  for (int i = 0; i < players.length; i++) {
    dist[i]=9999.9;
    players[i].update(i);
    players[i].p_kick_hantei(i);
    players[i].display(i);
    
    //circles[i].update();
    //circles[i].display();
  }
  ball.display();
  kicked=false;
  
  fill(0);
  text(frame+"F", 5, 10);
  text(nfs(frameRate, 3, 1)+"FPS", 80, 10);
  text(p_point+"-"+b_point, 160, 10);
}


class Ball{
  float b_radius;
  float b_xPos;
  float b_yPos;
  
  Ball(){
    b_radius=18.0;
    b_xPos=200;
    b_yPos=400;
  }
  
  void B_initialize(){
    fill(#000000);
    ellipse(200, 400, b_radius, b_radius);
    b_xPos=200; b_yPos=400;
    eb_xPos=200; eb_yPos=400;
  }
  
  void display(){
    fill(#000000);
    ellipse(b_xPos, b_yPos, b_radius, b_radius);
    eb_xPos=b_xPos; eb_yPos=b_yPos;
  }
  
  void kick(float kakudo,float power,int num){
    float p_x_kick=(cos(kakudo*PI/180)+0.2)*power;
    float p_y_kick=(sin(kakudo*PI/180)+0.2)*power;
    
    
    
    if(num%2 ==0){
      b_xPos+=p_x_kick;
      b_yPos+=p_y_kick;
      
      if(b_xPos>400-b_radius) b_xPos=400-b_radius;  //ball is out of vesel (not goal)
      if(b_xPos<b_radius) b_xPos=b_radius;  //ball is out of vesel (not goal)
      
      if(b_yPos>800-b_radius){
        p_point++;
        b_yPos=400;
        b_xPos=200;
        
        for(int i=0; i<players.length; i++){
          players[i].p_goal_init(i);
        }
    }
      if(b_yPos<b_radius){
        b_point++;
        b_yPos=400;
        b_xPos=200;
        
        for(int i=0; i<players.length; i++){
          players[i].p_goal_init(i);
        }
    }
      
      eb_xPos=b_xPos;
      eb_yPos=b_yPos;
    }
    
    else if(num%2 ==1){
      b_xPos-=p_x_kick;
      b_yPos-=p_y_kick;
      
      if(b_xPos>400-b_radius) b_xPos=400-b_radius;  //ball is out of vesel (not goal)
      if(b_xPos<b_radius) b_xPos=b_radius;  //ball is out of vesel (not goal)
      
      if(b_yPos>800-b_radius){
        p_point++;
        b_yPos=400;
        b_xPos=200;
        
        for(int i=0; i<players.length; i++){
          players[i].p_goal_init(i);
        }
    }
      if(b_yPos<b_radius){
        b_point++;
        b_yPos=400;
        b_xPos=200;
        
        for(int i=0; i<players.length; i++){
          players[i].p_goal_init(i);
        }
    }
      
      eb_xPos=b_xPos;
      eb_yPos=b_yPos;
    }
  }
}



///////////////////////////////////////////////////////////////////////////////////
class Player{
  float p_radius = 28;
  float p_xPos;
  float p_yPos;
  float p_xVec;
  float p_yVec;
  float p_spd;
  float p_angl;
  float p_power;
  
  int p_siya;
  int p_siya_d;
  
  Player(){    //mainly initiallize process    initial position determine another process
  p_spd=12*random(0.6,0.9);
  p_angl=0;
  p_xPos=0;
  p_yPos=0;
  
  p_siya=(int) random(2,12);
  p_siya_d=(int) random(160,600);
  
  p_power=random(12,32);
  }
  
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void P_initialize(int _number){
    int p_number = _number;
    
    if(p_number%2 ==0){
      
      if(p_number == 0){
        fill(#ff7fff);
        ellipse(40, 80, p_radius, p_radius);
        p_xPos=40; p_yPos=80;
      }
      
      if(p_number == 2){
        fill(#ff7fff);
        ellipse(200, 80, p_radius, p_radius);
        p_xPos=200; p_yPos=80;
      }
      
      if(p_number == 4){
        fill(#ff7fff);
        ellipse(360, 80, p_radius, p_radius);
        p_xPos=360; p_yPos=80;
      }
      
      if(p_number == 6){
        fill(#ff7fff);
        ellipse(150, 350, p_radius, p_radius);
        p_xPos=150; p_yPos=350;
      }
      
      if(p_number == 8){
        fill(#ff7fff);
        ellipse(250, 350, p_radius, p_radius);
        p_xPos=250; p_yPos=350;
      }
    }
    
    else if(p_number%2 ==1){
      
      if(p_number == 1){
        fill(#00bfff);
        ellipse(40, 720, p_radius, p_radius);
        p_xPos=40; p_yPos=720;
      }
      
      if(p_number == 3){
        fill(#00bfff);
        ellipse(200, 720, p_radius, p_radius);
        p_xPos=200; p_yPos=720;
      }
      
      if(p_number == 5){
        fill(#00bfff);
        ellipse(360, 720, p_radius, p_radius);
        p_xPos=360; p_yPos=720;
      }
      
      if(p_number == 7){
        fill(#00bfff);
        ellipse(150, 450, p_radius, p_radius);
        p_xPos=150; p_yPos=450;
      }
      
      if(p_number == 9){
        fill(#00bfff);
        ellipse(250, 450, p_radius, p_radius);
        p_xPos=250; p_yPos=450;
      }
    }
    
  }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  void update(int num){
    float p_dist;
    float x_dist;
    float y_dist;
    float kakudo;
    
    float p_siya_f;    //f means from
    float p_siya_e;    //e means end
    
    float p_x_ran;
    float p_y_ran;
    
    
    p_dist=sqrt((p_xPos-eb_xPos)*(p_xPos-eb_xPos)+(p_yPos-eb_yPos)*(p_yPos-eb_yPos));
    x_dist=eb_xPos-p_xPos;
    y_dist=eb_yPos-p_yPos;
    
    kakudo=degrees(atan2(x_dist,y_dist));
    
    if(kakudo < 0){
      kakudo+=kakudo+360;
    }
    
    p_angl=kakudo;
    
    p_siya_f = 360 * ( (float)frame % (float)p_siya ) / (float)p_siya;
    p_siya_e = 360 * ( (float)frame % (float)p_siya +1) / (float)p_siya;
    
    /////////////jyouken 1    ball siyanai   ball chikai
    if( p_dist < ((float)p_siya_d) && p_siya_f < kakudo && kakudo < p_siya_e){
      //println("players["+num+"], "+x_dist+","+y_dist +" , p_dist: "+p_dist +", p_siya_d: "+p_siya_d +" , kakudo: "+kakudo +", siya: "+ p_siya_f +" ~ "+p_siya_e);
      
      if(x_dist<=0 && y_dist <=0){
        p_x_ran=p_spd*(abs(cos(kakudo*PI/180)))*-1;
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1;
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>=0 && y_dist <=0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180));
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1;
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      if(x_dist<=0 && y_dist >=0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180))*-1;
        p_y_ran=p_spd*abs(sin(kakudo*PI/180));
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>=0 && y_dist >=0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180));
        p_y_ran=p_spd*abs(sin(kakudo*PI/180));
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      //hamidasi
      if(p_xPos>400-p_radius) p_xPos=400-p_radius;
      if(p_xPos<p_radius) p_xPos=p_radius;
      if(p_yPos>800-p_radius) p_yPos=800-p_radius;
      if(p_yPos<p_radius) p_yPos=p_radius;
      
      dist[num]=sqrt((p_xPos-eb_xPos)*(p_xPos-eb_xPos)+(p_yPos-eb_yPos)*(p_yPos-eb_yPos));
    }
    ///////////////////////////////////////////////////////////////
    
    
    //////////////////jyouken 2    ball out of gancyu   ball chikai
    else if(p_dist < ((float)p_siya_d) ){
      if(x_dist<0 && y_dist <0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180))*-1*random(-0.75,0.75);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1*random(-0.75,0.75);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>0 && y_dist <0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180))*random(-0.75,0.75);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1*random(-0.75,0.75);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      if(x_dist<0 && y_dist >0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180))*-1*random(-0.75,0.75);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*random(-0.75,0.75);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>0 && y_dist >0){
        p_x_ran=p_spd*abs(cos(kakudo*PI/180))*random(-0.75,0.75);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*random(-0.75,0.75);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      //hamidasi
      if(p_xPos>400-p_radius) p_xPos=400-p_radius;
      if(p_xPos<p_radius) p_xPos=p_radius;
      if(p_yPos>800-p_radius) p_yPos=800-p_radius;
      if(p_yPos<p_radius) p_yPos=p_radius;
      
      dist[num]=sqrt((p_xPos-eb_xPos)*(p_xPos-eb_xPos)+(p_yPos-eb_yPos)*(p_yPos-eb_yPos));
      
    }
    /////////////////////////////////////////////////////////
    
    /////////////jyouken 3    ball toi
    else if(p_dist > ((float)p_siya_d) ){
      
            if(x_dist<=0 && y_dist <0){
        p_x_ran=p_spd*(abs(cos(kakudo*PI/180))+random(-5.0,5.0))*-1*random(0,0.4);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1*random(0,0.4);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>=0 && y_dist <0){
        p_x_ran=p_spd*(abs(cos(kakudo*PI/180))+random(-5.0,5.0))*random(0,0.4);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*-1*random(0,0.4);
       
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      if(x_dist<=0 && y_dist >0){
        p_x_ran=p_spd*(abs(cos(kakudo*PI/180))+random(-5.0,5.0))*-1*random(0,0.4);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*random(0,0.4);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      else if(x_dist>=0 && y_dist >0){
        p_x_ran=p_spd*(abs(cos(kakudo*PI/180))+random(-5.0,5.0))*random(0,0.4);
        p_y_ran=p_spd*abs(sin(kakudo*PI/180))*random(0,0.4);
        
        p_xPos+=p_x_ran;
        p_yPos+=p_y_ran;
      }
      
      //hamidasi
      if(p_xPos>400-p_radius) p_xPos=400-p_radius;
      if(p_xPos<p_radius) p_xPos=p_radius;
      if(p_yPos>800-p_radius) p_yPos=800-p_radius;
      if(p_yPos<p_radius) p_yPos=p_radius;
      
    }
    
  }
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  void p_kick_hantei(int num){
    float min=min(dist);
    if(dist[num]<p_radius && min == dist[num]){
      kicked=true;
      ball.kick(p_angl,p_power,num);    //ball.kick method uses as  ball.kick(ANGLE,POWER);
    }
  }
  
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void display(int num){
    float hani =(float) p_siya;
    float siya1 =(float) (frame%p_siya);
    float siya2 =(float) ((frame+1)%p_siya);
    float siya_d=p_siya_d;
    float kakudo=360.0;
    
    
    
    if(num%2 == 0){
      fill(#ff7fff,255);
      ellipse(p_xPos,p_yPos,p_radius,p_radius);
      fill(#ff7fff,63);
      arc( p_xPos, p_yPos, siya_d*2, siya_d*2, radians(kakudo*siya1/hani),radians(kakudo*siya2/hani));
      alpha(0);
    }
    
    else{
      fill(#00bfff,255);
      ellipse(p_xPos,p_yPos,p_radius,p_radius);
      fill(#00bfff,63);
      arc( p_xPos, p_yPos, siya_d*2, siya_d*2, radians(kakudo*siya1/hani),radians(kakudo*siya2/hani));
      alpha(0);
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  void p_goal_init(int num){
    float x_pos=random(p_radius*2,400-p_radius*2);
    float y_pos=random(p_radius*2,800-p_radius*2);
    
    p_xPos=x_pos;
    p_yPos=y_pos;
  }
}
```