Ejemplo n.º 1
0
        /// <summary>
        /// Finds path in group through adjacent tiles
        /// </summary>
        ///
        /// <param name="group">Group of crops to find path through.</param>
        public List <ActionableTile> findFillPath(Group group, console console)
        {
            // Start a new path of actionable tiles
            // Actionable tiles are a standing place, and nearby tiles to water
            List <ActionableTile> path = new List <ActionableTile>();

            // Reset the visited values of each tile in group.
            foreach (Tile tile in group.getList())
            {
                this.map[tile.y][tile.x].reset();
            }

            // Queue for depth first search
            List <Tile> stack = new List <Tile>();

            stack.Add(group.findClosestTile(Game1.player.getTileX(), Game1.player.getTileY()).Item1);

            bool keepGoing;

            do
            {
                keepGoing = false;

                while (stack.Count > 0)
                {
                    Tile current = stack[stack.Count - 1];
                    stack.RemoveAt(stack.Count - 1);

                    if (current.visited)
                    {
                        continue;
                    }
                    else if (current.watered)
                    {
                        current.visited = true;

                        foreach (Tuple <int, int, Func <int, int, bool> > direction in this.directions)
                        {
                            if (direction.Item3(current.y + direction.Item1, current.x + direction.Item2))
                            {
                                Tile neighbor = this.map[current.y + direction.Item1][current.x + direction.Item2];
                                if (!neighbor.visited && group.Contains(neighbor))
                                {
                                    stack.Add(neighbor);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Start a new action
                        ActionableTile actionable = new ActionableTile(ActionableTile.Action.Water);
                        current.visited = true;

                        if (current.block)
                        {
                            int  score      = 0;
                            Tile bestOption = null;

                            // If you can stand on adjacents, do it.
                            foreach (Tuple <int, int, Func <int, int, bool> > direction in this.directions.Concat(this.diagonals))
                            {
                                if (direction.Item3(current.y + direction.Item1, current.x + direction.Item2))
                                {
                                    Tile neighbor = this.map[current.y + direction.Item1][current.x + direction.Item2];
                                    if (neighbor.block)
                                    {
                                        continue;
                                    }

                                    int neighborScore = 0;

                                    if (group.Contains(neighbor))
                                    {
                                        neighborScore += 5;
                                    }
                                    if (neighbor.waterable)
                                    {
                                        neighborScore += 5;
                                    }
                                    if (!neighbor.watered)
                                    {
                                        neighborScore += 5;
                                    }
                                    if (!neighbor.visited)
                                    {
                                        neighborScore += 5;
                                    }

                                    if (neighborScore > score)
                                    {
                                        bestOption = neighbor;
                                    }
                                }
                            }

                            if (bestOption == null)
                            {
                                continue;
                            }

                            // Set possible standing point.
                            actionable.setStand(bestOption.getPoint());
                        }
                        else
                        {
                            // Set this as standing position
                            actionable.setStand(current.getPoint());
                        }

                        // Water here
                        if (current.getPoint() == actionable.getStand())
                        {
                            actionable.pushExecuteOn(current.getPoint());
                            current.watered = true;
                        }
                        else if (this.map[actionable.getStand().Y][actionable.getStand().X].waterable && !this.map[actionable.getStand().Y][actionable.getStand().X].watered)
                        {
                            actionable.pushExecuteOn(actionable.getStand());
                            this.map[actionable.getStand().Y][actionable.getStand().X].watered = true;
                        }

                        // If you can water adjacents, do it.
                        foreach (Tuple <int, int, Func <int, int, bool> > direction in this.directions)
                        {
                            if (direction.Item3(actionable.getStand().Y + direction.Item1, actionable.getStand().X + direction.Item2))
                            {
                                Tile neighbor = this.map[actionable.getStand().Y + direction.Item1][actionable.getStand().X + direction.Item2];
                                if (neighbor.waterable && !neighbor.watered)
                                {
                                    actionable.pushExecuteOn(neighbor.getPoint());
                                    neighbor.watered = true;
                                }
                                if (!neighbor.visited && group.Contains(neighbor))
                                {
                                    stack.Add(neighbor);
                                }
                            }
                        }

                        // If you can water diagonals, do it.
                        foreach (Tuple <int, int, Func <int, int, bool> > direction in this.diagonals)
                        {
                            if (direction.Item3(actionable.getStand().Y + direction.Item1, actionable.getStand().X + direction.Item2))
                            {
                                Tile neighbor = this.map[actionable.getStand().Y + direction.Item1][actionable.getStand().X + direction.Item2];
                                if (neighbor.waterable && !neighbor.watered)
                                {
                                    actionable.pushExecuteOn(neighbor.getPoint());
                                    neighbor.watered = true;
                                }
                            }
                        }

                        path.Add(actionable);
                    }
                }

                foreach (Tile tile in group.getList())
                {
                    if (!tile.visited)
                    {
                        stack.Add(tile);
                        keepGoing = true;
                        break;
                    }
                }
            } while (keepGoing);

            return(path);
        }
        public void refillWater()
        {
            if (!this.active)
            {
                return;
            }

            Tile playerLocation = this.map.map[Game1.player.getTileY()][Game1.player.getTileX()];

            this.refillStation = this.map.getClosestRefill(playerLocation, this.console);

            if (!this.active)
            {
                return;
            }

            if (this.refillStation != null)
            {
                Game1.player.controller = new PathFindController(Game1.player, Game1.currentLocation, refillStation.getStand(), 2, this.startRefilling);
            }
            else
            {
                this.noWater();
            }
        }