// 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; } }