1.模拟抛硬币过程

首先,试图使用Java模拟一个抛硬币的过程。过程是使用一个随机函数随机的产生正与反,然后进行统计。
Coin.java

package zj.code.fun1;

import java.util.Random;

public class Coin {

    private int negative=0;

    private int positive=0;

    private int turn;

   

    public Coin(int turn){

       this.turn=turn;

    }

   

    public void tossing(){

       Random rand=new Random();

       for(int i=0;i<turn;i++){

           getResult(rand.nextInt(2));

       }

       showResults();

    }

   

    public void getResult(int i){

       if(i==0)

           negative++;

       else if(i==1)

           positive++;

       else

           System.err.println("Wrong result.");

    }

   

    public void showResults(){

       System.out.println("Play turns:"+turn);

       System.out.println("Get negative:"+negative+","

              +(float)negative/(float)turn*100+"%");

       System.out.println("Get positive:"+positive+","

              +(float)positive/(float)turn*100+"%");

    }

   

    public static void main(String[] args) {

       Coin co=new Coin(200);

        co.tossing();

    }

}

成员变量negitivepositve分别统计出现正反的次数,turn表示模拟的轮次。方法tossing()里面包含一个随机数01产生的过程,并将结果交给方法getResult()处理用于统计。最后通过方法showResults()可以显示统计结果。
下面做个测试,main()方法中通过抛200次,可以得到类似结果,
Play turns:200

Get negative:105,52.499996%

Get positive:95,47.5%
2.过程提炼与抽象

上面的代码可以很好的模拟抛硬币的场景,但太过于具体,我试图将其抽象化。
首先对于一个随机过程的演示,我想到它应该做3件事情,1提供随机产生器;2进行过程演示;3输出结果。我把它定义到一个接口中。
Randomer.java  <<interface>>
package zj.code.fun2;

public interface Randomer {

    public Seeder getSeed();

   

    public void runToss();

   

    public void showResults();

}
而设想针对抛硬币的过程,我使用一个抽象类先部分给出设定随机数产生器与轮次的概念。当然对于过程演示(runToss)与输出结果(showResults)是具体应用的东西,先不作考虑,继续抽象它。
Tosser.java <<abstract class>>
package zj.code.fun2;

public abstract class Tosser implements Randomer{

    protected Seeder curSeed;

    protected int turn;

 

    public Tosser(Seeder seed,int turn){

       curSeed=seed;

       this.turn=turn;

    }

   

    public Seeder getSeed() {

       return curSeed;

    }

 

    public void changeSeed(Seeder curSeed) {

       this.curSeed = curSeed;

    }

   

    public abstract void runToss();

   

    public abstract void showResults();

}

好了,现在试图提供一个随机数产生器,这个产生器设定为基于均等机率产生整型数。产生数的范围range是可以通过具体应用设定的。
Seeder.java

package zj.code.fun2;

import java.util.Random;

public class Seeder {

    private int range;

    Random rand=new Random();

   

    public Seeder(int range){

       this.range=range;

    }

 

    public int getValue(){

       return rand.nextInt(range);

    }

}

3.抛硬币与掷骰子

现在我用上面的结构,再次设计一个抛硬币的过程。它会继承抽象类Tosser
Coin.java

package zj.code.fun2;

 

public class Coin extends Tosser{

    private int negative=0;

    private int positive=0;

   

    public Coin(int turn) {

       super(new Seeder(2), turn);

    }

 

    @Override

    public void runToss() {

       for(int i=0;i<turn;i++){

           int v=curSeed.getValue();

           if(v==0)

              negative++;

           else if(v==1)

              positive++;

           else

              System.err.println("Wrong result.");

       }

    }

 

    @Override

    public void showResults() {

       System.out.println("Play turns:"+turn);

       System.out.println("Get negative:"+negative+","

              +(float)negative/(float)turn*100+"%");

       System.out.println("Get positive:"+positive+","

              +(float)positive/(float)turn*100+"%");

    }

   

    public static void main(String[] args) {

       Coin co=new Coin(200);

       co.runToss();

       co.showResults();

    }

}
在构造子中,我设定了随机数构造器的range=2。并将runToss()与showResults()的具体逻辑补充完。在main()方法中,再次进行测试,轮次还是200。可以得到类似的结果为,
Play turns:200

Get negative:99,49.5%

Get positive:101,50.5%
有了上面的结构,我不但可以抛硬币,我还可以掷骰子。
Dice.java

package zj.code.fun2;

public class Dice extends Tosser{

    private int ONE=0;

    private int TWO=0;

    private int THREE=0;

    private int FOUR=0;

    private int FIVE=0;

    private int SIX=0;

 

    public Dice(int turn) {

       super(new Seeder(6), turn);

    }

    @Override

    public void runToss() {

       for (int i = 0; i < turn; i++) {

           int v = curSeed.getValue();

           switch (v) {

           case 0:

              ONE++;

              break;

           case 1:

              TWO++;

              break;

           case 2:

              THREE++;

              break;

           case 3:

              FOUR++;

              break;

           case 4:

              FIVE++;

              break;

           case 5:

              SIX++;

              break;

           default:

              System.err.println("Wrong result.");

           }

       }

    }

 

    @Override

    public void showResults() {

       System.out.println("Play turns:"+turn);

       System.out.println("Get ONE:"+ONE+","

              +(float)ONE/(float)turn*100+"%");

       System.out.println("Get TWO:"+TWO+","

              +(float)TWO/(float)turn*100+"%");

       System.out.println("Get THREE:"+THREE+","

              +(float)THREE/(float)turn*100+"%");

       System.out.println("Get FOUR:"+FOUR+","

              +(float)FOUR/(float)turn*100+"%");

       System.out.println("Get FIVE:"+FIVE+","

              +(float)FIVE/(float)turn*100+"%");

       System.out.println("Get SIX:"+SIX+","

              +(float)SIX/(float)turn*100+"%");

    }

 

    public static void main(String[] args) {

       Dice di=new Dice(200);

       di.runToss();

       di.showResults();

    }

}

同样设定轮次为200,可以得到类似的测试结果,
Play turns:200

Get ONE:32,16.0%

Get TWO:29,14.5%

Get THREE:36,18.0%

Get FOUR:36,18.0%

Get FIVE:24,12.0%

Get SIX:43,21.5%
4. 既抛硬币又掷骰子

现在既要抛硬币又要掷骰子,我在抽象基类Tosser中增加一个Simple Factory
Tosser.java <<abstract class>>
。。。
public final static Randomer getTosserInstance(String type, int turn) {

    if (type.equalsIgnoreCase("coin"))

       return new Coin(turn);

    else if (type.equalsIgnoreCase("dice"))

       return new Dice(turn);

    else {

       System.err.println("Wrong Type.");

       return null;

    }

}
。。。
下面写一个测试类。
TosserTest.java

package zj.code.fun2;

public class TosserTest {

    public static void main(String[] args) {

       Randomer rand=Tosser.getTosserInstance("coin", 100);

       rand.runToss();

       rand.showResults();

       System.out.println("==================");

       rand=Tosser.getTosserInstance("dice", 100);

       rand.runToss();

       rand.showResults();

    }

}
既抛硬币又掷骰子,轮次都为100,可以得到类似测试结果为,
Play turns:100

Get negative:52,52.0%

Get positive:48,48.0%

==================

Play turns:100

Get ONE:17,17.0%

Get TWO:20,20.0%

Get THREE:17,17.0%

Get FOUR:18,18.0%

Get FIVE:12,12.0%

Get SIX:16,16.0%