예제 #1
0
        public AStarState Create(Board board, AStarState previousState)
        {
            int currentScore  = wrongPlacesHeuristicScoreComputer.Compute(board);
            int previousScore = previousState?.TotalHeuristicScore ?? 0;
            int totalScore    = previousScore + currentScore;

            return(new AStarState(board, previousState, currentScore, totalScore));
        }
 public AStarState(AStarState <Node> copy)
 {
     open     = new HashSet <Node>(copy.open);
     closed   = new HashSet <Node>(copy.closed);
     gs       = new Dictionary <Node, float>(copy.gs);
     fs       = new Dictionary <Node, float>(copy.fs);
     previous = new Dictionary <Node, Node>(copy.previous);
     current  = copy.current;
     finished = copy.finished;
 }
예제 #3
0
        public void AStarPathSync()
        {
            AStarState <Point> state = new AStarState <Point>();

            state.Start = new Point(4, 2);
            state.EndPoints.Add(new Point(5, 15));

            var astar = new AStar <Point>(new FakeMap());

            astar.FindPathSync(state);

            // two steps to the left to get to (2, 2)
            // 13 steps down to get to (2, 15)
            // 3 steps to the right to get to (5, 15)
            // that's 18 steps, plus the start point makes 19.
            state.Path.Count.Should().Be(19);
        }
예제 #4
0
            public IEnumerable <Point> GetAvailableSteps(AStarState <Point> task, Point location)
            {
                for (int j = -1; j <= 1; j++)
                {
                    for (int i = -1; i <= 1; i++)
                    {
                        if (i == j || i == -j)
                        {
                            continue;
                        }

                        Point trial = new Point(location.X + i, location.Y + j);

                        if (IsAvailable(trial))
                        {
                            yield return(trial);
                        }
                    }
                }
            }
    static void DebugGoap(AStarState <Node> state)
    {
        var candidate = state.current;

        U.Log("OPEN SET " + state.open.Aggregate("", (a, x) => a + x.ToString() + "\n\n"));
        U.Log("CLOSED SET " + state.closed.Aggregate("", (a, x) => a + x.ToString() + "\n\n"));
        U.Log("CHOSEN CANDIDATE COST " + state.fs[candidate] + ":" + candidate.ToString());
        if (state is AStarState <GOAPState> )
        {
            U.Log("SEQUENCE FOR CANDIDATE" +
                  U.Generate(state.current, n => state.previous[n])
                  .TakeWhile(x => x != null)
                  .Reverse()
                  .Select(x => x as GOAPState)
                  .Where(x => x != null && x.generatingAction != null)
                  .Aggregate("", (a, x) => a + "-->" + x.generatingAction.name)
                  );

            var prevs = state.previous as Dictionary <GOAPState, GOAPState>;
            U.Log("Other candidate chains:\n"
                  + prevs
                  .Select(kv => kv.Key)
                  .Where(y => !prevs.ContainsValue(y))
                  .Aggregate("", (a, y) => a +
                             U.Generate(y, n => prevs[n])
                             .TakeWhile(x => x != null)
                             .Reverse()
                             .Select(x => x as GOAPState)
                             .Where(x => x != null && x.generatingAction != null)
                             .Aggregate("", (a2, x) => a2 + "-->" + x.generatingAction.name + "(" + x.step + ")")
                             + " (COST: g" + (state.gs)[y as Node] + "   f" + state.fs[y as Node] + ")"
                             + "\n"
                             )
                  );
        }
    }
    //expand can return null as "no neighbours"
    public static IEnumerable <Node> Run
    (
        Node from,
        Node to,
        Func <Node, Node, float> h,              //Current, Goal -> Heuristic cost
        Func <Node, bool> satisfies,             //Current -> Satisfies
        Func <Node, IEnumerable <Arc> > expand   //Current -> (Endpoint, Cost)[]
    )
    {
        var initialState = new AStarState <Node>();

        initialState.open.Add(from);
        initialState.gs[from]       = 0;
        initialState.fs[from]       = h(from, to);
        initialState.previous[from] = null;
        initialState.current        = from;

        var state = initialState;

        while (state.open.Count > 0 && !state.finished)
        {
            //Debugger gets buggy af with this, can't watch variable:
            state = state.Clone();

            var candidate = state.open.OrderBy(x => state.fs[x]).First();
            state.current = candidate;

            //DebugGoap(state);

            if (satisfies(candidate))
            {
                U.Log("SATISFIED");
                state.finished = true;
            }
            else
            {
                state.open.Remove(candidate);
                state.closed.Add(candidate);
                var neighbours = expand(candidate);
                if (neighbours == null || !neighbours.Any())
                {
                    continue;
                }

                var gCandidate = state.gs[candidate];

                foreach (var ne in neighbours)
                {
                    if (ne.endpoint.In(state.closed))
                    {
                        continue;
                    }

                    var gNeighbour = gCandidate + ne.cost;
                    state.open.Add(ne.endpoint);

                    if (gNeighbour > state.gs.DefaultGet(ne.endpoint, () => gNeighbour))
                    {
                        continue;
                    }

                    state.previous[ne.endpoint] = candidate;
                    state.gs[ne.endpoint]       = gNeighbour;
                    state.fs[ne.endpoint]       = gNeighbour + h(ne.endpoint, to);
                }
            }
        }

        if (!state.finished)
        {
            return(null);
        }

        //Climb reversed tree.
        var seq =
            U.Generate(state.current, n => state.previous[n])
            .TakeWhile(n => n != null)
            .Reverse();

        return(seq);
    }
예제 #7
0
 public void ReportProgress(AStarState <Point> task)
 {
 }
예제 #8
0
    public static IEnumerator Run
    (
        Node start,
        Func <Node, float> heuristic,
        Func <Node, bool> satisfies,
        Func <Node, IEnumerable <NodeCost> > expand,
        Action <IEnumerable <Node> > callback
    )
    {
        var initialState = new AStarState <Node>();

        initialState.open.Add(start);
        initialState.gs[start]       = 0;
        initialState.fs[start]       = heuristic(start);
        initialState.previous[start] = null;
        initialState.current         = start;

        var state = initialState;

        while (state.open.Count > 0 && !state.finished)
        {
            state = state.Clone();

            var candidate = state.open.OrderBy(x => state.fs[x]).First();
            state.current = candidate;

            if (satisfies(candidate))
            {
                state.finished = true;
            }
            else
            {
                state.open.Remove(candidate);
                state.closed.Add(candidate);
                var neighbours = expand(candidate);
                if (neighbours == null || !neighbours.Any())
                {
                    continue;
                }

                var gCandidate = state.gs[candidate];

                foreach (var neighbour in neighbours)
                {
                    if (neighbour.endpoint.In(state.closed))
                    {
                        continue;
                    }

                    var gNeighbour = gCandidate + neighbour.cost;
                    state.open.Add(neighbour.endpoint);

                    if (gNeighbour > state.gs.DefaultGet(neighbour.endpoint, () => gNeighbour))
                    {
                        continue;
                    }

                    state.previous[neighbour.endpoint] = candidate;
                    state.gs[neighbour.endpoint]       = gNeighbour;
                    state.fs[neighbour.endpoint]       = gNeighbour + heuristic(neighbour.endpoint);
                }
            }

            yield return(null);
        }

        if (!state.finished)
        {
            callback(null);
        }
        else
        {
            var seq =
                AStarUtility.Generate(state.current, n => state.previous[n])
                .TakeWhile(n => n != null)
                .Reverse();

            callback(seq);
        }
    }