なずブログ

インフラSE、Java開発、リモートワークエンジニアな人のメモ帳

オブジェクト指向でFizzBuzz イン JAVA ~手続き型で考えるとわかんない~

f:id:nazuna_0124:20170329192937p:plain

わかりやすく、表題ではオブジェクト指向と書きましたが、

いつも通り自信なし。オブジェクト主体って言いたいです。


昨日の鯛焼きで気がついたことの続きです。

オブジェクト主体でならすぐ出来るのに、手続き型で思いつかない!!


今回のお題はこちらです。


・3人で実際にFizzBuzzをやってみた。

・それぞれ苦手倍数があり、1%の確率で間違える。

・開始数字と回答順は固定。

・10回戦して勝敗を表示。


さっくりとやってみて確認すると問題発生!すぐ気づくべきだったかも…


3人だと順番によって苦手倍数が回ってこないので負けがありません


4人ですることに変更。ついでに、間違える確率を指定できるように。

(ほんと、こういう変更が簡単なのです)


ソースはこんなかんじ。Mainはわかりやすさ重視!!

本当はPersonは配列にして、ちゃんと回答順を入れ替えるべきかなって思います。


Main.java

public class Main {

    public static void main(String[] args) {

   //名前、苦手倍数、苦手倍数が回ってきたときの誤答率です。
        Person bob = new Person("ボブ", 3, 1);
        Person ken = new Person("ケン", 5, 1);
        Person emily = new Person("エミリー", 15, 1);
        Person tom = new Person("トム", 3, 2);

        for (int i = 0; i < 10; i++) {
            Judge j = new Judge();
            while (j.game == true) {

                emily.answer(j);
                System.out.println(j.game);
                if (j.game == false) {
                    break;
                }

                ken.answer(j);
                System.out.println(j.game);
                if (j.game == false) {
                    break;
                }

                bob.answer(j);
                if (j.game == false) {
                    break;
                }
                System.out.println(j.game);

                tom.answer(j);
                if (j.game == false) {
                    break;
                }
                System.out.println(j.game);
            }
        }
        System.out.println("ボブの負け数:" + bob.loose);
        System.out.println("ケンの負け数:" + ken.loose);
        System.out.println("エミリーの負け数:" + emily.loose);
        System.out.println("トムの負け数:" + tom.loose);

    }
}


Person.java

public class Person {
    String name ;
    int loose = 0;
    int weakNum;
    int missRate;
    
    Person(String name,int num ,int missRate){
        this.name = name;
        this.weakNum = num;
        this.missRate = missRate;
    }
    
    void answer(Judge j) {
        String res = "";
        
        if(j.cnt % 15 == 0){
            res = "FizzBuzz";
        }else if(j.cnt % 3 == 0){
            res = "Fizz";
        }else if(j.cnt % 5 == 0){
            res = "Buzz";
        }else{
            res = String.valueOf(j.cnt);
        }
        
        //一定の確率で間違う処理
        if(j.cnt % this.weakNum == 0){
            int rnd = new java.util.Random().nextInt(99) +1 ;
            
            if (rnd <= this.missRate){
                res = "miss!";
            }
                   
        }
        
        System.out.println(this.name + ":"  + res);        
        j.check(this,res);
    }  
}


Judge.java

public class Judge {
    int cnt =1;
    int endCnt = 10000;
    boolean game = true;

    Boolean check(Person p ,String answer) {
        int counter = this.cnt ;
        String correct;

            if(counter % 15 == 0){
                correct = "FizzBuzz";
            }else if(counter% 3 == 0){
                correct = "Fizz";
            }else if(counter % 5 == 0){
                correct = "Buzz";
            }else{
                correct = String.valueOf(counter);
            }
        
        if(answer.equals(correct) == true){
            this.cnt++;
            
            if ( this.cnt >= this.endCnt){
                return false;
            }else{
                return true;
            }
            
        }else{
            p.loose ++;
            this.game = false ;
            return false;
        }      
    }    
}


結果は至って普通に考えて出現頻度の低い15倍数が苦手のエミリーが強いです。


頻出の3倍で2%間違えるトムは激弱。エミリーを6%まで誤答率を引き上げると

だいたいおんなじ感じになるので、ほとんど出現率依存な雰囲気。


数学的にはさっぱりわかりませんが!!


というわけで、何の言語でも構いませんので、

ふつーに今回のお題を作っていただける方大募集です!