public override Vector2[] MakeDecisions(FlockControl.UnityState us)
    {
        generateRewards(us);


        Vector2[] sfs  = new Vector2[us.birds.Length];
        float[]   mags = new float[sfs.Length];
        for (int i = 0; i < us.birds.Length; i++)
        {
            if (!us.birds [i].Moving)
            {
                sfs [i]  = Vector2.zero;
                mags [i] = 0;
                continue;
            }
            sfs [i] = getStaticForces(us, i);
            mags[i] = sfs[i].magnitude;
        }

        Vector2[] forces = new Vector2[us.birds.Length];
        for (int i = 0; i < us.birds.Length; i++)
        {
            if (!us.birds [i].Moving)
            {
                forces [i] = Vector2.zero;
                continue;
            }
            Vector2 df = repulsion(us.birds, mags, us.birds [i]) + aligment(us.birds, mags, us.birds [i]);
            Vector2 f  = sfs [i] + df;
            forces [i] = steer(us.birds [i], f);
        }

        return(forces);
    }
Exemplo n.º 2
0
    private float calcScore(FlockControl.UnityState us, BirdControl me)
    {
        float score = 0;

        float gd = (us.goal.transform.position - transform.position).magnitude;

        score += GOAL_CONST * Mathf.Min(ASYMPTOTE, 1 / Mathf.Sqrt(gd));

        if (!me.Moving)
        {
            return(score);
        }

        foreach (BirdControl b in us.birds)
        {
            if (b.Equals(me) || !b.Moving)
            {
                continue;
            }

            float d = me.GetDistance(b).dist;
            score += BIRD_CONST * Mathf.Min(ASYMPTOTE, 1 / Mathf.Sqrt(d));
        }

        for (int i = 0; i < us.walls.Length; i++)
        {
            float d = me.WallDistance(i).dist;
            score += WALL_CONST * Mathf.Min(ASYMPTOTE, 1 / Mathf.Sqrt(d));
        }

        return(score);
    }
Exemplo n.º 3
0
 public void SetScore(FlockControl.UnityState us)
 {
     for (int i = 0; i < us.birds.Length; i++)
     {
         scores[i] = calcScore(us, us.birds[i]);
     }
 }
Exemplo n.º 4
0
    public void InitializeGrid(FlockControl.UnityState us)
    {
        graph    = new List <GraphPoint>();
        memoized = new Dictionary <GraphPoint, PathDistance>();

        CircleCollider2D cd = GetComponent <CircleCollider2D>();

        gameObject.transform.localScale = new Vector3(CHECK_DISTANCE * us.maxSize, CHECK_DISTANCE * us.maxSize);

        initCF(us);

        Collider2D[] others = new Collider2D[1];
        grid = new bool[(int)(us.roomWidth), (int)(us.roomHeight)];


        for (int x = 0; x < us.roomWidth; x++)
        {
            for (int y = 0; y < us.roomHeight; y++)
            {
                if (Vector2.SqrMagnitude(new Vector2(x, y) - (Vector2)us.goal.transform.position) < us.goal.transform.localScale.x * us.goal.transform.localScale.x)
                {
                    grid [(int)x, (int)y] = true;
                    continue;
                }

                transform.position = new Vector2(x, y);
                int hit = cd.OverlapCollider(cf, others);
                grid [x, y] = hit == 0;
            }
        }

        initGraph(us.goal.transform.position);
    }
Exemplo n.º 5
0
    public void InitializeGrid(FlockControl.UnityState us)
    {
        CircleCollider2D cd = GetComponent <CircleCollider2D>();

        gameObject.transform.localScale = new Vector3(CHECK_DISTANCE * us.maxSize, CHECK_DISTANCE * us.maxSize);
        ContactFilter2D cf = new ContactFilter2D();

        cf.useTriggers  = true;
        cf.layerMask    = LayerMask.GetMask("Wall");
        cf.useLayerMask = true;
        Collider2D[] others = new Collider2D[NUM_COLLIDERS];
        grid = new bool[(int)(us.roomWidth / GRID_STEP), (int)(us.roomHeight / GRID_STEP)];


        for (float x = 0; x < us.roomWidth; x += GRID_STEP)
        {
            for (float y = 0; y < us.roomHeight; y += GRID_STEP)
            {
                transform.position = new Vector2(x, y);
                int hit = cd.OverlapCollider(cf, others);
                int gx  = (int)(x / GRID_STEP);
                int gy  = (int)(y / GRID_STEP);
                if (Vector2.SqrMagnitude(new Vector2(x, y) - (Vector2)us.goal.transform.position) < us.goal.transform.localScale.x * us.goal.transform.localScale.x)
                {
                    grid [gx, gy] = true;
                    continue;
                }

                grid [gx, gy] = hit == 0;
            }
        }
        // @Javiar: Foreach node in the grid, look at its eight neighbors
        // Also be sure to include the goal position in the graph you make, even though its neighbors will likely be in the grid
    }
Exemplo n.º 6
0
 private void initCF(FlockControl.UnityState us)
 {
     gameObject.transform.localScale = new Vector3(CHECK_DISTANCE * us.maxSize, CHECK_DISTANCE * us.maxSize);
     cf              = new ContactFilter2D();
     cf.useTriggers  = true;
     cf.layerMask    = LayerMask.GetMask("Wall");
     cf.useLayerMask = true;
 }
    private int giveToken(FlockControl.UnityState us, int bird, int tokens, bool[] nextGotToken)
    {
        nextGotToken [bird] = true;
        BirdControl me = us.birds [bird];

        Vector2[] path = pf.CalculatePath(me);
        rewardForces [bird] = rewardPathfind(path, me);
        return(tokens - 1);
    }
