コード例 #1
0
        // Projects the powerup position downwards to rest on the ground
        public void ProjectDownwards(BlockWorld world)
        {
            // Don't project downwards if not falling anymore!
            if (!isFalling)
            {
                return;
            }

            // Speed and gravity fall
            if (Type != PowerupType.Speed && Type != PowerupType.Gravity)
            {
                return;
            }

            // Get nearest two horizontal indices
            int i1 = World.XToI(X - 64.0f);             // HACK: Powerup size better not change
            int i2 = i1 + 1;

            // Increase y until hit ground
            float y = World.FloorLevel;

            for (int j = 0; j < World.BlocksHeight; j++)
            {
                if (world.CheckGroundByIndex(i1, j) || world.CheckGroundByIndex(i2, j))
                {
                    break;
                }

                y += World.BlockSize;
            }
        }
コード例 #2
0
    override public bool Level2GoalFunction(BlockWorld blockWorld)
    {
        int playerI   = blockWorld.Player.I;
        int playerJ   = blockWorld.Player.J;
        int opponentI = Level2DangerZone.SourceI;
        int opponentJ = Level2DangerZone.SourceJ;

        // Check distance
        if (Util.ManhattanDistance(playerI, playerJ, opponentI, opponentJ) <= RunAwayBlockDistance)
        {
            return(false);
        }

        // Enforce no ground above
        bool groundAbove = false;

        for (int j = playerJ; j >= 0; j--)
        {
            if (blockWorld.CheckGroundByIndex(playerI, j))
            {
                groundAbove = true;
                break;
            }
        }
        if (groundAbove)
        {
            return(false);
        }

        // Enforce no danger
        if (Level2DangerZone.CheckDanger(playerI, playerJ) != 0.0f)
        {
            return(false);
        }

        return(true);
    }
コード例 #3
0
    // Recursively add danger to the 2D array
    void addDangerToBlockAndNeighbors(int i, int j, WeaponType type, float probability, int ammo,
                                      bool facingRight, BlockWorld blockWorld, bool isFalling = false)
    {
        // Base cases
        if (probability < epsilon)
        {
            return;
        }
        if (ammo == 0)
        {
            return;                    // Master mode has negative ammo - do not return
        }
        // Blow out ground if there is any at the current position. If there is
        if (blockWorld.CheckGroundByIndex(i, j))
        {
            // Another base case for immutable ground
            bool immutable = blockWorld.CheckGroundImmutableByIndex(i, j);
            if (immutable)
            {
                return;                        // End of the line
            }
            // Blow out ground otherwise
            blockWorld.SetGroundByIndex(i, j, false);
            addDangerToBlockAndNeighbors(i, j, type, probability * groundBlowoutFactor, ammo - 1,
                                         facingRight, blockWorld);
            return;
        }
        else
        {
            int normalized = facingRight ? -1 : 1;

            switch (type)
            {
            case WeaponType.Rockets: {
                addDanger(i, j, probability * RocketsDangerWeight);
                addDangerToBlockAndNeighbors(i + normalized, j, type, probability, ammo,
                                             facingRight, blockWorld);
                break;
            }

            case WeaponType.Bombs: {
                addDanger(i, j, probability * BombsDangerWeight);
                addDangerToBlockAndNeighbors(i, j + 1, type, probability, ammo, facingRight, blockWorld);
                break;
            }

            case WeaponType.Minions: {
                addDanger(i, j, probability * MinionsDangerWeight);

                bool groundDown  = blockWorld.CheckGroundByIndex(i, j + 1);
                bool groundRight = blockWorld.CheckGroundByIndex(i + normalized, j);
                bool goRight     = false;
                bool goDown      = false;

                // Do natural motion - right first unless hasn't fallen
                if (!groundRight && !groundDown)
                {
                    if (isFalling && blockWorld.CheckGroundByIndex(i + normalized, j + 1))
                    {
                        goRight = true;
                    }
                    else
                    {
                        goDown = true;
                    }
                }
                else if (!groundRight && groundDown)
                {
                    goRight = true;
                }
                else if (groundRight && !groundDown)
                {
                    goDown = true;
                }
                else
                {
                    // Block worlds diverge, so make a new one
                    BlockWorld newBlockWorld = blockWorld.Clone();

                    // Go both directions
                    addDangerToBlockAndNeighbors(i + normalized, j, type, probability / 2.0f,
                                                 ammo, facingRight, blockWorld, false);
                    addDangerToBlockAndNeighbors(i, j + 1, type, probability / 2.0f,
                                                 ammo, facingRight, newBlockWorld, true);
                }

                // Do sole motions
                if (goRight)
                {
                    addDangerToBlockAndNeighbors(i + normalized, j, type, probability,
                                                 ammo, facingRight, blockWorld, false);
                    return;
                }
                if (goDown)
                {
                    addDangerToBlockAndNeighbors(i, j + 1, type, probability,
                                                 ammo, facingRight, blockWorld, true);
                    return;
                }

                break;
            }
            }
        }
    }
