protected Dictionary <LevelBoard.Directions, Piece> CheckAdjacentSolderTiles(Agent agent) { Dictionary <LevelBoard.Directions, Piece> adjacents = new Dictionary <LevelBoard.Directions, Piece>(); // For each cardinal direction for (var i = 0; i < 4; i++) { var dir = (LevelBoard.Directions)(i * 2); // Create Direction // Get coordinates of adjacent Space in that Direction var coords = LevelBoard.GetAdjacentCoords(agent.Coords, dir); // Get Tile at that Space var tile = agent.TileAt(coords); // If there's a Solder Tile there if (tile != null && tile.Type == Tile.Types.Solder) { // Get Piece at that Space var piece = agent.PieceAt(coords); // Add adjacency adjacents.Add(dir, piece); } } return(adjacents); }
protected virtual Dictionary <LevelBoard.Directions, CircuitComponent> CheckAdjacentSolderTiles(Agent agent) { Dictionary <LevelBoard.Directions, CircuitComponent> adjacents = new Dictionary <LevelBoard.Directions, CircuitComponent>(); for (var i = 0; i < 4; i++) { var dir = (LevelBoard.Directions)(i * 2); var coords = LevelBoard.GetAdjacentCoords(agent.Coords, dir); var tile = agent.TileAt(coords); // If there's a Solder Tile there if (tile != null && tile.Type == Tile.Types.Solder) { var piece = agent.PieceAt(coords); if (piece == null) { adjacents.Add(dir, null); } else if (piece is CircuitComponent component && component.Stats.Food < component.Stats.MaxFood) { adjacents.Add(dir, component); } } } return(adjacents); }
override public Action Available(Agent agent) { var adjacents = CheckAdjacentSolderTiles(agent); var start = ((int)agent.Orientation) / 2; for (var i = 0; i < 4; i++) { var dir = (LevelBoard.Directions)(((start + i + 3) % 4) * 2); if (adjacents.TryGetValue(dir, out var component)) { var tcoords = LevelBoard.GetAdjacentCoords(agent.Coords, dir); if (tcoords.sqrMagnitude > 1000f) { continue; } if (component == null) { return(new ElectricMovement(dir, tcoords)); } else { return(new Charge(component)); } } } return(null); }
public override bool Undo(Agent agent) { var oppositeDir = (LevelBoard.Directions)(((int)this.Direction + 4) % 8); var origCoords = LevelBoard.GetAdjacentCoords(this.MoveCoords, oppositeDir); agent.Move(origCoords, 1000f); agent.Rotate(this.OrigOrientation, 1f); agent.MoveInBoard(origCoords); agent.RotateInBoard(this.OrigOrientation); return(base.Undo(agent)); }
override public Action Available(Agent agent) { var adjacents = CheckAdjacentSolderTiles(agent); #region Crossing Attributes var crossing = false; List <LevelBoard.Directions> unexplored = null; if (adjacents.Count > 2) { crossing = true; var slime = (SmartElectricSlime)agent; slime.UpdateCrossing(slime.Coords, new List <LevelBoard.Directions>(adjacents.Keys)); unexplored = slime.GetUnexploredPaths(slime.Coords); } #endregion var start = ((int)(agent.Orientation)) / 2; var maxUtility = 0; var bestChoice = LevelBoard.Directions.None; var isMove = true; // For each cardinal Direction for (var i = 0; i < 4; i++) { // Make the Direction var dir = (LevelBoard.Directions)(((start + i + 3) * 2) % 8); // If there is an adjacent Solder Tile if (adjacents.TryGetValue(dir, out var piece)) { var utility = 1; // If there's a Piece that is not a Component // Or a Component that is at capacity, check the next Direction if ((piece != null && !(piece is CircuitComponent)) || (piece is CircuitComponent component && component.Stats.Food >= component.Stats.MaxFood)) { continue; } // If this Direction has not been explored if (crossing && unexplored.Contains(dir)) { utility += 1; } // If the utility is better going this way if (utility > maxUtility) { maxUtility = utility; bestChoice = dir; isMove = piece == null; } } } // If the best choice is not to stay in place if (bestChoice != LevelBoard.Directions.None) { if (isMove) { return(new SmartElectricMovement(bestChoice, LevelBoard.GetAdjacentCoords(agent.Coords, bestChoice), crossing)); } else { return(new Charge((CircuitComponent)adjacents[bestChoice], crossing)); } } return(null); }
public List <Piece> PiecesInSight(float range) { float toExplore = range; List <Piece> pieces = new List <Piece>(); Queue <Vector2Int> queue = new Queue <Vector2Int>(); queue.Enqueue(this.Coords); Dictionary <Vector2Int, LevelBoard.Directions> toExpand = new Dictionary <Vector2Int, LevelBoard.Directions> { { this.Coords, LevelBoard.Directions.None } }; Queue <Vector2Int> nextQueue; Dictionary <Vector2Int, LevelBoard.Directions> toExpandNext; while (toExplore > 0f) { nextQueue = new Queue <Vector2Int>(); toExpandNext = new Dictionary <Vector2Int, LevelBoard.Directions>(); while (queue.Count > 0) { Vector2Int coords = queue.Dequeue(); if (!toExpand.TryGetValue(coords, out LevelBoard.Directions originDir)) { continue; } toExpand.Remove(coords); int dirId = (int)originDir; Vector2Int adjCoords; Piece found; switch (originDir) { case LevelBoard.Directions.None: for (int i = 0; i < 8; i++) { LevelBoard.Directions checkDir = (LevelBoard.Directions)(i % 8); adjCoords = LevelBoard.GetAdjacentCoords(coords, checkDir); // Out of Bounds if (adjCoords.x == -1) { continue; } found = this.Puzzle.GetPiece(adjCoords); // No Piece in the space if (found == null) { if (i % 2 == 0 && toExplore - 1 >= 0f || i % 2 == 1 && toExplore - 1 >= 0.5f) { nextQueue.Enqueue(adjCoords); // Queue position to be checked toExpandNext.Add(adjCoords, checkDir); // List direction it was reached from } continue; } pieces.Add(found); // Add Piece to the list } break; case LevelBoard.Directions.East: case LevelBoard.Directions.South: case LevelBoard.Directions.West: case LevelBoard.Directions.North: for (int i = dirId - 1; i <= dirId + 1; i++) { LevelBoard.Directions checkDir = (LevelBoard.Directions)(i % 8); if (checkDir == LevelBoard.Directions.None) { checkDir = LevelBoard.Directions.SouthEast; } // Get adjacent space coordinates adjCoords = LevelBoard.GetAdjacentCoords(coords, checkDir); // Out of Bounds if (adjCoords.x == -1) { continue; } if (toExplore - 1 >= 0f) { nextQueue.Enqueue(adjCoords); // Queue position to be checked toExpandNext.Add(adjCoords, checkDir); // List direction it was reached from } found = this.Puzzle.GetPiece(adjCoords); // No Piece in the space if (found == null) { continue; } pieces.Add(found); // Add Piece to the list } break; case LevelBoard.Directions.SouthEast: case LevelBoard.Directions.SouthWest: case LevelBoard.Directions.NorthEast: case LevelBoard.Directions.NorthWest: adjCoords = LevelBoard.GetAdjacentCoords(coords, originDir); // Out of Bounds if (adjCoords.x == -1) { continue; } if (toExplore - 1 >= 0.5f) { nextQueue.Enqueue(adjCoords); // Queue position to be checked toExpandNext.Add(adjCoords, originDir); // List direction it was reached from } found = this.Puzzle.GetPiece(adjCoords); // No Piece in the space if (found == null) { continue; } pieces.Add(found); // Add Piece to the list break; } } queue = nextQueue; toExpand = toExpandNext; toExplore--; } return(pieces); }
public override Action Available(Agent agent) { var adjacents = this.CheckAdjacentSolderTiles(agent); #region Crossing Attributes var crossing = false; Dictionary <LevelBoard.Directions, int> utilities = null; var slime = (SmarterElectricSlime)agent; // If this is a Crossing if (adjacents.Count > 2) { crossing = true; slime.UpdateCrossing(slime.Coords, new List <LevelBoard.Directions>(adjacents.Keys)); utilities = slime.GetUtilities(slime.Coords); } #endregion var start = ((int)(agent.Orientation)) / 2; var maxUtility = float.MinValue; var bestChoice = LevelBoard.Directions.None; var isMove = true; // For each cardinal Direction for (var i = 0; i < 4; i++) { // Make the Direction var dir = (LevelBoard.Directions)(((start + i + 3) * 2) % 8); // If there is an adjacent Solder Tile if (adjacents.TryGetValue(dir, out var piece)) { var utility = (4 - i) * 0.25f; // If this is a Crossing get the Directions utility if (crossing && utilities.ContainsKey(dir)) { utility += utilities[dir]; } if (dir == LevelBoard.InvertDirection(agent.Orientation)) { if (utility > 0) { utility *= 0.5f; } else { utility *= 2f; } } // If there's a Piece that is not a Component // Or a Component that is at capacity, check the next Direction if ((piece != null && !(piece is CircuitComponent)) || (piece is CircuitComponent component && component.Stats.Food >= component.Stats.MaxFood)) { if (utility > maxUtility) { slime.PathBlocked = true; } continue; } // If the utility is better going this way if (utility > maxUtility) { maxUtility = utility; bestChoice = dir; isMove = piece == null; } } } // If the best choice is not to stay in place if (bestChoice != LevelBoard.Directions.None) { if (isMove) { return(new SmarterElectricMovement(bestChoice, LevelBoard.GetAdjacentCoords(agent.Coords, bestChoice), crossing)); } else { return(new Charge((CircuitComponent)adjacents[bestChoice], crossing)); } } return(null); }