Exemplo n.º 8
0
 public virtual Vector2[] MakeDecisions(FlockControl.UnityState us)
 {
     Vector2[] decisions = new Vector2[us.birds.Length];
     for (int i = 0; i < decisions.Length; i++)
     {
         decisions [i] = Vector2.zero;
     }
     return(decisions);
 }
    private Vector2 getStaticForces(FlockControl.UnityState us, int birdNumber)
    {
        BirdControl me = us.birds [birdNumber];

        Vector2 cohes = cohesion(us.birds, me);

        Vector2 obstcl = obstacle(us.walls, me);

        Vector2 goal = rewardForces [me.Number];

        Vector2 bndry = boundary(us, me);

        return(cohes + obstcl + goal + bndry);
    }
Exemplo n.º 10
0
    private Vector2 boundary(FlockControl.UnityState us, BirdControl me)
    {
        float xForce = 0;
        float yForce = 0;

        // Also, in this case, we are limiting the individual forces in the x and y dimensions to the force and distance of the genomes boundary
        // Whereas in other forces we limit the vector(x,y) to the corresponding parameters
        if (me.transform.position.x < us.roomWidth / 2)
        {
            float xDist = me.transform.position.x;
            if (xDist <= genome.Boundary.Distance)
            {
                xForce = genome.Boundary.Constant / Mathf.Pow(xDist, genome.Boundary.Exponent);
            }
        }
        else
        {
            float xDist = us.roomWidth - me.transform.position.x;
            if (xDist <= genome.Boundary.Distance)
            {
                xForce = -1 * genome.Boundary.Constant / Mathf.Pow(xDist, genome.Boundary.Exponent);
            }
        }

        if (me.transform.position.y < us.roomHeight / 2)
        {
            float yDist = me.transform.position.y;
            if (yDist <= genome.Boundary.Distance)
            {
                yForce = genome.Boundary.Constant / Mathf.Pow(yDist, genome.Boundary.Exponent);
            }
        }
        else
        {
            float yDist = us.roomHeight - me.transform.position.y;
            if (yDist <= genome.Boundary.Distance)
            {
                yForce = -1 * genome.Boundary.Constant / Mathf.Pow(yDist, genome.Boundary.Exponent);
            }
        }
        return(new Vector2(xForce, yForce));
    }
Exemplo n.º 11
0
 public override void StartGeneration(FlockControl.UnityState us)
 {
     pf.InitializeGrid(us);
     genome         = dna.Next();
     gotRewardToken = new bool[us.birds.Length];
 }
Exemplo n.º 12
0
    private void generateRewards(FlockControl.UnityState us)
    {
        int pathfindTokens = PATHFIND_TOKENS;

        rewardForces = new Vector2[us.birds.Length];
        bool[] nextGotToken = new bool[us.birds.Length];

        /* In this function, we give away a number of tokens equal to PATHFIND_TOKENS to birds so that they use the more computational expensive pathfinding.
         * We prioritize the birds that previously received tokens, then birds with no leaders, but we want to make sure that as the number of active birds falls,
         * we still give away all of our tokens to birds that are active. If we have more tokens than active birds, every bird should use pathfinding.
         */

        // First we give priority to birds that are already holding tokens
        for (int bird = 0; bird < us.birds.Length; bird++)
        {
            BirdControl me = us.birds [bird];
            if (!gotRewardToken [bird] || !me.Moving)
            {
                continue;
            }
            if (Random.value > genome.Pathfind.Carryover)
            {
                continue;
            }
            // This bird had a token and carries it over in this frame
            pathfindTokens = giveToken(us, bird, pathfindTokens, nextGotToken);
        }

        // Then we prioritize birds with no leaders
        int[] birdIndex = range(us.birds.Length);
        shuffle(birdIndex);
        for (int i = 0; i < birdIndex.Length && pathfindTokens > 0; i++)
        {
            int         bird = birdIndex [i];
            BirdControl me   = us.birds [bird];
            if (!me.Moving || nextGotToken [bird])
            {
                continue;
            }

            bool hasLeader = false;
            foreach (BirdControl b in us.birds)
            {
                if (b.Equals(me) || !b.Moving)
                {
                    continue;
                }

                float dist = me.GetDistance(b).dist;
                // Distance here is used a bit differently than in other cases, but it is trained just the same and does not result in any issues.
                if (dist > genome.Pathfind.Distance)
                {
                    continue;
                }

                hasLeader = hasLeader || inView(b, me);
            }

            if (hasLeader)
            {
                continue;
            }
            // This bird has no leader so use a token
            pathfindTokens = giveToken(us, bird, pathfindTokens, nextGotToken);
        }

        // Now we give out the rest of the tokens randomly
        birdIndex = range(us.birds.Length);
        shuffle(birdIndex);
        for (int i = 0; i < birdIndex.Length && pathfindTokens > 0; i++)
        {
            int         bird = birdIndex [i];
            BirdControl me   = us.birds [bird];
            if (!me.Moving || nextGotToken [bird])
            {
                continue;
            }
            // This bird has received a token through random chance
            pathfindTokens = giveToken(us, bird, pathfindTokens, nextGotToken);
        }

        // The remainder of the birds do not receive tokens and so just do simple pathfinding towards the goal
        for (int bird = 0; bird < us.birds.Length; bird++)
        {
            BirdControl me = us.birds [bird];
            if (!me.Moving)
            {
                continue;
            }
            if (nextGotToken [bird])
            {
                // This bird already received a token
                continue;
            }
            rewardForces [bird] = rewardSimple(us.goal.transform.position, me);
        }

        gotRewardToken = nextGotToken;
    }
Exemplo n.º 13
0
 public virtual void StartGeneration(FlockControl.UnityState us)
 {
 }