コード例 #4
0
    // Computes a belief distribution for the projectile sources
    void computeSourceBeliefs(int playerNum, World world)
    {
        // Find player
        World.Player player  = playerNum == 1 ? world.Player1 : world.Player2;
        int          playerI = World.XToI(player.X);
        int          playerJ = World.YToJ(player.Y);

        sourceI = playerI;
        sourceJ = playerJ;

        // The initial source is at the player
        ProjectileSourceBelief initial = new ProjectileSourceBelief(1.0f, player.Ammo, player.Weapon);

        sourceBeliefs.Add(new IJCoords(playerI, playerJ), initial);

        // Compute distribution of projectile sources
        for (int iter = 0; iter < DistributionSteps; iter++)
        {
            Dictionary <IJCoords, ProjectileSourceBelief> newBeliefs = new Dictionary <IJCoords, ProjectileSourceBelief>();
            float newBeliefsTotal = 0.0f;

            // Advance our belief state, except keep the old one around for efficiency
            foreach (KeyValuePair <IJCoords, ProjectileSourceBelief> entry in sourceBeliefs)
            {
                ProjectileSourceBelief belief = entry.Value;

                int i = entry.Key.I;
                int j = entry.Key.J;

                float prior = belief.Probability;

                // Determine possible directions
                bool upPossible    = false;
                bool leftPossible  = false;
                bool rightPossible = false;
                bool downPossible  = false;
                bool stayPossible  = false;

                int  numPossibleDirections = 0;
                bool supported             = blockWorld.CheckPositionSupported(i, j);
                if (!supported)
                {
                    // Can only move down from unsupported positions
                    numPossibleDirections++;
                    downPossible = true;
                }
                else
                {
                    stayPossible = true;
                    numPossibleDirections++;

                    if (!blockWorld.CheckGroundByIndex(i, j + 1))
                    {
                        downPossible = true;
                        numPossibleDirections++;
                    }
                    if (!blockWorld.CheckGroundByIndex(i + 1, j))
                    {
                        leftPossible = true;
                        numPossibleDirections++;
                    }
                    if (!blockWorld.CheckGroundByIndex(i - 1, j))
                    {
                        rightPossible = true;
                        numPossibleDirections++;
                    }
                    if (!blockWorld.CheckGroundByIndex(i, j - 1))
                    {
                        upPossible = true;
                        numPossibleDirections++;
                    }
                }

                // Compute chance of each direction - uniform
                float chance        = 1.0f / numPossibleDirections;
                float derivedChance = chance * prior;

                // Update beliefs based on possible directions

                // Staying in place is always an option
                if (stayPossible)
                {
                    addBeliefUsingWorld(newBeliefs, i, j, belief, derivedChance, ref newBeliefsTotal);
                }

                if (upPossible)
                {
                    addBeliefUsingWorld(newBeliefs, i, j - 1, belief, derivedChance, ref newBeliefsTotal);
                }
                if (downPossible)
                {
                    addBeliefUsingWorld(newBeliefs, i, j + 1, belief, derivedChance, ref newBeliefsTotal);
                }
                if (leftPossible)
                {
                    addBeliefUsingWorld(newBeliefs, i + 1, j, belief, derivedChance, ref newBeliefsTotal);
                }
                if (rightPossible)
                {
                    addBeliefUsingWorld(newBeliefs, i - 1, j, belief, derivedChance, ref newBeliefsTotal);
                }
            }

            // Normalize our new belief state
            foreach (KeyValuePair <IJCoords, ProjectileSourceBelief> entry in newBeliefs)
            {
                entry.Value.Probability /= newBeliefsTotal;
            }

            // Update
            sourceBeliefs = newBeliefs;
        }
    }