public void AddSolution(Solution otherSolution) { for (var i = 0; i < otherSolution._contents.Count; i++) { var otherReagent = otherSolution._contents[i]; var found = false; for (var j = 0; j < _contents.Count; j++) { var reagent = _contents[j]; if (reagent.ReagentId == otherReagent.ReagentId) { found = true; _contents[j] = new ReagentQuantity(reagent.ReagentId, reagent.Quantity + otherReagent.Quantity); break; } } if (!found) { _contents.Add(new ReagentQuantity(otherReagent.ReagentId, otherReagent.Quantity)); } } TotalVolume += otherSolution.TotalVolume; }
/// <summary> /// Remove the specified quantity from this solution. /// </summary> /// <param name="quantity">The quantity of this solution to remove</param> public void RemoveSolution(ReagentUnit quantity) { if (quantity <= 0) { return; } var ratio = (TotalVolume - quantity).Double() / TotalVolume.Double(); if (ratio <= 0) { RemoveAllSolution(); return; } for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; var oldQuantity = reagent.Quantity; // quantity taken is always a little greedy, so fractional quantities get rounded up to the nearest // whole unit. This should prevent little bits of chemical remaining because of float rounding errors. var newQuantity = oldQuantity * ratio; _contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity); } TotalVolume = TotalVolume * ratio; }
public void RemoveReagent(string reagentId, ReagentUnit quantity) { if (quantity <= 0) { return; } for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; if (reagent.ReagentId != reagentId) { continue; } var curQuantity = reagent.Quantity; var newQuantity = curQuantity - quantity; if (newQuantity <= 0) { _contents.RemoveSwap(i); TotalVolume -= curQuantity; } else { _contents[i] = new ReagentQuantity(reagentId, newQuantity); TotalVolume -= quantity; } return; } }
/// <summary> /// Remove the specified quantity from this solution. /// </summary> /// <param name="quantity">The quantity of this solution to remove</param> /// <param name="removedSolution">Out arg. The removed solution. Useful for adding removed solution /// into other solutions. For example, when pouring from one container to another.</param> public void RemoveSolution(int quantity, out Solution removedSolution) { removedSolution = new Solution(); if (quantity <= 0) { return; } var ratio = (float)(TotalVolume - quantity) / TotalVolume; if (ratio <= 0) { removedSolution = this.Clone(); //Todo: Check if clone necessary RemoveAllSolution(); return; } for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; var oldQuantity = reagent.Quantity; // quantity taken is always a little greedy, so fractional quantities get rounded up to the nearest // whole unit. This should prevent little bits of chemical remaining because of float rounding errors. var newQuantity = (int)Math.Floor(oldQuantity * ratio); _contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity); removedSolution.AddReagent(reagent.ReagentId, oldQuantity - newQuantity); } TotalVolume = (int)Math.Floor(TotalVolume * ratio); }
public Solution SplitSolution(ReagentUnit quantity) { if (quantity <= 0) { return(new Solution()); } Solution newSolution; if (quantity >= TotalVolume) { newSolution = Clone(); RemoveAllSolution(); return(newSolution); } newSolution = new Solution(); var newTotalVolume = ReagentUnit.New(0); var remainingVolume = TotalVolume; for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; var ratio = (remainingVolume - quantity).Double() / remainingVolume.Double(); remainingVolume -= reagent.Quantity; var newQuantity = reagent.Quantity * ratio; var splitQuantity = reagent.Quantity - newQuantity; _contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity); newSolution._contents.Add(new ReagentQuantity(reagent.ReagentId, splitQuantity)); newTotalVolume += splitQuantity; quantity -= splitQuantity; } newSolution.TotalVolume = newTotalVolume; TotalVolume -= newTotalVolume; return(newSolution); }
/// <summary> /// Adds a given quantity of a reagent directly into the solution. /// </summary> /// <param name="reagentId">The prototype ID of the reagent to add.</param> /// <param name="quantity">The quantity in milli-units.</param> public void AddReagent(string reagentId, ReagentUnit quantity) { if (quantity <= 0) { return; } for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; if (reagent.ReagentId != reagentId) { continue; } _contents[i] = new ReagentQuantity(reagentId, reagent.Quantity + quantity); TotalVolume += quantity; return; } _contents.Add(new ReagentQuantity(reagentId, quantity)); TotalVolume += quantity; }
public Solution SplitSolution(int quantity) { if (quantity <= 0) { return(new Solution()); } Solution newSolution; if (quantity >= TotalVolume) { newSolution = Clone(); RemoveAllSolution(); return(newSolution); } newSolution = new Solution(); var newTotalVolume = 0; var ratio = (float)(TotalVolume - quantity) / TotalVolume; for (var i = 0; i < _contents.Count; i++) { var reagent = _contents[i]; var newQuantity = (int)Math.Floor(reagent.Quantity * ratio); var splitQuantity = reagent.Quantity - newQuantity; _contents[i] = new ReagentQuantity(reagent.ReagentId, newQuantity); newSolution._contents.Add(new ReagentQuantity(reagent.ReagentId, splitQuantity)); newTotalVolume += splitQuantity; } TotalVolume = (int)Math.Floor(TotalVolume * ratio); newSolution.TotalVolume = newTotalVolume; return(newSolution); }