Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }