// Returns the path index - the index of the next path node to target given the current player int getNewPathIndex(World.Player player, int currentIndex) { if (strategy.SearchPath == null) { return(currentIndex); } int pathLength = strategy.SearchPath.States.Count; // Get target for (int i = 0; i + currentIndex < pathLength; i++) { BlockWorld targetWorld = strategy.SearchPath.States[currentIndex + i]; int targetI = targetWorld.Player.I; int targetJ = targetWorld.Player.J; int playerI = World.XToI(player.X); int playerJ = World.YToJ(player.Y); // If the player is touching the next path coord, then return the index of the new path coord if (playerI == targetI && playerJ == targetJ) { return(currentIndex + i + 1); } } return(currentIndex); }
// 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; } }
private static void Main(string[] args) { using (BlockWorld gw = new BlockWorld(800, 600, "Test")) { gw.Run(60.0); } }
// A player's danger zone must be calculated from a World and a blockWorld public DangerZone(int playerNum, World world, BlockWorld blockWorld) { // Init danger array dangerZoneArray = new float[World.BlocksWidth, dangerZoneHeight]; // Init to zero for (int i = 0; i < World.BlocksWidth; i++) { for (int j = 0; j < dangerZoneHeight; j++) { dangerZoneArray[i, j] = 0.0f; } } // Store block world as a copy for modification this.blockWorld = blockWorld.Clone(); // Uses exact filtering to compute a belief distribution for player position // and weapon type/ammo sourceBeliefs = new Dictionary <IJCoords, ProjectileSourceBelief>(); computeSourceBeliefs(playerNum, world); // For each source belief computed by exact filtering, run the trajectory runTrajectories(); }
// Returns a new path with a state and cost added on BUT SAME ARRAY public Path ExtendedPath(BlockWorld newState, float newCost) { List <BlockWorld> newStateList = states.ToList(); newStateList.Add(newState); return(new Path(cost + newCost, newStateList)); }
public GenerateChunkTask(WorldPopulator populator, BlockWorld world) { this.populator = populator; this.world = world; chunk = new UngeneratedChunk(); world.EnsureFullyGenerated(); }
public BlockGroup(int size, int x, int y, int z, BlockWorld world) { this.size = size; this.x = x; this.y = y; this.z = z; this.world = world; }
override public float Level2HeuristicFunction(BlockWorld blockWorld) { int playerI = blockWorld.Player.I; int playerJ = blockWorld.Player.J; int opponentI = Level2DangerZone.SourceI; int opponentJ = Level2DangerZone.SourceJ; return(RunAwayBlockDistance - Util.ManhattanDistance(playerI, playerJ, opponentI, opponentJ)); }
private void Awake() { selectionBox = Instantiate(blockSelectionPrefab) as GameObject; selectionBox.SetActive(false); if (world == null) { world = FindObjectOfType <BlockWorld>(); } }
public Game(BlockWorld world, IWorldManager manager, IGenerator <Chunk <Block>, List <PointB> > animalSpawner) { this.manager = manager; this.animalSpawner = animalSpawner; manager.AddAlert += SpawnAnimals; World = world; Animals = new List <Cow>(); }
// Render public void Render(Game resourceScript, int startIndex = 0) { for (int i = startIndex; i < States.Count; i++) { BlockWorld world = States[i]; BlockWorld.BlockPlayer player = world.Player; GameObject obj = Object.Instantiate(resourceScript.Protopath); obj.transform.position = new Vector3(World.IToXMin(player.I), World.JToYMin(player.J)); SpriteRenderer renderer = obj.GetComponent <SpriteRenderer>(); renderer.color = new Color(1.0f, 1.0f, 1.0f, 0.25f); } }
// Clone public BlockWorld Clone() { BlockWorld world = new BlockWorld(); world.Player = Player.Clone(); world.Powerups = new List <BlockPowerup>(); foreach (BlockPowerup powerup in Powerups) { world.Powerups.Add(powerup.Clone()); } world.ground = (bool[, ])ground.Clone(); world.justCollectedAmmo = justCollectedAmmo; // Any other members should go here... return(world); }
override public float Level2HeuristicFunction(BlockWorld blockWorld) { BlockWorld.BlockPlayer player = blockWorld.Player; // Return distance to nearest ammo float minDistance = float.MaxValue; foreach (BlockWorld.BlockPowerup powerup in blockWorld.Powerups) { float d = Util.ManhattanDistance(powerup.I, powerup.J, player.I, player.J); if (d < minDistance) { minDistance = d; } } return(minDistance); }
protected override void OnLoad(EventArgs e) { GL.ClearColor(Color4.DarkSlateGray); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.VertexProgramPointSize); program = new ShaderProgram() .AttachShader(Shader.FromFile("./Assets/Shader/Fragment.glsl", ShaderType.FragmentShader)) .AttachShader(Shader.FromFile("./Assets/Shader/Vertex.glsl", ShaderType.VertexShader)) .Link(); hudprogram = new ShaderProgram() .AttachShader(Shader.FromFile("./Assets/Shader/HudFragment.glsl", ShaderType.FragmentShader)) .AttachShader(Shader.FromFile("./Assets/Shader/HudVertex.glsl", ShaderType.VertexShader)) .Link(); texture = Texture.FromFiles(256, Block.Textures); texture.SetFiltering(TextureMinFilter.LinearMipmapLinear, TextureMagFilter.Linear); texture.SetLODBias(-0.7f); aoTexture = AmbientOcclusion.GetAOTexture4();//Texture.FromFile("./Assets/Textures/ao.png"); aoTexture.SetWarpMode(TextureWrapMode.MirroredRepeat); Console.WriteLine(GL.GetError()); camera = new Camera(75f * (float)Math.PI / 180, (float)Width / (float)Height, 0.1f, 300.0f) { Position = new Vector3(8, 50, 8) }; frustum = new Frustum(camera.CameraMatrix); world = new BlockWorld(); Resize += (sender, ea) => { GL.Viewport(0, 0, Width, Height); camera.Aspect = (float)Width / (float)Height; }; GC.Collect(); base.OnLoad(e); }
public void Compile(BlockWorld world) { blockCount = 0; MaterialBlock matProps; for (int i = 0; i < materials.Length; i++) { if (materials[i] == null) { blocks[i] = 0; blockStates[i] = 0; continue; } matProps = world.BlockTypes.GetMaterialProperties(materials[i]); blockCount++; blocks[i] = matProps.Id; blockStates[i] = matProps.BlockState; } }
// Runs trajectories of projectile source beliefs void runTrajectories() { // Iterate through each possibility foreach (KeyValuePair <IJCoords, ProjectileSourceBelief> entry in sourceBeliefs) { ProjectileSourceBelief sourceBelief = entry.Value; int sourceI = entry.Key.I; int sourceJ = entry.Key.J; int sourceAmmo = sourceBelief.Ammo; float sourceProbability = sourceBelief.Probability; // Iterate through each weapon type for each possibility foreach (WeaponType weaponType in sourceBelief.PossibleWeapons) { if (weaponType == WeaponType.Lightning) { // Add danger to all above for lightning - easy for (int j = -World.FloorLevelJ; j < World.BlocksHeight; j++) { if (j < sourceJ) { addDanger(sourceI, j, sourceProbability * LightningDangerWeight); } } } else { // Recursively add values to the danger zone 2D array // Use same blockworld for both directions since paths won't cross BlockWorld newBlockWorld = blockWorld.Clone(); addDangerToBlockAndNeighbors(sourceI, sourceJ, weaponType, sourceProbability, sourceAmmo, true, newBlockWorld); addDangerToBlockAndNeighbors(sourceI, sourceJ, weaponType, sourceProbability, sourceAmmo, false, newBlockWorld); } } } }
private void Awake() { world = GetComponent <BlockWorld>(); loadOrder = GetComponent <ChunkLoadOrder>(); workers = new TerrainWorker[workerThreads]; for (int i = 0; i < workerThreads; i++) { workers[i] = new TerrainWorker(); } loadOrder.UpdateBufferRadius(chunkLoadRadius, chunkLoadHeight); genTasks = new GenerateChunkTask[workerThreads]; for (int i = 0; i < workerThreads; i++) { genTasks[i] = new GenerateChunkTask(worldPopulator, world); } for (int i = 0; i < pregenerateChunks; i++) { GenerateNextChunk(true, 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); }
private PointF DefineSpawn(PointI ready) { var chunk = World[ready]; for (byte x = 0; x < Chunk <Block> .XLength; x++) { for (byte z = 0; z < Chunk <Block> .ZLength; z++) { for (byte y = 253; y > 0; y--) { var p0 = new PointB(x, y, z); var p1 = new PointB(x, (byte)(y + 1), z); var p2 = new PointB(x, (byte)(y + 2), z); if (chunk[p0] != null && chunk[p1] == null && chunk[p2] == null) { return((BlockWorld.GetAbsolutePosition(p1, ready).AsVector() + new Vector3(0.5f, 0, 0.5f)) .AsPointF()); } } } } throw new ArgumentException("Не удалось найти подходящего для спавна места", ready.ToString()); }
// Compares equality of two block worlds public bool PropertiesEqual(BlockWorld blockWorld) { // Compare ground for (int i = 0; i < World.BlocksWidth; i++) { for (int j = 0; j < World.BlocksHeight; j++) { if (ground[i, j] != blockWorld.ground[i, j]) { return(false); } } } if (justCollectedAmmo != blockWorld.justCollectedAmmo) { return(false); } // Compare player if (!Player.PropertiesEqual(blockWorld.Player)) { return(false); } // Compare powerups for (int i = 0; i < Powerups.Count; i++) { if (!Powerups[i].PropertiesEqual(blockWorld.Powerups[i])) { return(false); } } return(true); }
public void DownloadSchematic(BlockWorld world, BlockLocation minEdge) { if (blocks == null || materials == null || world == null) { return; } int minX = minEdge.x; int minY = minEdge.y; int minZ = minEdge.z; int maxX = minEdge.x + sizeX - 1; int maxY = minEdge.y + sizeY - 1; int maxZ = minEdge.z + sizeZ - 1; int minChunkX = minX >> 4; int minChunkY = minY >> 4; int minChunkZ = minZ >> 4; int maxChunkX = maxX >> 4; int maxChunkY = maxY >> 4; int maxChunkZ = maxZ >> 4; Chunk chunk; int a, b, c, x, y, z; int minX2, minY2, minZ2; int maxX2, maxY2, maxZ2; int index; for (a = minChunkX; a <= maxChunkX; a++) { for (b = minChunkY; b <= maxChunkY; b++) { for (c = minChunkZ; c <= maxChunkZ; c++) { chunk = world.GetChunkByCoords(a, b, c, true); minX2 = Mathf.Max(minX, chunk.chunkX * 16); minY2 = Mathf.Max(minY, chunk.chunkY * 16); minZ2 = Mathf.Max(minZ, chunk.chunkZ * 16); maxX2 = Mathf.Min(maxX, chunk.chunkX * 16 + 15); maxY2 = Mathf.Min(maxY, chunk.chunkY * 16 + 15); maxZ2 = Mathf.Min(maxZ, chunk.chunkZ * 16 + 15); for (x = minX2; x <= maxX2; x++) { for (y = minY2; y <= maxY2; y++) { for (z = minZ2; z <= maxZ2; z++) { index = (x - minX) * sizeY * sizeZ + (y - minY) * sizeZ + (z - minZ); chunk.SetBlock(x & 15, y & 15, z & 15, blocks[index] == 0 ? null : materials[blocks[index] - 1]); } } } } } } if (world.autoRemesh) { world.UpdateAllChunks(); } }
override public float Level2CostFunction(BlockWorld blockWorld) { return(1.0f + Level2DangerDistanceRatio * Level2DangerZone.CheckDanger(blockWorld.Player.I, blockWorld.Player.J)); }
override public bool Level2GoalFunction(BlockWorld blockWorld) { return(blockWorld.JustCollectedAmmo); }
override public float Level2HeuristicFunction(BlockWorld blockWorld) { return(World.WallDepthJ - blockWorld.Player.J); }
override public bool Level2GoalFunction(BlockWorld blockWorld) { return(blockWorld.Player.J >= World.WallDepthJ); }
// Outputs the optimal path public Path ComputeBestPath(BlockWorld blockWorld) { HeapPriorityQueue <Path> frontier = new HeapPriorityQueue <Path>(MaxNodes); HashSet <BlockWorld> explored = new HashSet <BlockWorld>(); // Initial state, path BlockWorld initialState = blockWorld; Path initialPath = new Path(0, new List <BlockWorld>() { initialState }); // Add the initial path to the frontier frontier.Enqueue(initialPath, 0 + Heuristic(initialState)); // Find paths int expansions = 0; while (frontier.Count > 0) { Path path = frontier.Dequeue(); BlockWorld lastWorld = path.Last(); // Return the no path if (expansions > MaxExpansions) { return(null); } // Check goal if (GoalFunction(lastWorld)) { return(path); } // Mark as explored explored.Add(lastWorld); // Iterate over possible actions List <BlockWorldAction> possibleActions = lastWorld.ApplicableActions(); foreach (BlockWorldAction action in possibleActions) { // Try the action on a cloned block world BlockWorld newWorld = lastWorld.Clone(); newWorld.Advance(action); // Check if explored already bool alreadyExplored = false; foreach (BlockWorld exploredWorld in explored) { if (exploredWorld.PropertiesEqual(newWorld)) { alreadyExplored = true; break; } } if (!alreadyExplored) { // Extend path Path newPath = path.ExtendedPath(newWorld, CostFunction(newWorld)); // Add to frontier frontier.Enqueue(newPath, Heuristic(newWorld) + newPath.Cost); } } expansions++; } // No solution exists return(null); }
protected void OnEnable() { m_BlockWorld = target as BlockWorld; }
public void UploadSchematic(BlockWorld world, BlockLocation block1, BlockLocation block2) { int minX = Mathf.Min(block1.x, block2.x); int minY = Mathf.Min(block1.y, block2.y); int minZ = Mathf.Min(block1.z, block2.z); int maxX = Mathf.Min(block1.x, block2.x); int maxY = Mathf.Min(block1.y, block2.y); int maxZ = Mathf.Min(block1.z, block2.z); int minChunkX = minX >> 4; int minChunkY = minY >> 4; int minChunkZ = minZ >> 4; int maxChunkX = maxX >> 4; int maxChunkY = maxY >> 4; int maxChunkZ = maxZ >> 4; sizeX = maxX - minX + 1; sizeY = maxY - minY + 1; sizeZ = maxZ - minZ + 1; blocks = new ushort[sizeX * sizeY * sizeZ]; Chunk chunk; int a, b, c, x, y, z; int minX2, minY2, minZ2; int maxX2, maxY2, maxZ2; for (a = minChunkX; a <= maxChunkX; a++) { for (b = minChunkY; b <= maxChunkY; b++) { for (c = minChunkZ; c <= maxChunkZ; c++) { chunk = world.GetChunkByCoords(a, b, c, false); if (chunk == null) { continue; } minX2 = Mathf.Max(minX, chunk.chunkX * 16); minY2 = Mathf.Max(minY, chunk.chunkY * 16); minZ2 = Mathf.Max(minZ, chunk.chunkZ * 16); maxX2 = Mathf.Min(maxX, chunk.chunkX * 16 + 15); maxY2 = Mathf.Min(maxY, chunk.chunkY * 16 + 15); maxZ2 = Mathf.Min(maxZ, chunk.chunkZ * 16 + 15); for (x = minX2; x <= maxX2; x++) { for (y = minY2; y <= maxY2; y++) { for (z = minZ2; z <= maxZ2; z++) { blocks[(x - minX) * sizeY * sizeZ + (y - minY) * sizeZ + (z - minZ)] = chunk.GetBlockId(x & 15, y & 15, z & 15); } } } } } } ArrayList materialList = new ArrayList(); for (int i = 0; i < blocks.Length; i++) { if (blocks[i] == 0) { continue; } if (!materialList.Contains(blocks[i])) { materialList.Add(blocks[i]); } blocks[i] = (ushort)(materialList.IndexOf(blocks[i]) + 1); } materials = new Material[materialList.Count]; for (int i = 0; i < materials.Length; i++) { materials[i] = materialList[i] as Material; } }
// 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; } } } }
/// <summary> /// Sets up the character with necessary references. /// </summary> /// <param name="client">The client to send data using.</param> /// <param name="blockWorld">The block world reference.</param> public void Setup(UnityClient client, BlockWorld blockWorld) { this.client = client; this.blockWorld = blockWorld; }