Ejemplo n.º 1
0
        public IEnumerable <BottlesState> GetStates(BottlesState currentState)
        {
            var options = new List <BottlesState>();

            // Bottle 1 --> Bottle 2
            if (currentState.Bottle1 > 0 && currentState.Bottle2 < _bottle2Max)
            {
                int bottle2  = currentState.Bottle2 + currentState.Bottle1;
                var overflow = bottle2 - _bottle2Max;

                // Om vi inte får plats, låt det överflödiga ligga kvar
                int bottle1 = overflow > 0 ? overflow : 0;

                // Om vi inte får plats, fyll flaskan.
                bottle2 = bottle2 > _bottle2Max ? _bottle2Max : bottle2;
                options.Add(new BottlesState(bottle1, bottle2));
            }

            // Bottle 2 --> Bottle 1
            if (currentState.Bottle2 > 0 && currentState.Bottle1 < _bottle1Max)
            {
                int bottle1  = currentState.Bottle1 + currentState.Bottle2;
                var overflow = bottle1 - _bottle1Max;

                // Om vi inte får plats, låt det överflödiga ligga kvar
                int bottle2 = overflow > 0 ? System.Math.Abs(overflow) : 0;

                // Om vi inte får plats, fyll flaskan.
                bottle1 = bottle1 > _bottle1Max ? _bottle1Max : bottle1;
                options.Add(new BottlesState(bottle1, bottle2));
            }

            // Bottle 1 --> Empty
            if (currentState.Bottle1 > 0)
            {
                options.Add(new BottlesState(0, currentState.Bottle2));
            }

            // Bottle 2 --> Empty
            if (currentState.Bottle2 > 0)
            {
                options.Add(new BottlesState(currentState.Bottle1, 0));
            }

            // Bottle 1 --> Fill
            if (currentState.Bottle1 < _bottle1Max)
            {
                options.Add(new BottlesState(_bottle1Max, currentState.Bottle2));
            }

            // Bottle 2 --> Fill
            if (currentState.Bottle2 < _bottle2Max)
            {
                options.Add(new BottlesState(currentState.Bottle2, _bottle2Max));
            }

            return(options);
        }
Ejemplo n.º 2
0
        public static IEnumerable <BottlesState> FindPath(BottleGraph map, BottlesState start, Func <BottlesState, bool> isDone)
        {
            var foundPath = new List <BottlesState>();

            int  nodesChecked = 0;
            bool found        = false;

            var toVisit = new Queue <BottlesState> ();

            toVisit.Enqueue(start);

            var cameFrom = new Dictionary <Tuple <int, int>, BottlesState> ();

            cameFrom.Add(Tuple.Create(start.Bottle1, start.Bottle2), null);

            var costs = new Dictionary <Tuple <int, int>, int> ();

            costs.Add(Tuple.Create(start.Bottle1, start.Bottle2), 0);

            var foundGoal = toVisit.First();

            while (toVisit.Count > 0)
            {
                var current = toVisit.Dequeue();

                if (isDone(current))
                {
                    found     = true;
                    foundGoal = current;
                    break;
                }

                var neighbours = map.GetStates(current).ToArray();

                foreach (var next in neighbours)
                {
                    int newCost = costs[Tuple.Create(current.Bottle1, current.Bottle2)] + 1;

                    if (!costs.ContainsKey(Tuple.Create(next.Bottle1, next.Bottle2)) || newCost < costs [Tuple.Create(next.Bottle1, next.Bottle2)])
                    {
                        costs [Tuple.Create(next.Bottle1, next.Bottle2)] = newCost;
                        toVisit.Enqueue(next);
                        cameFrom [Tuple.Create(next.Bottle1, next.Bottle2)] = current;
                    }
                }
                nodesChecked++;
            }
            if (!found)
            {
                return(foundPath);
            }

            var reverseCurrent = foundGoal;
            var path           = new Queue <BottlesState> (new[] { reverseCurrent });

            while (reverseCurrent != start)
            {
                reverseCurrent = cameFrom [Tuple.Create(reverseCurrent.Bottle1, reverseCurrent.Bottle2)];
                path.Enqueue(reverseCurrent);
            }

            foundPath = path.Reverse().ToList();

            return(foundPath);
        }