Beispiel #1
0
		/// <summary>
		///   Adds the given <paramref name="capability" /> to the role's capabilities to be applied.
		/// </summary>
		/// <exception cref="InvalidOperationException">
		///   Thrown if the given capability is not the
		///   next required capability.
		/// </exception>
		public void AddCapabilityToApply(Capability capability)
		{
			if (_capabilitiesToApplyStart + _capabilitiesToApplyCount >= Recipe.RequiredCapabilities.Length)
				throw new InvalidOperationException("All required capabilities already applied.");
			if (!capability.Equals(Recipe.RequiredCapabilities[_capabilitiesToApplyStart + _capabilitiesToApplyCount]))
				throw new InvalidOperationException("Cannot apply capability that is not required.");

			_capabilitiesToApplyCount++;
		}
Beispiel #2
0
		/// <summary>
		///   Creates a new recipe with the specified sequence of ingredients.
		/// </summary>
		/// <param name="ingredients">The sequence of ingredients to add to the containers.</param>
		/// <param name="amount">The number of containers to produce for this recipe.</param>
		public Recipe(Ingredient[] ingredients, uint amount)
		{
			_activeContainers = new List<PillContainer>((int)amount);
			Amount = amount;

			RequiredCapabilities = new Capability[] { new ProduceCapability() }
				.Concat(ingredients)
				.Concat(new[] { new ConsumeCapability() })
				.ToArray();
		}
Beispiel #3
0
		public static bool IsSatisfiable(Capability[] required, Capability[] available)
		{
			if (required.OfType<ProduceCapability>().Any() && !available.OfType<ProduceCapability>().Any())
				return false;
			if (required.OfType<ConsumeCapability>().Any() && !available.OfType<ConsumeCapability>().Any())
				return false;

			var requiredAmounts = GroupIngredientAmounts(required);
			var availableAmounts = GroupIngredientAmounts(available);

			foreach (var pair in requiredAmounts)
			{
				int value;
				if (!availableAmounts.TryGetValue(pair.Key, out value) || value < pair.Value)
					return false;
			}

			return true;
		}
Beispiel #4
0
		/// <summary>
		///   Appends the given <see cref="Capability" /> to the <see cref="State" />.
		/// </summary>
		/// <param name="capability">The capability to append.</param>
		/// <exception cref="InvalidOperationException">
		///   Thrown if the capability does not match
		///   the <see cref="Recipe" />'s next required capability.
		/// </exception>
		public void AppendToState(Capability capability)
		{
			if (_statePrefixLength >= Recipe.RequiredCapabilities.Length)
				throw new InvalidOperationException("Condition already has maximum state.");
			if (Recipe.RequiredCapabilities[_statePrefixLength] != capability)
				throw new InvalidOperationException("Capability must be next required capability.");

			_statePrefixLength++;
		}
Beispiel #5
0
		private static Dictionary<IngredientType, int> GroupIngredientAmounts(Capability[] capabilities)
		{
			return capabilities.OfType<Ingredient>()
							   .GroupBy(ingredient => ingredient.Type, ingredient => (int)ingredient.Amount)
							   .ToDictionary(group => group.Key, group => group.Sum());
		}