かみ砕いてみたC#(カプセル化の基本）


過去にやったC#の基本のカプセル化についてJavaを踏まえアウトプット

アクセス修飾子publicとpraivateの違い（他にもあるが初学者はこの二つがおすすめ)
「アクセス可能」か「アクセス不可」にしたいかで変わる

使って欲しい機能だけ見えるようにする

Program.cs

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleRPG
{
    class Program
    {
        static void Main(string[] args)
        {
            Player player = new Player("たかし", 500);
            
            player.Hp -= 2000;
            Console.WriteLine("HPは" + player.Hp);
        }
    }
}
```


Player.cs

```C#

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

namespace SampleRPG
{
    class Player
    {
        // privateなメンバ変数を宣言
        private string name;
        private int hp;

        // 以下、publicなコンストラクタとメンバメソッドを定義
        public Player(string name, int hp)
        {
            this.name = name;
            this.hp = hp;
        }

      
        public int Hp
        {
            set //処理された物をセット
            {
                this.hp = value;
                if (this.hp < 0)
                {
                    this.hp = 0;
                }
            }
            get
            {
                return this.hp; //現在のhp取得
            }
        }
        public String Name
        {
            set //処理された物をセット
            {
                this.name = value;
                if (value.Length < 8)
                {
                    this.name = value;
                }
            }
            get
            {
                return this.name; //現在のname取得
            }
        }
        /*public void SetName(string name)
        {
            
            if (name != null)
            {
                int len = name.Length;
                
                if (len <= 8)
                {
                    this.name = name;
                }
            }
        }

        
        public string GetName()
        {
            return this.name;
        }*/

        public void Attack()
        {
            Console.WriteLine(this.name + "は攻撃した");
        }

        public void Defense()
        {
            Console.WriteLine(this.name + "は防御した");
        }
    }
}
```

補足1

基本ではありますがjavaと同じでゲッターで現在の値を取得(get)してセッター(set)で取得して処理をする。

「C#」には「JAVA」と違いプロパティという仕組みがあります。
ゲッターとセッターを簡略化できる。

```C#
 public int Hp
        {
            set
            {
                this.hp = value;
                if (this.hp < 0)
                {
                    this.hp = 0;
                }
            }
            get
            {
                return this.hp;
            }
        }
```

補足2

staticキーワード

静的メンバはクラス事態に属する値なのでこれがつくと参照できない。

補足3

自クラスのコンストラクタの呼び出し

```C#
 public Person(string name,int age):this(name)
        {
            
        }
```

#応用問題

Q.Monkeyクラスを作成し、MonkeyAppクラスから以下の処理を実現せよ。(アクセス性はすべてpublicでよい）
[実行例]
おさるの名前を決めてください:>トシ
おさるの歳を決めてください:>3
おさるに何をさせますか？1…挨拶、2…竹馬、3…逆立ち、4…終了>1
こんにちはトシ(3才)です。よろしく！
おさるに何をさせますか？1…挨拶、2…竹馬、3…逆立ち、4…終了>2
トシは上手に竹馬にのった！
おさるに何をさせますか？1…挨拶、2…竹馬、3…逆立ち、4…終了>3
トシはひょいと逆立ちをした！
おさるに何をさせますか？1…挨拶、2…竹馬、3…逆立ち、4…終了>4
アプリケーションを終了します。

##MonkeyAPP作成
###Monkey.cs

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonkeyApp
{
    class Monkey
    {

        public String name;
        public int age;

        public Monkey()
        {
            
        }

        public void Info()
        {
            Console.WriteLine(this.name);
            Console.WriteLine(this.age);
        }



        public void reverse()
        {
            Console.WriteLine("こんにちは+" + this.name + "(" + this.name + ")です。よろしく！");
        }
        public void Take()
        {
            Console.WriteLine(this.name + "は上手に竹馬にのった！");
        }

        public void Defense()
        {
            Console.WriteLine(this.name + "ひょいと逆立ちをした！");
        }
       
        public void Lust()
        {
            Console.WriteLine("アプリケーションを終了します。");
        }
    }
}

```

###Program.cs
```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonkeyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Monkey monkey1 = new Monkey();
            Console.Write("おさるの名前を決めてください> ");
            monkey1.name = Console.ReadLine();
            Console.Write("あなたのお名前は？ : ");
            monkey1.age = int.Parse(Console.ReadLine());

            Console.Write("あおさるに何をさせますか？1…挨拶、2…竹馬、3…逆立ち、4…終了>");
            var select = int.Parse(Console.ReadLine());
            switch (select)
            {
                case 1:
                    monkey1.reverse();
                    break;
                case 2:
                    monkey1.Take();
                    break;
                case 3:
                    monkey1.Defense();
                    break;
                case 4:
                    monkey1.Lust();
                    break;
            }
        }
    }
}

```

###詰まった所

```C#
//Monkey.cs
Monkey monkey1 = new Monkey();

//Program.cs
public Monkey(){}
```

ここは「JavaBeans」で何度も見て記述してたはずなのに...

練習問題1(解く人の考えず分岐などあまり考えず過去に自分が考えたやりにくい奴です。）

Q1 Humanクラスを作成し、HumanAppクラスから以下の処理を実現せよ。(アクセス性はすべてpublicでよい）

[実行例1]
現在の体重は？:>70
目標体重は？:>50
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>1
1kg減りました！この調子で頑張りましょう！
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>2
5kg減りました！この調子で頑張りましょう！
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>3
10kg減りました！この調子で頑張りましょう！
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>4
16kg痩せてます！残り4kgです！頑張りましょう！
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>3
目標達成です！Congratulation!
[実行例2]
目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>5
アプリケーションを終了します。


練習問題2

１から１３の数とジョーカーが２枚入ったトランプ（計５４枚）を２組用意する
２組のトランプをランダムで引き二つとも同じ数を引いたときに抜ける処理を実現せよ
「条件」
１　引けるのは５回まで
２　ジョーカーをどちらかが引いた場合引ける数が１増える
３　ジョーカーをそろえて引いた場合負けそこでゲーム終了　ただし引いたカードは減ることとする
例A　３をドローした　
　　４をドローした　
　　残念

例B　１をドローした
    ジョーカーをドローした
    引ける回数が一回増えました

例C　５をドローした
　　　５をドローした
    成功ですおめでとう
例D　ジョーカーをドローした
    ジョーカーをドローした
    あなたの負けですゲーム終了
例E　５回で引けなかったら
    あなたの負けですゲーム終了

<details><summary>解答例</summary><div>

##Q1

Program.cs

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sano
{
    class Program
    {
        static void Main(string[] args)
        {
            
            Console.Write("現在の体重は？");
            int now = int.Parse(Console.ReadLine());
            Console.Write("目標体重は？");
            int goal = int.Parse(Console.ReadLine());
            Human h1 = new Human(now,goal,now);
            while (true)
            {
                Console.Write("目標に向けて今日は何キロ走りますか？1…10km、2…20km、3…30km、4…現在の情報、5…終了>");
                var select = int.Parse(Console.ReadLine());
                
                switch (select)
                {
                    case 1:
                       h1.Run10();
                       
                        break;
                    case 2:
                        h1.Run20();
                        
                        break;
                    case 3:

                        h1.Run30();
                        break;
                    case 4:
                        h1.ShowInfo();
                        break;
                    case 5:
                        h1.End();
                        return;
                }
                if (h1.GoalWeight >= h1.NowWeight)
                {
                    Console.WriteLine("目標達成ですCongratulation!");
                    break;
                }
            
                
            }
        }
    }
}
```

Human.cs

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sano
{
    class Human
    {
        public int NowWeight { get; set; }
        public int GoalWeight { get; set; }
        public int Weight { get; set; }
        public Human(int weight, int weight2, int weight3)
        {
            this.NowWeight = weight;
            this.GoalWeight = weight2;
            this.Weight = weight3;
        }
   
        public void Run10()
        {
            NowWeight--;
            if (GoalWeight < NowWeight)
            {
                Console.WriteLine("1kg減りました！この調子で頑張りましょう！");
            }
            
        }
        public void Run20()
        {
            NowWeight -= 5;
            if (GoalWeight < NowWeight)
            {


                Console.WriteLine("5kg減りました！この調子で頑張りましょう！");
            }
            
        }
        public void Run30()
        {
            NowWeight -= 10;
            if (GoalWeight < NowWeight)
            {
                Console.WriteLine("10kg減りました！この調子で頑張りましょう！");
            }
        }
        public void ShowInfo()
        {
            Console.WriteLine($"{Weight - NowWeight}kg痩せてます！残り{(NowWeight - GoalWeight)}kgです！頑張りましょう！");
        }
        public void End()
        {
            Console.WriteLine("アプリケーションを終了します");
        }
    }
}
```


Q2

Program.cs

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nagasawa {
    class Program {
        const int MAX_TURN = 5;
        static void Main(string[] args) {
            Deck d1 = new Deck();
            Deck d2 = new Deck();
            for(int i = 0; i < MAX_TURN; i++) {
                string c1 = d1.Draw();
                string c2 = d2.Draw();
                
                if (c1 == c2) {
                    Console.WriteLine("成功ですおめでとう");
                    return;
                }else if(c1=="ジョーカー" && c2 == "ジョーカー") {
                    Console.WriteLine("あなたの負けですゲーム終了");
                    return;
                }
                else if(c1=="ジョーカー" || c2 == "ジョーカー") {
                    Console.WriteLine("引ける回数が一回増えました");
                    i--;
                } else {
                    Console.WriteLine("残念");
                }
                Console.ReadLine();
            }
            Console.WriteLine("あなたの負けですゲーム終了");
        }
    }
    public class Deck {
        public List<string> Cards { get; set; }
        public Deck() {
            CreateDeck();
        }
        public void CreateDeck() {
            var temp = new List<string>();
            for (int i = 0; i < 54; i++) {
                if (i < 52) {
                    temp.Add( i % 13 + 1 + "");
                } else {
                    temp.Add( "ジョーカー");
                }
            }
            Cards = temp.OrderBy(i => Guid.NewGuid()).ToList();
        }
        public string Draw() {
            var card = Cards[0];
            Console.WriteLine(card + "をドローした");
            Cards.RemoveAt(0);
            return card;
        }
    }
}
```
</div></details>

知見を高めなければ