Пример #1
0
    /// <summary>
    /// Finds the shortest path from precalculated starting location to the given target
    /// Adjacent cells and teleports (per special game rules) count as 1 distance point.
    /// </summary>
    /// <param name="target">The cell to find the path to</param>
    /// <returns>1. True if cell is accessible, False if blocked 2. The shortest path</returns>
    public (bool accessible, LogicalPath path) LookupShortestPath(LogicalCell target)
    {
        LogicalPath path       = new LogicalPath();
        var         p          = new List <LogicalCell>();
        bool        accessible = false;

        if (distancesByCell[target] != int.MaxValue || target == startingLocation)
        {
            LogicalCell currentCell = target;
            while (currentCell != null)
            {
                accessible = true;
                path.PrependPath(currentCell.Loc);
                currentCell = paths[currentCell];
            }
        }

        return(accessible : accessible, path : path);
    }
Пример #2
0
    /// <summary>
    /// Ticks the AI's brain. It will move one square each tick currently.
    /// </summary>
    /// <param name="graph">The scene graph</param>
    /// <param name="state">The state of the level</param>
    public void Tick(LogicalCellGraph graph, ILevelState state)
    {
        // So on a bigger game I probably wouldn't do this,
        // But it seems Djikstra's is performant enough to
        // Recompute each tick!! (keep in mind, the AI's tick
        // is only approximately once every second). If this
        // weren't the case, I would probably go with A*.
        RebuildGraph(graph);

        if (enemyPawn == null || enemyWeightGraph == null)
        {
            return;
        }
        var goal = findAIGoal(graph, state);

        if (goal == null)
        {
            return;
        }

        var(accessible, path) = enemyWeightGraph.LookupShortestPath(goal);
        if (!accessible)
        {
            return;
        }

        if (!path.Path.Any())
        {
            return;
        }

        var nextCell = path.Path.Skip(1).Take(1).FirstOrDefault();

        if (nextCell != null)
        {
            var truncatedPath = new LogicalPath();
            truncatedPath.PrependPath(nextCell);
            enemyPawn.PushMotionPath(truncatedPath);
        }
    }