Пример #1
0
        public static int Run(bool isRanByUser, string[] args)
        {
            int target = -1;

            target = !isRanByUser?int.Parse(args[0]) : GetParametersFromConsole();

            if (target > 8 || target < 0)
            {
                throw new ArgumentException("We're not ready to handle values over 8 or below 0 yet");
            }

            List <StateOfBottles> listOfStates = new List <StateOfBottles>();
            //In order to perform a breadth-first search we must populate this list sorted by actions taken.

            StateOfBottles state = new StateOfBottles();

            listOfStates.Add(state);

            int variant = 0;

            while (true)
            {
                if (state.EvaluateIfTargetIsReached(target))
                {
                    break;
                }

                state = listOfStates.First();
                listOfStates.Remove(state);

                //Only used for manual debugging.
                //Console.WriteLine($"Itteration: {variant}, Five: {state.FiveLiterBottle.CurrentVolume}, Three: {state.ThreeLiterBottle.CurrentVolume}, Target: {target}, ActionTaken: {state.ActionTaken}");

                listOfStates = StateOfBottles.AddAnotherRound(listOfStates, state);
                variant     += 1;
            }

            Console.WriteLine($"To find {target} requires {state.ActionsTaken} steps, we evaluated {variant} different states in order to find this path.");
            Console.WriteLine("Press Enter to display the actions taken");
            if (isRanByUser)
            {
                Console.ReadLine();
            }

            Console.WriteLine($"Actions Taken to reach the route:");
            var statesToAccomplishTask = CalculateStepsTaken(new List <ValidActions>(), state);

            foreach (var x in statesToAccomplishTask)
            {
                Console.WriteLine((object)x);
            }

            if (isRanByUser)
            {
                Console.ReadLine();
            }

            return(state.ActionsTaken);
        }
Пример #2
0
        /// <summary>
        /// Be careful using this constructor, it's intended to be used internally.
        /// </summary>
        /// <param name="parentState"></param>
        /// <param name="actionToTake"></param>
        private StateOfBottles(StateOfBottles parentState, ValidActions actionToTake)
        {
            //TODO: Verify if simply FiveLiterBottle = ParentState.FiveLiterBottle is a copy or a reference
            //For now we play safe and copy manually
            FiveLiterBottle  = new Bottle(parentState.FiveLiterBottle);
            ThreeLiterBottle = new Bottle(parentState.ThreeLiterBottle);

            this.ParentState = parentState;

            ActionTaken = actionToTake;

            ActionsTaken = parentState.ActionsTaken + 1;
            switch (actionToTake)
            {
            case ValidActions.Fill5:
                FiveLiterBottle.Fill();
                break;

            case ValidActions.Fill3:
                ThreeLiterBottle.Fill();
                break;

            case ValidActions.Empty5:
                FiveLiterBottle.Empty();
                break;

            case ValidActions.Empty3:
                ThreeLiterBottle.Empty();
                break;

            case ValidActions.Pour5To3:
                ThreeLiterBottle.AddToVolumeFromThisBottle(FiveLiterBottle);
                break;

            case ValidActions.Pour3To5:
                FiveLiterBottle.AddToVolumeFromThisBottle(ThreeLiterBottle);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(actionToTake), actionToTake, null);
            }
        }
Пример #3
0
        /// <summary>
        ///     Adds all actions used in ValidActions to the end of the provided list.
        /// </summary>
        /// <param name="list"></param>
        /// <param name="state"></param>
        /// <returns>List, with all actions from ValidActions applied to the end, using the supplied state as first action.</returns>
        public static List <StateOfBottles> AddAnotherRound(List <StateOfBottles> list, StateOfBottles state)
        {
            var variant = Enum.GetValues(typeof(ValidActions)).Cast <ValidActions>();

            foreach (var action in variant)
            {
                //Console.WriteLine($"Performing action: {action}");
                list.Add(state.Perform(action));
            }
            return(list);
        }
Пример #4
0
        private static List <ValidActions> CalculateStepsTaken(List <ValidActions> list, StateOfBottles state)
        {
            if (state == null)
            {
                list.Reverse(); //Reverse the list in order to output the actions in correct order (the state without a parent is the first action we take).
                return(list);
            }
            if (state.ActionTaken.HasValue)
            {
                list.Add(state.ActionTaken.Value);
            }

            return(CalculateStepsTaken(list, state.ParentState));
        }