自动豆子机的Java实现

来源:互联网 发布:海康威视4g网络摄像头 编辑:程序博客网 时间:2024/04/28 22:11

豆子机是一个用来做统计学实验的设备,由英国科学家高尔顿发现,故又名为高尔顿瓶。如下图所示:

这里写图片描述

球从瓶口落下,每当碰到钉子(白圈),它就有50%的机会落向左边或者右边。于是在瓶子底部的格槽中就会累积一定的球,当球落够一定的次数或者任一格槽满后,实验停止。
程序实现:

BeanMachinePanel类

import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JPanel;import javax.swing.Timer;public class BeanMachinePanel extends JPanel{    final static int HGAP = 20;    final static int VGAP = 20;    final static int RADIUS = 5;    final static int LENGTH_OF_SLOTS = 40;    final static int LENGTH_OF_OPENNING = 15;    final static int Y_FOR_FIRST_NAIL = 50;    final static int RED_BALL_START_Y = Y_FOR_FIRST_NAIL - RADIUS;    final static int NUMBER_OF_SLOTS = 9;    final static int NUMBER_OF_ROWS = NUMBER_OF_SLOTS - 2;    private int shift = 0;    private int[] slots = new int[NUMBER_OF_SLOTS];    private int numberOfBallsDropped = 0;    private int moveCount = 0;    private int position = 0;    private int yRed = RED_BALL_START_Y;    private boolean hideRedBall = false;    private Timer timer=new Timer(200, new ActionListener() {        public void actionPerformed(ActionEvent e) {            moveCount++;            if(moveCount<=NUMBER_OF_ROWS){                if(Math.random()<0.5)                    moveRedBallLeft();                else{                    moveRedBallRight();                    position++;                }            }else            {                slots[position]++;                startRedBall();                shift=0;                moveCount=0;                position=0;                numberOfBallsDropped++;                if(numberOfBallsDropped==10){                    timer.stop();                    hideRedBall();                }            }        }    });    public BeanMachinePanel() {        timer.start();    }    public void moveRedBallLeft() {      shift -= HGAP / 2;      yRed += VGAP;      repaint();    }    /** 向右落下**/    public void moveRedBallRight() {      shift += HGAP / 2;      yRed += VGAP;      repaint();    }    /** 向左落下**/    public void startRedBall() {      yRed = RED_BALL_START_Y;      hideRedBall = false;      repaint();    }    /** 结束实验 **/    public void hideRedBall() {      hideRedBall = true;      repaint();    }    protected void paintComponent(Graphics g) {        super.paintComponent(g);        int y = Y_FOR_FIRST_NAIL;        int xCenter = getWidth() / 2;        if (!hideRedBall) {          g.setColor(Color.RED);          int xRed = xCenter + shift;          g.fillOval(xRed - RADIUS, yRed - RADIUS, 2 * RADIUS, 2 * RADIUS);        }        g.setColor(Color.GREEN);        for (int i = 0; i < NUMBER_OF_ROWS; i++) {          y += VGAP;          for (int k = 0; k <= i; k++) {            g.fillOval(xCenter - i * HGAP / 2 + k * HGAP - RADIUS, y - RADIUS, 2 * RADIUS, 2 * RADIUS);          }        }        g.setColor(Color.BLACK);        y = y + RADIUS;        for (int i = 0; i < NUMBER_OF_SLOTS; i++) {          int x = xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + (i - 1) * HGAP;          g.drawLine(x, y, x, y + LENGTH_OF_SLOTS);        }        g.drawLine(xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 - HGAP, y + LENGTH_OF_SLOTS,           xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + NUMBER_OF_ROWS * HGAP, y + LENGTH_OF_SLOTS);        g.drawLine(xCenter + HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + NUMBER_OF_ROWS * HGAP, y);        g.drawLine(xCenter - HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 - HGAP, y);        g.drawLine(xCenter - HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - HGAP / 2, Y_FOR_FIRST_NAIL - LENGTH_OF_OPENNING);        g.drawLine(xCenter + HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter + HGAP / 2, Y_FOR_FIRST_NAIL - LENGTH_OF_OPENNING);        g.setColor(Color.RED);              for (int i = 0; i < slots.length; i++) {          int x = xCenter - (NUMBER_OF_ROWS) * HGAP / 2 + i * HGAP;          for (int j = 0; j < slots[i]; j++) {            g.fillOval(x - RADIUS, y + LENGTH_OF_SLOTS - 2 * RADIUS - j * 2 * RADIUS, 2 * RADIUS, 2 * RADIUS);          }        }      }}

主函数

import javax.swing.JFrame;public class MainFrame extends JFrame{    private BeanMachinePanel panel=new BeanMachinePanel();    public MainFrame() {            add(panel);    }    public static void main(String[] args) {        MainFrame frame=new MainFrame();        frame.setTitle("豆子机");        frame.setSize(300, 300);        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.setLocationRelativeTo(null);        frame.setVisible(true);    }}

运行结果:

开始
实验开始

结束
实验结束

0 0