paiza.ioでc# その7

# 概要
paiza.ioでc#、やってみた。
練習問題やってみた。

# 練習問題
オブジェクト指向なアプリを書け。

# 参考にしたページ

https://qiita.com/elipmoc101/items/4ba1ed383c157cc5ad01


# サンプルコード

```

using System;
using System.Linq;
using System.Collections.Generic;
using static Domain.HandKind; 
using static Domain.ResultKind;
using Domain;

namespace Domain
{
    enum ResultKind {
        Win,
        Lose,
        Draw
    }
    enum HandKind {
        Guu,
        Tyoki,
        Paa
    }
    interface IRule {
        ResultKind Judge(HandKind myHand, IEnumerable<HandKind> otherHands);
    }
    class StandardRule: IRule {
        public ResultKind Judge(HandKind myHand, IEnumerable<HandKind> otherHands) {
            uint winCount = 0;
            uint loseCount = 0;
            foreach (var otherHand in otherHands)
            {
                var resultKind = Judge(myHand, otherHand);
                if (resultKind == Win) 
                    winCount++;
                else if (resultKind == Lose) 
                    loseCount++;
            }
            if (winCount * loseCount != 0 || winCount + loseCount == 0) 
                return Draw;
            if (winCount != 0) 
                return Win;
            return Lose;
        }
        private ResultKind Judge(HandKind myHand, HandKind otherHand) {
            if (myHand == otherHand) 
                return Draw;
            if 
            (
                (myHand == Guu && otherHand == Paa) || (myHand == Tyoki && otherHand == Guu) || (myHand == Paa && otherHand == Tyoki))
                return Lose;
            return Win;
        }
    }
    class Human<Rule> where Rule: IRule {
        private readonly Rule rule;
        public HandKind Hand { 
            get; 
        }
        public Human(Rule rule, HandKind hand) {
            this.rule = rule;
            this.Hand = hand;
        }
        public ResultKind KnowResult(Human<Rule>[] otherHumen) => rule.Judge(Hand, otherHumen.Select(x => x.Hand));
    }
}
namespace Application
{
    interface IView {
        event Action<string> OnInput;
        void ShowRequest();
        void ShowTryRequest();
        void ShowResult(string result, string myHand, IEnumerable<string> aiHands);
    }
    class Program {
        static void Main(string[] args) {
            new Application.Game(new UserInterface.ConsoleView(), new Application.AiHumanCreator(new Random()));
        }
    }
    class Game {
        public Game(IView view, AiHumanCreator aiHumanCreator) {
            view.OnInput += input => {
                var handKind = StringConverter.StringToHandKind(input);
                if (handKind == null)
                {
                    view.ShowTryRequest();
                    return;
                }
                var player = new Human<StandardRule>(new StandardRule(), (HandKind)handKind);
                var aiHumen = aiHumanCreator.CreateAiHumen(new StandardRule(), 2);
                view.ShowResult(StringConverter.ResultKindToString(player.KnowResult(aiHumen)), StringConverter.HandKindToString(player.Hand), aiHumen.Select(x => StringConverter.HandKindToString(x.Hand)));
            };
            view.ShowRequest();
        }
    }
    class AiHumanCreator {
        private readonly Random rand;
        public AiHumanCreator(Random rand) => this.rand = rand;
        public Human<Rule>[] CreateAiHumen<Rule>(Rule rule, uint size) where Rule: IRule {
            var handKinds = new HandKind[] { 
                HandKind.Guu, 
                HandKind.Tyoki, 
                HandKind.Paa 
            };
            var aiHumen = new Human<Rule>[size];
            for (int i = 0; i < aiHumen.Length; i++)
            {
                var aiHandKind = handKinds[rand.Next(3)];
                aiHumen[i] = new Human<Rule>(rule, aiHandKind);
            }
            return aiHumen;
        }
    }
    static class StringConverter {
        static public HandKind? StringToHandKind(string consoleString) {
            int result;
            if (int.TryParse(consoleString, out result) == false) 
                return null;
            if (result < 1 || result > 3) 
                return null;
            var handKinds = new HandKind[] { 
                HandKind.Guu, 
                HandKind.Tyoki, 
                HandKind.Paa 
            };
            return handKinds[result - 1];
        }
        static public string ResultKindToString(ResultKind resultKind) {
            switch (resultKind)
            {
            case ResultKind.Draw:
                return "引き分け";
            case ResultKind.Win:
                return "勝利";
            default:
                return "敗北";
            }
        }
        static public string HandKindToString(HandKind handKind) {
            switch (handKind)
            {
            case HandKind.Guu:
                return "グー";
            case HandKind.Tyoki:
                return "チョキ";
            default:
                return "パー";
            }
        }
    }
}    
namespace UserInterface
{
    class ConsoleView: Application.IView {
        public event Action<string> OnInput;
        public void ShowRequest() {
            Console.WriteLine("ジャンケンの手を選んでください（1=グー,2=チョキ,3=パー）");
            var input = Console.ReadLine();
            OnInput(input);
        }
        public void ShowTryRequest() {
            Console.WriteLine("もう一度入力してください");
            ShowRequest();
        }
        public void ShowResult(string result, string myHand, IEnumerable<string> aiHands) {
            Console.WriteLine("あなた:" + myHand);
            foreach (var aiHand in aiHands)
                Console.WriteLine("AI:" + aiHand);
            Console.WriteLine("あなたは" + result + "です");
        }
    }
}



```

# 実行結果

```
ジャンケンの手を選んでください（1=グー,2=チョキ,3=パー）
あなた:グー
AI:グー
AI:グー
あなたは引き分けです
```

# 成果物

https://paiza.io/projects/1So0VWeLUzS9O4dScwdinA


以上。