Changeset - a93007642265
[Not reviewed]
default
0 1 0
Jason Maltzen - 3 years ago 2021-09-09 23:59:27
jason@hiddenachievement.com
Add a utility on a paint recipe to find the list of missing reaction pairs for that recipe
1 file changed with 38 insertions and 2 deletions:
0 comments (0 inline, 0 general)
Models/PaintRecipe.cs
Show inline comments
...
 
@@ -115,130 +115,130 @@ namespace DesertPaintCodex.Models
 
                if (!_recalculate) return _baseColor;
 
                ComputeBaseColor();
 
                ComputeReactedColor();
 
                _recalculate = false;
 
                return _baseColor;
 
            }
 
        }
 

	
 
        public void AddReagent(string reagentName, uint quantity = 1)
 
        {
 
            if (quantity == 0)
 
            {
 
                return;
 
            }
 
            Reagent reagent = ReagentService.GetReagent(reagentName);
 

	
 
            ReagentQuantity? reagentQty = _recipe.Find(x => x.Name.Equals(reagentName));
 
            if (reagentQty != null)
 
            {
 
                if (!reagent.IsCatalyst)
 
                {
 
                    reagentQty.Quantity += quantity;
 
                }
 
            }
 
            else
 
            {
 
                ReagentQuantity newReagentQty = new(reagentName, reagent.IsCatalyst ? 1 : quantity);
 
                _recipe.Add(newReagentQty);
 
            }
 
            _reagents.Add(reagentName);
 
            _recalculate = true;
 
        }
 

	
 
        public void Clear()
 
        {
 
            _reagents.Clear();
 
            _recipe.Clear();
 
            _recalculate = true;
 
        }
 

	
 
        private static byte CalculateColor(int baseSum, uint pigmentCount, int reactSum)
 
        {
 
            // Changed to Math.Floor from Math.Round, since Round appears to be incorrect.
 
            return (byte)Math.Max(Math.Min(Math.Floor((((float)baseSum / pigmentCount) + reactSum)), 255), 0);
 
        }
 

	
 
        // Compute the color including reactions based on the player's profile
 
        private void ComputeReactedColor()
 
        {
 
            RGB baseRGB;
 
            baseRGB.R = 0;
 
            baseRGB.G = 0;
 
            baseRGB.B = 0;
 
            RGB reactionColor;
 
            reactionColor.R = 0;
 
            reactionColor.G = 0;
 
            reactionColor.B = 0;
 

	
 
            uint pigmentCount = 0;
 
            
 
            ReactionSet? reactions = ProfileManager.CurrentProfile?.Reactions;
 
            Debug.Assert(reactions != null);
 
            
 
            // track visited reagents so the reaction is only applied once
 
            HashSet<string> reagentSet   = new();
 
            List<Reagent>                  prevReagents = new();
 
            HashSet<string> reagentSet = new();
 
            List<Reagent> prevReagents = new();
 

	
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName))
 
                {
 
                    continue;
 
                }
 

	
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 

	
 
                if (!reagent.IsCatalyst)
 
                {
 
                    Debug.Assert(reagent.Color != null);
 
                    baseRGB.R += (reagent.Color.Red   * (int)ingredient.Quantity); 
 
                    baseRGB.G += (reagent.Color.Green * (int)ingredient.Quantity);
 
                    baseRGB.B += (reagent.Color.Blue  * (int)ingredient.Quantity);
 
                    pigmentCount += ingredient.Quantity;
 
                }
 

	
 
                if (!reagentSet.Contains(reagentName) && reagentSet.Count <= 4)
 
                {
 
                    reagentSet.Add(reagentName);
 
                    // Run reactions.
 
                    foreach (Reagent otherReagent in prevReagents)
 
                    {
 
                        Reaction? reaction = reactions.Find(otherReagent, reagent);
 
                        if (reaction != null)
 
                        {
 
                            reactionColor.R += reaction.Red;
 
                            reactionColor.G += reaction.Green;
 
                            reactionColor.B += reaction.Blue;
 
                        }
 
                    }
 
                    prevReagents.Add(reagent);
 
                }
 
            }
 
            _reactedColor.Red = CalculateColor(baseRGB.R, pigmentCount, reactionColor.R);
 
            _reactedColor.Green = CalculateColor(baseRGB.G, pigmentCount, reactionColor.G);
 
            _reactedColor.Blue = CalculateColor(baseRGB.B, pigmentCount, reactionColor.B);
 
        }
 

	
 
        // Compute the base color without any reactions
 
        private void ComputeBaseColor()
 
        {
 
            RGB baseRGB;
 
            baseRGB.R = 0;
 
            baseRGB.G = 0;
 
            baseRGB.B = 0;
 
            uint pigmentCount = 0;
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName))
 
                {
 
                    continue;
 
                }
 

	
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 
                
 
                if (reagent.IsCatalyst) continue;
 
                
 
                Debug.Assert(reagent.Color != null);
 
                baseRGB.R    += (reagent.Color.Red   * (int)ingredient.Quantity);
...
 
@@ -299,66 +299,102 @@ namespace DesertPaintCodex.Models
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName))
 
                {
 
                    continue;
 
                }
 

	
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 
                cost += (reagent.Cost * ingredient.Quantity);
 
            }
 
            uint batchCount = (uint)Math.Ceiling((double)quantity / cost);  // number of batches require to make quantity
 
            return batchCount * cost;
 
        }
 

	
 
        public bool IsValidForConcentration(uint concentration)
 
        {
 
            uint weight = 0;
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName))
 
                {
 
                    continue;
 
                }
 

	
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 
                if (!reagent.IsCatalyst)
 
                {
 
                    weight += ingredient.Quantity;
 
                }
 
            }
 
            return (weight >= concentration);
 
        }
 
        public bool HasMissingReactions()
 
        {
 
            ReactionSet? reactions = ProfileManager.CurrentProfile?.Reactions;
 
            Debug.Assert(reactions != null);
 

	
 
            HashSet<string> reagentSet = new();
 
            List<Reagent> prevReagents = new();
 
            
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                if (reagentSet.Count > 4) return false;
 
                
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName)) continue;
 
                if (reagentSet.Contains(reagentName)) continue;
 
                reagentSet.Add(reagentName);
 
                
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 

	
 
                // Find reactions.
 
                foreach (Reagent otherReagent in prevReagents)
 
                {
 
                    Reaction? reaction = reactions.Find(otherReagent, reagent);
 
                    if (reaction == null) return true;
 
                }
 
                prevReagents.Add(reagent);
 
            }
 

	
 
            return false;
 
        }
 

	
 
        public List<(string, string)> MissingReactionPairs()
 
        {
 
            ReactionSet? reactions = ProfileManager.CurrentProfile?.Reactions;
 
            Debug.Assert(reactions != null);
 

	
 
            HashSet<string> reagentSet = new();
 
            List<Reagent> prevReagents = new();
 

	
 
            List<(string, string)> missingReactionPairs = new List<(string, string)>(16);
 

	
 
            foreach (ReagentQuantity ingredient in _recipe)
 
            {
 
                if (reagentSet.Count > 4) return missingReactionPairs; // no more reactions
 

	
 
                string reagentName = ingredient.Name;
 
                if (string.IsNullOrEmpty(reagentName)) continue;
 
                if (reagentSet.Contains(reagentName)) continue;
 
                reagentSet.Add(reagentName);
 

	
 
                Reagent reagent = ReagentService.GetReagent(reagentName);
 

	
 
                // Find reactions.
 
                foreach (Reagent prevReagent in prevReagents)
 
                {
 
                    Reaction? reaction = reactions.Find(prevReagent, reagent);
 
                    if (reaction == null)
 
                    {
 
                        missingReactionPairs.Add((prevReagent.Name, reagentName));
 
                    }
 
                }
 
                prevReagents.Add(reagent);
 
            }
 

	
 
            return missingReactionPairs;
 
        }
 
    }
 
}
0 comments (0 inline, 0 general)