⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aiplayer.c

📁 这是一个相当棒的Linux下的台球游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
            !ball_in_way(minind,hole->aim,balls) ){            angle = fabs( vec_angle( vec_diff(r_hit,bcue->r), vec_diff(hole->aim,r_hit) ) );            if( angle<minangle ){                minhole = j;  minangle = angle;                DPRINTF("aiplayer: hole:%d\n",minhole);            }        } else {            DPRINTF("aiplayer: hole:%d - no! inway1=%d, inway2=%d\n",                    j,ball_in_way(0,r_hit,balls),ball_in_way(i,hole->aim,balls));        }    }    if(minhole!=-1){        hole = &walls->hole[minhole];        r_hit = vec_scale(vec_unit(vec_diff(bhit->r,hole->aim)),(bcue->d+bhit->d)/2.0);        r_hit = vec_diff(vec_add(bhit->r,r_hit),bcue->r);    } else {  /* no proper ball found */        DPRINTF("aiplayer: no proper hole found\n");        r_hit = vec_diff(bhit->r,bcue->r);    }    r_hit=vec_add(r_hit,vec_scale(vec_xyz(my_rand01()-0.5,my_rand01()-0.5,my_rand01()-0.5),0.02*ai_err*vec_abs(r_hit)));    return vec_unit(r_hit);}#define IS_RED(x) ( x==1 || x>=8 )int snooker_ball_legal(int ball,struct Player *player){    return ((IS_RED(ball) && player->snooker_on_red)          ||(!IS_RED(ball) && !player->snooker_on_red && player->snooker_next_color<=1)          ||(player->snooker_on_red==0 && ball==player->snooker_next_color && player->snooker_next_color>1));}#define CUE_OBJ_WEIGHT 0.2#define OBJ_HOLE_WEIGHT 0.7#define POINT_WEIGHT 0.3#define CENTERHOLE_ANGLE_WEIGHT 1#define CORNERHOLE_ANGLE_WEIGHT 1#define ANGLE_WEIGHT 1VMvect ai_get_stroke_dir_snooker( BallsType * balls, BordersType * walls, struct Player * pplayer ){   //return vec_xyz(1,1,0);;    VMvect r_hit,hole_aim,hole_aim_def,min_r_hit;    VMfloat angle, minweight,hole_angle,weight,corner_acentrism;    BallType *bhit, *bcue;    HoleType *hole;    int minball;    int minhole;    int i,j;    int legal_ball=1;    fprintf(stderr,"aiplayer: start player[%s]\n",pplayer->name);    minball=0;    minhole=-1;    minweight=12;    bcue = &balls->ball[0];    for( i=balls->nr-1;i>=1; i-- ) if ( balls->ball[i].in_game ){        if(snooker_ball_legal(i,pplayer))        {            bhit = &balls->ball[i];            for( j=0; j<walls->holenr; j++ ){                hole = &walls->hole[j];                if(j>1)                {                    hole_aim=hole->aim;                    if(hole_aim.x>0) hole_aim.x-=0.007;                    if(hole_aim.x<0) hole_aim.x+=0.007;                    if(hole_aim.y>0) hole_aim.y-=0.007;                    if(hole_aim.y<0) hole_aim.y+=0.007;                }                else                {                    hole_aim=vec_scale(hole->aim,1.02);                }                r_hit = vec_scale(vec_unit(vec_diff(bhit->r,hole_aim)),(bcue->d+bhit->d)/2.0);                r_hit = vec_add(bhit->r,r_hit);                if( !ball_in_way(0,r_hit,balls) &&                    !ball_in_way(i,hole_aim,balls) ){                    angle = fabs( vec_angle( vec_diff(r_hit,bcue->r), vec_diff(hole_aim,r_hit) ) );                    hole_angle = vec_angle(vec_diff(hole_aim,bhit->r),vec_diff(vec_xyz(2*hole_aim.x,hole_aim.y,0),hole_aim));                    corner_acentrism=fabs(hole_angle-M_PI/4);                    /*fprintf(stderr,"aiplayer: ball:%d hole:%d raw hole_angle %f\n",balls->ball[i].nr,j, hole_angle*180/M_PI);*/                    /* normalized to give an unweighted maximum of +- 2.5 per item */                    weight = 0.64 * ANGLE_WEIGHT * pow(angle,3)                             +(j<=1)*0.64 * CENTERHOLE_ANGLE_WEIGHT * pow(hole_angle,3)                             +(j>1) * 5.0 * CORNERHOLE_ANGLE_WEIGHT * pow(corner_acentrism,3)                             +0.04 * OBJ_HOLE_WEIGHT * vec_abssq(vec_diff(bhit->r,hole_aim))                             +0.15 * CUE_OBJ_WEIGHT * vec_abs(vec_diff(bhit->r,bcue->r))                             -1.5 * POINT_WEIGHT *(i>=2||i<=7?i-2:0)                              ;                     if(weight <minweight){                         minball = i; minhole = j;  minweight = weight;hole_aim_def=hole_aim;                        fprintf(stderr,"aiplayer: ball:%d hole:%d\n",i,minhole);                    }                }            }        }    }    /*fprintf(stderr,"aiplayer: 1\n");*/    if( minball==0 )  /* no pottable ball found, hit any legal ball */    {        //for( i=1;i<balls->nr && minball==0;i++) if ( balls->ball[i].in_game ){        for( i=balls->nr-1;i>=1 && minball==0;i--) if ( balls->ball[i].in_game ){            if(snooker_ball_legal(i,pplayer))            {                VMfloat d;                for(d=-(balls->ball[0].d-0.001);d<(balls->ball[0].d-0.001) && minball==0;d+=0.005)                {                   VMvect offset,new_r_hit;                   bhit = &balls->ball[i];                   r_hit = vec_diff(bhit->r,bcue->r);                   /*r_hit=vec_rotate(r_hit,vec_xyz(0,0,asin(d/vec_abs(r_hit))));*/                   offset=vec_scale(vec_unit(vec_rotate(r_hit,vec_xyz(0,0,M_PI/2))),d);                   new_r_hit = vec_diff(vec_add(bhit->r,offset),bcue->r);                   new_r_hit = vec_diff(new_r_hit,vec_scale(vec_unit(new_r_hit),balls->ball[i].d/1.99));                                      if( !ball_in_way(0,vec_add(balls->ball[0].r,new_r_hit),balls))                   {                       fprintf(stderr,"ball found\n");                       minball=i;                       min_r_hit=new_r_hit;                   }               }            }        }    }    if( minball==0 )  /* no legal ball found, just play anything */    {        legal_ball=0;        minball=0;        if (pplayer->snooker_on_red)        {           minball=2+my_rand(6);        }        else if (pplayer->snooker_on_red==0 && pplayer->snooker_next_color<2)        {           minball=7+my_rand(15);           if(minball==21) minball=1;        }        else        {           minball=pplayer->snooker_next_color;        }    }    /*fprintf(stderr,"aiplayer: 2\n");*/    bhit = &balls->ball[minball];    if(minhole!=-1){        hole = &walls->hole[minhole];        r_hit = vec_scale(vec_unit(vec_diff(bhit->r,hole_aim_def)),(bcue->d+bhit->d)/2.0);        r_hit = vec_diff(vec_add(bhit->r,r_hit),bcue->r);    } else {  /* no proper ball found */        if(legal_ball==0)        {           fprintf(stderr,"aiplayer: no proper ball found\n");           r_hit = vec_diff(bhit->r,bcue->r);        }        else        {           fprintf(stderr,"aiplayer: can hit legal ball : %d\n",minball);           r_hit=min_r_hit;        }    }    r_hit=vec_add(r_hit,vec_scale(vec_xyz(my_rand01()-0.5,my_rand01()-0.5,my_rand01()-0.5),0.02*ai_err/vec_abs(r_hit)));    fprintf(stderr,"aiplayer: done\n");    return vec_unit(r_hit);}#undef IS_REDVMvect ai_get_stroke_dir_carambol( BallsType * balls, BordersType * walls, struct Player * pplayer ){#define CUE_BALL_IND (pplayer->cue_ball)    int i,j,k, foundshot;    VMvect wc;    /* way of cueball to objectball 1 */    VMvect w12;   /* way of cueball from objectball 1 to objectball 2 */    VMvect d12;   /* vec from objectball 1 to objectball 2 */    VMvect p1;    /* vec from ball1 to cueball at hit */    VMvect min_wc;    double min_angle;    double th;    foundshot=0;    min_angle=M_PI;    for(i=0;i<balls->nr;i++) if(i!=CUE_BALL_IND){             /* i = objectball 1 */        for( j=0 ; j<balls->nr ; j++ ){                       /* j = objectball 2 */            if(j!=CUE_BALL_IND && j!=i) break;        }        DPRINTF("ai_get_stroke_dir_carambol:i=%d,j=%d\n",i,j);        d12 = vec_diff( balls->ball[j].r, balls->ball[i].r );        th = acos(BALL_D/vec_abs(d12));        for(k=0;k<2;k++){  /* the two possible tangents */            p1  = vec_scale( vec_unit( vec_rotate(d12,vec_xyz(0,0,(k==0)?th:-th)) ), BALL_D );            wc  = vec_diff( vec_add(balls->ball[i].r,p1), balls->ball[CUE_BALL_IND].r );            w12 = vec_diff( balls->ball[j].r, vec_add(balls->ball[i].r,p1) );            if( vec_mul(wc,w12)>0.0 && vec_mul(wc,p1)<0.0 ){  /* conditions for possible shot */                foundshot=1;                if( vec_angle( wc, w12 ) < min_angle ){                    min_angle = vec_angle( wc, w12 );                    min_wc = wc;                }            }        }    }    if(foundshot){        return vec_unit(min_wc);    } else {        return vec_unit( vec_diff(balls->ball[(CUE_BALL_IND+1+(rand()%2))%3].r, balls->ball[CUE_BALL_IND].r) );    }#undef CUE_BALL_IND}void setfunc_ai_get_stroke_dir(VMvect (*func)( BallsType * balls, BordersType * walls, struct Player * pplayer )){    ai_get_stroke_dir=func;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -