• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

samsmithnz / SatisfactoryTree / 12846773348

18 Jan 2025 07:19PM UTC coverage: 36.569% (+1.6%) from 34.92%
12846773348

Pull #203

github

web-flow
Merge 01984e572 into 0d6c7988b
Pull Request #203: Adding first logic

431 of 585 branches covered (73.68%)

Branch coverage included in aggregate %.

76 of 77 new or added lines in 1 file covered. (98.7%)

1076 of 3536 relevant lines covered (30.43%)

2622.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.25
/src/SatisfactoryTree.Console/Calculator.cs
1
using SatisfactoryTree.Console.OldModels;
2

3
namespace SatisfactoryTree.Console
4
{
5
    public class Item
6
    {
7
        public string Name { get; set; }
61✔
8
        public double Quantity { get; set; }
30✔
9
        public List<Item> Ingredients { get; set; }
13✔
10
        public string Building { get; set; }
18✔
11
        public double BuildingQuantity { get; set; }
18✔
12

13
        public int Counter { get; set; }
35✔
14
    }
15

16
    public class Calculator
17
    {
18

19
        //Using a target item, calculate the total number of items needed to produce the target item
20
        public Calculator() { }
9✔
21
        public List<Item> CalculateProduction(FinalData finalData, string partName, double quantity)
22
        {
3✔
23
            List<Item> results = new();
3✔
24
            int counter = 1;
3✔
25

26
            //Add the goal item
27
            NewRecipe recipe = FindRecipe(finalData, partName);
3✔
28
            double buildingRatio = quantity / recipe.products[0].perMin;
3✔
29
            results.Add(new() { Name = partName, Quantity = quantity, Ingredients = new(), Building = recipe.building.name, BuildingQuantity = buildingRatio, Counter = counter });
3✔
30
            //Get the dependencies/ingredients for the goal item
31
            results.AddRange(GetIngredients(finalData, partName, quantity, counter));
3✔
32

33
            //transfer the results list into a dictonary to combine results
34
            Dictionary<string, Item> resultsDictionary = new();
3✔
35
            foreach (Item item in results)
35✔
36
            {
13✔
37
                //if the item doesn't exist in the dictionary, add it
38
                if (!resultsDictionary.ContainsKey(item.Name))
13✔
39
                {
11✔
40
                    resultsDictionary.Add(item.Name, item);
11✔
41
                }
11✔
42
                else
43
                {
2✔
44
                    //if the item exists in the dictionary, add the quantity to the existing item
45
                    resultsDictionary[item.Name].Quantity += item.Quantity;
2✔
46
                }
2✔
47
            }
13✔
48

49
            //sort the dictonary back into a list
50
            results = resultsDictionary.Values.ToList();
3✔
51

52
            //sort the results by counter to show the goal items first and raw items last, and then part name
53
            results = results.OrderBy(x => x.Counter).ThenBy(x => x.Name).ToList();
25✔
54

55
            return results;
3✔
56
        }
3✔
57

58
        private List<Item> GetIngredients(FinalData finalData, string partName, double quantity, int counter)
59
        {
13✔
60
            List<Item> results = new();
13✔
61
            counter++;
13✔
62
            NewRecipe newRecipe = FindRecipe(finalData, partName);
13✔
63

64
            //If we have a recipe, calculate the ingredients
65
            if (newRecipe != null && newRecipe.products != null)
13✔
66
            {
9✔
67
                double ratio = 0;
9✔
68
                foreach (Product product in newRecipe.products)
36✔
69
                {
9✔
70
                    if (product.part == partName)
9!
71
                    {
9✔
72
                        ratio = quantity / product.perMin;
9✔
73
                        break;
9✔
74
                    }
NEW
75
                }
×
76

77
                //If we have a recipe, calculate the ingredients
78
                if (newRecipe != null && newRecipe.ingredients != null)
9!
79
                {
9✔
80
                    foreach (Ingredient ingredient in newRecipe.ingredients)
47✔
81
                    {
10✔
82
                        //Get this ingredient's recipe
83
                        NewRecipe ingredientRecipe = FindRecipe(finalData, ingredient.part);
10✔
84
                        string? buildingName = null;
10✔
85
                        double buildingRatio = 0;
10✔
86
                        if (ingredientRecipe != null)
10✔
87
                        {
6✔
88
                            buildingName = ingredientRecipe.building.name;
6✔
89
                            buildingRatio = ingredient.perMin * ratio / ingredientRecipe.products[0].perMin;
6✔
90
                        }
6✔
91

92
                        //Add this ingredient
93
                        results.Add(new() { Name = ingredient.part, Quantity = ingredient.perMin * ratio, Ingredients = new(), Building = buildingName, BuildingQuantity = buildingRatio, Counter = counter });
10✔
94
                        //Search for this ingredient's dependencies
95
                        results.AddRange(GetIngredients(finalData, ingredient.part, ingredient.perMin * ratio, counter));
10✔
96
                    }
10✔
97
                }
9✔
98
                ////Check to see if the part is a raw material
99
                //else if (finalData.items.rawResources.ContainsKey(partName))
100
                //{
101
                //    results.Add(new() { Name = partName, Quantity = quantity, Ingredients = new(), Counter = counter });
102
                //}
103
            }
9✔
104
            return results;
13✔
105
        }
13✔
106

107
        private NewRecipe FindRecipe(FinalData finalData, string partName)
108
        {
26✔
109
            foreach (NewRecipe recipe in finalData.newRecipes)
12,220✔
110
            {
6,080✔
111
                //Skip alternative recipes for now
112
                if (recipe != null && recipe.isAlternate == false && recipe.building.name != "converter")
6,080✔
113
                {
2,814✔
114
                    foreach (Product product in recipe.products)
13,940✔
115
                    {
2,758✔
116
                        if (product.part == partName)
2,758✔
117
                        {
18✔
118
                            return recipe;
18✔
119
                        }
120
                    }
2,740✔
121
                }
2,796✔
122
            }
6,062✔
123
            return null;
8✔
124
        }
26✔
125
    }
126
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc