コード例 #1
0
        private void MoveTowardsGoal()
        {
            if (this.X == this.goal.X && this.Y == this.goal.Y)
            {
                this.goal    = map.FindEmptyPosition();
                this.goalMap = this.CreateGoalMap();
            }

            var path = goalMap.FindPath(this.X, this.Y);

            if (path != null)
            {
                var now      = path.Steps.First();
                var nextStep = path.Steps.Skip(1).FirstOrDefault();
                if (nextStep != null && map.IsWalkable(nextStep.X, nextStep.Y))
                {
                    this.Move(nextStep.X, nextStep.Y);
                }
                else
                {
                    // Pick a new goal next time
                    this.goal = new Point(this.X, this.Y);
                }
            }
            else
            {
                // No path to goal... Pick a new goal next time
                this.goal = new Point(this.X, this.Y);
            }
        }
コード例 #2
0
        public Monster(ColourTuple colour, int agility, string visionType, int visionSize, CaveFloorMap map) : base('m', colour, true)
        {
            this.Agility    = agility;
            this.VisionType = visionType;
            this.VisionSize = visionSize;

            Monster.map  = map;
            this.goal    = map.FindEmptyPosition();
            this.goalMap = this.CreateGoalMap();
        }
コード例 #3
0
        // We pick a goal, and move towards it, no matter what. Doing this every frame
        // is really expensive and massively slows down the game. We can't have that.
        // Instead, change your goal only when you're stuck -- path is blocked.
        // Returns true if we attacked the player
        public bool MoveWithAi(Player player)
        {
            switch (this.currentState)
            {
            case MonsterState.Wandering:
                this.MoveTowardsGoal();
                return(false);

            case MonsterState.Hunting:
                if (DistanceBetween(player.X, player.Y, this.X, this.Y) == 1)
                {
                    player.Hurt();
                    return(true);
                }
                else
                {
                    // Find an empty space around the player that we can pathfind to. If one exists.
                    var target = map.GetIMap().GetCellsInRadius(player.X, player.Y, 1).FirstOrDefault(c =>
                    {
                        // Make sure it's walkable, and it's not the player's spot (kills pathfinding)
                        // Also make sure it's closer to the player than where we are now
                        if (c.IsWalkable && (c.X != player.X || c.Y != player.Y) && DistanceBetween(player.X, player.Y, c.X, c.Y) <= DistanceBetween(player.X, player.Y, this.X, this.Y))
                        {
                            var map = CreateGoalMap();
                            map.AddGoal(c.X, c.Y, 100);
                            return(map.FindPaths(this.X, this.Y).Any());
                        }
                        else
                        {
                            return(false);
                        }
                    });

                    if (target != null)
                    {
                        this.goal    = new Point(target.X, target.Y);
                        this.goalMap = this.CreateGoalMap();
                    }
                    else
                    {
                        if (this.DistanceBetween(this.X, this.Y, player.X, player.Y) > this.VisionSize)
                        {
                            this.currentState = MonsterState.Wandering;
                            this.goal         = new Point(this.X, this.Y); // reset next round
                        }
                    }
                    this.MoveTowardsGoal();
                }
                return(false);

            default:
                throw new InvalidOperationException($"Not sure how to deal with state {this.currentState}");
            }
        }