計算機科学のブログ

inheritance - Your object's family tree - beehive management system class model

Head First C Sharp: A Learner’s Guide to Real-World Programming with C Sharp and .NET (Andrew Stellman(著)、Jennifer Greene(著)、O’Reilly Media)の Chapter 6(inheritance - Your object’s family tree)、p.320(Long Exercise)の解答を求めてみる。

コード

Program.cs

static class HoneyVault
{
    public const float NECTAR_CONVERSION_RATIO = .19f;
    public const float LOW_LEVEL_WARNING = 10f;
    public static string StatusReport
    {
        get
        {
            string statusReport = $"{honey:0.0} units of honey\n" +
            $"{nectar:0.0} units of nector";
            if (honey < LOW_LEVEL_WARNING)
            {
                statusReport += $"\nLOW HONEY - ADD A HONEY MANUFACTURER";
            }
            if (nectar < LOW_LEVEL_WARNING)
            {
                statusReport += $"\nLOW NECTAR - ADD A NECTAR MANUFACTURER";
            }
            return statusReport;
        }
    }
    private static float honey = 25f;
    static private float nectar = 100f;
    public static void CollectedNectar(float amount)
    {
        if (amount > 0)
        {
            honey += amount;
        }
    }
    public static void ConvertNectarToHoney(float amount)
    {
        if (nectar < amount)
        {
            amount = nectar;
        }
        nectar -= amount;
        honey += amount * NECTAR_CONVERSION_RATIO;
    }
    public static bool ConsumeHoney(float amount)
    {
        if (honey >= amount)
        {
            honey -= amount;
            return true;
        }
        return false;
    }
}

class Bee
{
    public string Job { get; private set; }
    public virtual float CosntPerShift { get; }
    public Bee(string job)
    {
        Job = job;
    }
    public void WorkTheNextShift()
    {
        if (HoneyVault.ConsumeHoney(CosntPerShift))
        {
            DoJob();
        }
    }
    protected virtual void DoJob() { }
}
class Queen : Bee
{
    private const float EGGS_PER_SHIFT = 0.45f;
    private const float HONEY_PER_UNASSIGNED_WORKER = 0.5f;
    public string StatusReport { get; private set; } = "";
    private Bee[] workers = new Bee[0];
    private float eggs = 0;
    private float unassignedWorkers = 3;
    public override float CosntPerShift => 2.15f;
    protected override void DoJob()
    {
        eggs += EGGS_PER_SHIFT;
        foreach (Bee worker in workers)
        {
            worker.WorkTheNextShift();
        }
        HoneyVault.ConsumeHoney(HONEY_PER_UNASSIGNED_WORKER * workers.Length);
        UpdateStatusReport();
    }
    public void AssignBee(string job)
    {
        switch (job)
        {
            case "Honey Manufacturer":
                AddWorker(new HoneyManufacturer());
                break;
            case "Nectar Collector":
                AddWorker(new NectarCollector());
                break;
            case "Egg Care":
                AddWorker(new EggCare());
                break;
        }
        UpdateStatusReport();
    }

    private void AddWorker(Bee worker)
    {
        if (unassignedWorkers >= 1)
        {
            unassignedWorkers--;
            Array.Resize(ref workers, workers.Length + 1);
            workers[workers.Length - 1] = worker;
        }
    }
    public void CareForEggs(float eggsToConvert)
    {
        if (eggs >= eggsToConvert)
        {
            eggs -= eggsToConvert;
            unassignedWorkers += eggs;
        }
    }
    private void UpdateStatusReport()
    {
        int nectarCollector = 0;
        int honeyManufacturer = 0;
        int eggCare = 0;
        foreach (Bee worker in workers)
        {
            switch (worker.Job)
            {
                case "Nectar Collector":
                    nectarCollector++;
                    break;
                case "Honey Manufacturer":
                    honeyManufacturer++;
                    break;
                case "Egg Care":
                    eggCare++;
                    break;
            }
        }
        StatusReport = "Vault report:\n" +
        HoneyVault.StatusReport + "\n" +
        $"Egg count: {eggs}\n" +
        $"Unassigned workers: {unassignedWorkers}\n" +
        $"{nectarCollector} Nectar Collector bee";
        if (nectarCollector > 1) StatusReport += "s";
        StatusReport += $"\n{honeyManufacturer} Honey Manufacturer bee";
        if (honeyManufacturer > 1) StatusReport += "s";
        StatusReport += $"\n{eggCare} Egg Care bee";
        if (eggCare > 1) StatusReport += "s";
        StatusReport += $"\nTOTAL WORKERS: {workers.Length}";
    }


    public Queen() : base("Queen")
    {
        string[] jobs = ["Heny manufacturer", "Nectar Collectar", "Egg Care"];
        foreach (string job in jobs)
        {
            AssignBee(job);
        }
    }
}
class HoneyManufacturer : Bee
{
    private const float NECTAR_PROCESSED_PER_SHIFT = 33.15f;
    public override float CosntPerShift => 1.7f;
    protected override void DoJob()
    {
        HoneyVault.ConvertNectarToHoney(NECTAR_PROCESSED_PER_SHIFT);
    }
    public HoneyManufacturer() : base("Honey Manufacturer") { }
}
class NectarCollector : Bee
{
    private const float NECTAR_COLLECTED_PER_SHIFT = 33.25f;
    public override float CosntPerShift => 1.95f;
    protected override void DoJob()
    {
        HoneyVault.CollectedNectar(NECTAR_COLLECTED_PER_SHIFT);
    }
    public NectarCollector() : base("Nectar Collector") { }
}
class EggCare : Bee
{
    private Queen queen;
    private const float CARE_PROGRESS_PER_SHIFT = 0.15f;
    public override float CosntPerShift => 1.35f;
    protected override void DoJob()
    {
        queen.CareForEggs(CARE_PROGRESS_PER_SHIFT);
    }
    public EggCare() : base("Egg Care")
    {
        queen = new Queen();
    }
}