LoginSignup
2
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-09-25

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

ソース

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;
  }
}
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3