// Strategy.cpp : Defines the entry point for the DLL application

#include "stdafx.h"
#include "Strategy.h"

#include <math.h>

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
    switch (ul_reason_for_call)
        {
                case DLL_PROCESS_ATTACH:
                case DLL_THREAD_ATTACH:
                case DLL_THREAD_DETACH:
                case DLL_PROCESS_DETACH:
                        break;
    }
    return TRUE;
}

//global variables
const double PI = 3.1415926;
int WHO = 1; //1 blue 0 yellow
const double MAXL = 112; //球场对角线长
FILE *DEBUGFILE; //调试文件
Environment *ENV;
int NEEDROTATE[5] = {1, 1, 1, 1, 1}; //1 need, else not need
int PD[5] = {0}; //巡逻方向,由 点 1 到 2
double TRACE[6][2][2] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; //纪录 5 个机器人的轨迹
double DISPLACEMENT[6] = {0}; //纪录每个机器人在 1/6 秒内的位移
int EV[6] = {0}; //estimate v 估计的机器人的速度 and the ball
double COUNT1 = 0, COUNT2 = 0; //保存调用次数
double PBP[2] = {0, 0}; //预测的球的坐标 predict ball position
int WIB = 5; //whree is ball
double ROBOTLENGTH = 3.2; //length of a robot

//basic methods
void go(Robot *robot, int rID, const double x, const double y); //朝某点运动
void backGo(Robot *robot, int rID, const double x, const double y); //
double rotateTo(Robot *robot, int rID, const double desX, const double desY); //转动
void stop(Robot *robot, int rID); //停止
void to(Robot *robot, int rID, double x, double y); //到某点静止
void backTo(Robot *robot, int rID, double x, double y); //反向到某点静止
void estimateV(); //估计所有机器人的速度,and the ball
void predictBall(double s); //预测球的出现
void run(Robot *robot, int rID, int vl, int vr);

//advanced methods
void passBall(Robot *robotS, Robot *robotG, int rIDS, int rIDG); //传球 robot send ,robot get
void patrol(Robot *robot, int rID, double x1, double y1, double x2, double y2); //在 2 点间晃动
void nearBall(Robot *robot, int rID, double x, double y); //接近球,并且与 x,y 不在球的同一边
void kickBall(Robot *robot, int rID, double x, double y); //把球打到指定地点

//stratgies
bool canKShoot(Robot *robot, int rID);//是否可以用头撞球进 can kick shoot
bool canRShoot(Robot *robot, int rID); //是否可以旋转撞球进 rotate
int whereIsBall(); //判断球在哪个区域,返回区域编号
bool hasEnemyBetween(Robot *robot, double x, double y); //is there enemy between robot and x,y
void defend(int wib); //
void attack(int wib); //

//role controller
void waiter(Robot *robot, int rID, double x, double y); //在 x,y 点等待球,一旦 r.x>x,距离小于某值时kick ball
void activeDefender(Robot *robot, int rID); //绕到球的右边 kick ball
void negativeDefender(Robot *robot, int rID, double x, double y); //首在某点并对着球,一旦距离小于某一值 kick ball,b.x > x
void keepHelper(Robot *robot, int rID); //协助守门员在球门的另一半守门,x 坐标小于守门员
void keeper(Robot *robot, int rID); //守门员,在固定 x 坐标跟着球的 y 坐标跑
void attacker(Robot *robot, int rID); //绕到球的右边 kick ball

//strategy for all states
void strategyForD(Environment *env); //default
void strategyForFB(Environment *env);
void strategyForPlK(Environment *env);
void strategyForPeK(Environment *env);
void strategyForFK(Environment *env);
void strategyForGK(Environment *env);
extern "C" STRATEGY_API void Create ( Environment *env )
{
        // allocate user data and assign to env->userData
        // eg. env->userData = ( void * ) new MyVariables ();
}

extern "C" STRATEGY_API void Destroy ( Environment *env )
{
        // free any user data created in Create ( Environment * )
        // eg. if ( env->userData != NULL ) delete ( MyVariables * ) env->userData;
}


extern "C" STRATEGY_API void Strategy ( Environment *env )
{
        //here are my Strategies ,as the game state differes calls the responding method
        COUNT2 ++;
        ENV = env;
        estimateV();

        switch(env->gameState){
                case 0 : strategyForD(env);break;
                case FREE_BALL : strategyForD(env); break;
                case PLACE_KICK : strategyForD(env); break;
                case PENALTY_KICK : strategyForPeK(env); break;
                case FREE_KICK : strategyForD(env); break;
                case GOAL_KICK : strategyForD(env); break;
        }
}

void strategyForD(Environment *env){ //对默认情况
        //
        double bx,by ,rx; //ball's coordinate
        int lt = 0;

        bx = env->currentBall.pos.x;
        by = env->currentBall.pos.y;
        rx = env->home[0].pos.x;
        whereIsBall();
        //to(&env->home[3], 3,env->currentBall.pos.x, env->currentBall.pos.y);
        //negativeDefender(&env->home[2],2,0,58);
        //activeDefender(&env->home[1],1);
        //activeDefender(&env->home[2],2);
        //activeDefender(&env->home[3],3);
        //attacker(&env->home[4],4);
        keeper(&env->home[0],0);
        switch(WIB){
                case 1 : defend(1); break;
                case 2 : defend(2); break;
                case 3 : defend(3); break;
                case 4 : attack(4); break;
                case 5 : attack(5); break;
                case 6 : attack(6); break;
                case 7 : attack(7); break;
                case 8 : attack(8); break;
                case 9 : attack(9); break;
        }
        //以下相当于紧急模块
        if(bx > 88.28 && by > 33.93 && by < 52.92 && rx-bx>-0.5)
                go(&env->home[0], 0, bx-0.3, by);
        for(lt=0;lt<5;lt++){
                if(canKShoot(&env->home[lt], lt) && env->home[lt].pos.