2018年7月13日金曜日

開発環境

Head First C# ―頭とからだで覚えるC#の基本 (Andrew Stellman (著)、Jennifer Greene (著)、佐藤 嘉一 (監修, 監修)、木下 哲也 (翻訳)、オライリージャパン)の5章(継承 - オブジェクトの系図)、エクササイズ(p. 216)を取り組んでみる。

コード

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App1"
             x:Class="App1.MainPage">
    <StackLayout>
        <Label Text="働き蜂への仕事の割り当て"/>
        <Picker x:Name="workerBeeJob"
                Title="働き蜂の仕事">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>巣のメンテナンス</x:String>
                    <x:String>蜂蜜の収集</x:String>
                    <x:String>蜂蜜の製造</x:String>
                    <x:String>卵の世話</x:String>
                    <x:String>幼虫の世話</x:String>
                    <x:String>パトロール</x:String>
                </x:Array>
            </Picker.ItemsSource>
        </Picker>
        <Label Text="シフト"/>
        <Editor x:Name="shifts"
                Text="2"/>
        <Button Text="この仕事を蜂に割り当てる"
                Clicked="assignJob_Clicked"/>
        <Button Text="次のシフトの実行"
                Clicked="nextShift_Clicked"/>
        <Editor x:Name="report" VerticalOptions="FillAndExpand"/>
    </StackLayout>
</ContentPage>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    public partial class MainPage : ContentPage
    {
        private Queen queen;
        public MainPage()
        {
            InitializeComponent();

            Worker[] workers =
            {
                new Worker(175, new string[] {"蜂蜜の収集", "蜂蜜の製造" }),
                new Worker(114, new string[]{"卵の世話", "幼虫の世話"}),
                new Worker(149, new string[]{"巣のメンテナンス", "パトロール" }),
                new Worker(155, new string[]
                {"卵の世話", "楊柳の世話", "巣のメンテナンス", "パトロール"})
            };
            queen = new Queen(275, workers);
        }

        private void assignJob_Clicked(object sender, EventArgs e)
        {
            string job = workerBeeJob.SelectedItem.ToString();
            int shift = Convert.ToInt32(shifts.Text);
            if (queen.AssignWork(job, shift))
            {
                DisplayAlert(
                    "女王蜂が言った...",
                    "'" + job + "'は、あと" + shift + "シフトで終わる。",
                    "OK");
            }
            else
            {
                DisplayAlert("女王蜂が言った...",
                 "'" + job + "'の仕事をさせるための蜂がいない。",
                 "OK");
            }
        }

        private void nextShift_Clicked(object sender, EventArgs e)
        {
            report.Text += queen.WorkTheNextShift();
        }
    }

    public class Bee
    {
        private double weight;

        public Bee(double weight)
        {
            this.weight = weight;
        }

        public virtual int ShiftsLeft { get => 0; }

        public virtual double GetHoneyConsumption()
        {
            double consumption = 
                ShiftsLeft == 0 ? 7.5 : 9 + ShiftsLeft;
            consumption *= weight > 150 ? 1.35 : 1;
            return consumption;
        }
    }

    public class Queen:Bee
    {
        private Worker[] workers;
        private int shiftNumber;

        public Queen(double weight, Worker[] workers):
            base(weight)
        {
            this.workers = workers;
        }

        public override double GetHoneyConsumption()
        {
            double consumption = 0;
            int shifts = 0;
            foreach (Worker worker in workers)
            {
                if (worker.GetHoneyConsumption() > consumption)
                {
                    consumption = worker.GetHoneyConsumption();
                }
                if (worker.ShiftsLeft > 0)
                {
                    shifts++;
                }
            }
            consumption += shifts <= 2 ? 20 : 30;
            return consumption;
        }

        public bool AssignWork(string job, int shiftsToWork)
        {
            foreach (var worker in workers)
            {
                if (worker.DoThisJob(job, shiftsToWork))
                {
                    return true;
                }
            }
            return false;
        }

        public string WorkTheNextShift()
        {
            double consumption = 0;
            foreach (Worker worker in workers)
            {
                consumption += worker.GetHoneyConsumption();
            }
            consumption += this.GetHoneyConsumption();

            shiftNumber++;
            string report = "シフト#" + shiftNumber + "のレポート\r\n";
            for (int i = 0; i < workers.Length; i++)
            {
                Worker worker = workers[i];

                if (worker.WorkOneShift())
                {
                    report += "働き蜂#" + (i + 1) + "は作業を完了しました。\r\n";
                }
                if (string.IsNullOrEmpty(worker.CurrentJob))
                {
                    report += "働き蜂#" + (i + 1) + "の作業はありません。\r\n";
                }
                else
                {
                    if (worker.ShiftsLeft > 0)
                    {
                        report += "働き蜂#" + (i + 1) + "'" +
                            worker.CurrentJob +
                            "'の作業中で、あと" + worker.ShiftsLeft +
                            "つシフトがあります。\r\n";
                    }
                    else
                    {
                        report += "働き蜂#" + (i + 1) + "はこのシフトで'" + 
                            worker.CurrentJob + 
                            "'の作業を完了します。\r\n";
                    }
                }
            }

            report += "消費したすべての蜂蜜の量: " + consumption + "単位\r\n";

            return report;
        }
    }

    public class Worker:Bee
    {
        private string currentJob;
        private string[] jobsICanDo;
        private int shiftsToWork;
        private int shiftsWorked;

        public Worker(double weight, string[] jobsICanDo):
            base(weight)
        {
            this.jobsICanDo = jobsICanDo;
        }

        public string CurrentJob { get => currentJob; }
        public override int ShiftsLeft { get => shiftsToWork - shiftsWorked; }

        public bool DoThisJob(string job, int shiftsToWork)
        {
            if (string.IsNullOrEmpty(currentJob))
            {
                foreach (var item in jobsICanDo)
                {
                    if (item == job)
                    {
                        this.shiftsToWork = shiftsToWork;
                        currentJob = job;
                        shiftsWorked = 0;
                        return true;
                    }
                }
            }
            return false;
        }

        public bool WorkOneShift()
        {
            if (string.IsNullOrEmpty(currentJob))
            {
                return false;
            }
            shiftsWorked++;
            if (shiftsWorked > shiftsToWork)
            {
                shiftsWorked = 0;
                shiftsToWork = 0;
                currentJob = "";
                return true;
            }
            return false;
        }
    }
}

App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1.App">
 <Application.Resources>
    
 </Application.Resources>
</Application>

App.xaml.cs

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace App1
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            // MainPage = new MainPage();
            MainPage = new NavigationPage(
                new MainPage() { Title = "ミツバチの巣管理システム" });
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

0 コメント:

コメントを投稿