using System.Collections.Generic;
public static void Main()
var superStoneHatchet = new SuperStoneHatchet();
foreach(var material in superStoneHatchet.GetAllMaterials())
Console.WriteLine(material.Item.Name + ": " + material.Amount);
public abstract class Item
public abstract string Name { get; }
public abstract string Description { get; }
public abstract Ingredient[] Recipe { get; }
private bool IsMaterial => Recipe == null || Recipe.Length == 0;
public IEnumerable<Ingredient> GetAllMaterials()
return GetAllIngredients()
.Where(ing => ing.Item.IsMaterial)
.GroupBy(ing => ing.Item.Name)
.Select(ing => new Ingredient(ing.First().Item, ing.Sum(i => i.Amount)));
private IEnumerable<Ingredient> GetAllIngredients()
foreach (Ingredient ing in Recipe)
foreach(var subIngredient in ing.Item.GetAllIngredients())
yield return new Ingredient(subIngredient.Item, ing.Amount * subIngredient.Amount);
public Item Item { get; }
public int Amount { get; }
public Ingredient(Item item, int amount)
public IEnumerable<Ingredient> GetIngredientQuantities()
foreach (var ing in Item.GetAllMaterials())
yield return new Ingredient(ing.Item, ing.Amount * this.Amount);
public override string Name { get; }
public override string Description { get; }
public override Ingredient[] Recipe { get; }
Description = "Type of resource.";
public class Stone : Item
public override string Name { get; }
public override string Description { get; }
public override Ingredient[] Recipe { get; }
Description = "Type of resource.";
public class StoneHatchet : Item
public override string Name { get; }
public override string Description { get; }
public override Ingredient[] Recipe { get; }
Description = "Can be used as a weapon.";
Recipe = new Ingredient[]
new Ingredient(new Wood(), 10),
new Ingredient(new Stone(), 5)
public class SuperStoneHatchet : Item
public override string Name { get; }
public override string Description { get; }
public override Ingredient[] Recipe { get; }
public SuperStoneHatchet()
Name = "Super Stone Hatchet";
Description = "It’s like a stone hatchet, but with more stone.";
Recipe = new Ingredient[]
new Ingredient(new StoneHatchet(), 2),
new Ingredient(new Stone(), 5)