Ejemplo n.º 1
0
    void GenerateMoves(S_CurState i_stCurrent, float i_fTime, out S_CurMove[] o_stMoves)
    {
        int i;

        o_stMoves = new S_CurMove[6];
        for (i = 0; i < 6; i++)
        {
            S_CurState stNew = i_stCurrent;

            stNew.fPointing -= ALLMOVES[i].bRight ? SHIP_STEERSPEED * i_fTime : 0;
            stNew.fPointing += ALLMOVES[i].bLeft ? SHIP_STEERSPEED * i_fTime : 0;
            if (stNew.fPointing < 0)
            {
                stNew.fPointing += 360;
            }
            if (stNew.fPointing > 360)
            {
                stNew.fPointing -= 360;
            }

            float fThrust = ALLMOVES[i].bThrottle ? SHIP_THRUST : 0;

            Vector2 a = new Vector2(Mathf.Cos(stNew.fPointing * (Mathf.PI / 180)) * fThrust, Mathf.Sin(stNew.fPointing * (Mathf.PI / 180)) * fThrust);
            a += oCustomGravity.force;
            a -= stNew.vVel * oRb.drag;

            stNew.vPos += (stNew.vVel * i_fTime) + (0.5f * a * i_fTime * i_fTime);
            stNew.vVel += a * i_fTime;

            o_stMoves[i].stValue = stNew;
            o_stMoves[i].a       = Strategy5(stNew);
            o_stMoves[i].b       = Strategy1(stNew);
            o_stMoves[i].c       = Strategy2(stNew);
            o_stMoves[i].d       = Strategy4(stNew);
            o_stMoves[i].e       = MOVE_TO_MOVE_SCORE[stNew.iLastMove, i] * (1.0f / Strategy5(stNew));
        }
    }
Ejemplo n.º 2
0
    int EvaluateMoves(S_CurState i_stCurrent, int i_iLevel, bool i_bShallow)
    {
        int   i, iMove = 0;
        float fBest = 1000000000, fWorst = -1000000000;

        float[] dTest = new float[6];
        float   a, b, c, d, e;

        S_CurMove[] aMoves;
        int         iWorst;

        S_CurState stCurrent = i_stCurrent;

        stCurrent.fTimestep = 0.07f * TIME_FACTOR[i_iLevel];
        GenerateMoves(stCurrent, 0.07f * TIME_FACTOR[i_iLevel], out aMoves);

        for (i = 0; i < 6; i++)
        {
            a = aMoves[i].a;
            b = aMoves[i].b;
            c = aMoves[i].c;
            d = aMoves[i].d;
            e = aMoves[i].e;
            //dTest[i] = a * 0.0f + b * 1000.0f + c * 1.0f + d * 10.0f + e * 0.05f;
            dTest[i] = a * 0.0f + b * 10000.0f + c * 2.0f + d * 10.0f + e * 0.1f;

            if (dTest[i] > fWorst)
            {
                fWorst = dTest[i];
                iWorst = i;
            }
        }

        { //full search
            for (i = 0; i < 6; i++)
            {
                //recurse...
                stCurrent           = aMoves[i].stValue;
                stCurrent.iLastMove = i;
                if (i_iLevel < /**/ 1)
                {
                    dTest[i] += EvaluateMoves(stCurrent, i_iLevel + 1, true);
                }

                if (dTest[i] < fBest)
                {
                    fBest = dTest[i];
                    iMove = i;
                }
            }
        }

        if (i_iLevel > 0)
        {
            return((int)fBest);
        }
        else
        {
            return(iMove);
        }
    }

    //score for how far from the line
    float Strategy0(S_CurState stValues)
    {
        return(CheckPoint.PointDistanceToLineSeg(stValues.vPos, stValues.l0, stValues.l1));
    }

    //score for how much closer to goal
    float Strategy1(S_CurState stValues)
    {
        float fDistNow    = (stValues.vPos - stValues.l1).magnitude;
        float fDistBefore = ((stValues.vPos - (stValues.vVel * stValues.fTimestep)) - stValues.l1).magnitude;

        float fScore = (fDistNow - fDistBefore); //negative value is closer

        return(fScore);
    }

    float CalcLineAngle(Vector2 a, Vector2 b)
    {
        float difx = b.x - a.x;
        float dify = b.y - a.y;

        float fResult = 360.0f - (Mathf.Atan2(-dify, difx) * (180.0f / Mathf.PI));

        if (fResult >= 360.0f)
        {
            fResult -= 360.0f;
        }
        else if (fResult < 0.0f)
        {
            fResult += 360.0f;
        }

        return(fResult);
    }

    //score for pointing toward goal (more important further from goal)
    float Strategy2(S_CurState stValues)
    {
        float fGoalAngle = CalcLineAngle(stValues.vPos, stValues.l1);
        float fDiff      = fGoalAngle - stValues.fPointing;

        if (fDiff < 0)
        {
            fDiff += 360;
        }
        if (fDiff > 360)
        {
            fDiff -= 360;
        }
        if (fDiff > 180)
        {
            fDiff = 360 - fDiff;              //the difference of two angles can be max 180.
        }
        float fDistNow = (stValues.vPos - stValues.l1).magnitude;

        if (fDistNow > 1.0f)
        {
            fDistNow = 1.0f;
        }

        float fScore = fDiff / fDistNow;

        return(fScore);
    }

    //score for speed
    float Strategy3(S_CurState stValues)
    {
        float fVel = stValues.vVel.magnitude;

        float fScore = -fVel;

        return(fScore);
    }

    //score for speed vs dist to goal
    float Strategy4(S_CurState stValues)
    {
        float fVel = stValues.vVel.magnitude;

        float fDistNow = (stValues.vPos - stValues.l1).magnitude;

        if (fDistNow > 1.0f)
        {
            fDistNow = 1.0f;
        }

        float fScore = -fVel / (1.0f / fDistNow);

        return(fScore);
    }

    //score for dist to goal
    float Strategy5(S_CurState stValues)
    {
        float fDistNow = (stValues.vPos - stValues.l1).magnitude;

        float fScore = fDistNow;

        return(fScore);
    }

    ////////////////////////////////////////////////////////////////////////


    Vector2 vForceDir         = new Vector2(0, 0);
    int iLastInput            = 0; //bool bitfield
    float fReplayMessageTimer = 0;
    Vector2 vLastPosition;
    float[] fMeanSpeeds          = new float[16];
    internal float fMeanSpeed    = 0.0f;
    internal int iNumEnemiesNear = 0;
    internal int iNumBulletsNear = 0;
    float fCurrentSpeedSeg       = 0;
    int iBestMove = 0;
    void FixedUpdate()
    {
        if (!bInited)
        {
            return;
        }

        float fDist = (oRb.position - vLastPosition).magnitude;

        if (fDist > 0.80f)
        {
            fDist = 0.0f;                //detect when player has jumped to a new position (after death)
        }
        //mean speed calculation (used in race music)
        int iLastSec = (int)fCurrentSpeedSeg;

        fCurrentSpeedSeg += Time.fixedDeltaTime;
        if (fCurrentSpeedSeg >= 16.0f)
        {
            fCurrentSpeedSeg -= 16.0f;
        }
        int iCurSec = (int)fCurrentSpeedSeg;

        if (iCurSec != iLastSec)
        {
            fMeanSpeeds[iCurSec] = 0.0f;
        }
        fMeanSpeeds[iCurSec] += fDist;
        fMeanSpeed            = 0.0f;
        for (int i = 0; i < fMeanSpeeds.Length; i++)
        {
            if (i != iCurSec)
            {
                fMeanSpeed += fMeanSpeeds[i];
            }
        }
        fMeanSpeed = fMeanSpeed / (fMeanSpeeds.Length - 1) * 10;

        //enemies near (used in mission music)
        iNumEnemiesNear = oMap.GetNumEnemiesNearPlayer();
        //or enemy bullets near (used in mission music)
        iNumBulletsNear = oMap.GetNumBulletsNearPlayer();

        //distance achievement
        fAchieveDistance += fDist * 10;

        vLastPosition      = oRb.position;
        fTotalTimeMission += Time.fixedDeltaTime;
        if (bTimeCounting)
        {
            fTotalTime += Time.fixedDeltaTime;
        }

        //////get input, either from replay or from human player
        if (GameLevel.bRunReplay)
        {
            ReplayMessage rm;
            while (GameLevel.theReplay.Get(out rm, 0))
            {
                //we got new input
                if (rm.iType == (byte)MsgType.MOVEMENT)
                {
                    oRb.position = rm.vPos;
                    oRb.velocity = rm.vVel;
                    oRb.rotation = rm.fDirection;
                    bThrottle    = (rm.iKeyFlag & 8) != 0;
                    bLeft        = (rm.iKeyFlag & 4) != 0;
                    bRight       = (rm.iKeyFlag & 2) != 0;
                    bAdjust      = (rm.iKeyFlag & 1) != 0;
                }
                if (rm.iType == (byte)MsgType.BULLETP_NEW)
                {
                    //part of CreateBullet()
                    S_BulletInfo stBulletInfo;
                    stBulletInfo.vPos       = rm.vPos;
                    stBulletInfo.vVel       = rm.vVel;
                    stBulletInfo.fDirection = rm.fDirection;
                    GameObject o = Instantiate(oMap.oBulletObjBase, oMap.transform);
                    o.GetComponent <Bullet>().Init(stBulletInfo, 0 /*iOwnerID*/);

                    oASGeneral.PlayOneShot(oClipFire);
                }
                if (rm.iType == (byte)MsgType.PLAYER_KILL)
                {
                    oRb.position = rm.vPos;
                    oRb.velocity = rm.vVel;
                    oRb.rotation = rm.fDirection;
                    Kill(false);
                }
            }
        }