スナップショットを取れるようにしたpgg2moralsGr.java

/**
 * A public goods game simulation defined in
 * "Evolutionary Establishment of Moral and Double Moral Standards through Spatial Interaction"
 * By Dirk Helbing, Attila Szolnoki, Matjaz Perc, Gyorgy Szabo
 *
 **/

import java.awt.*; // uses the abstract windowing toolkit
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class pgg2moralsGr extends JPanel implements Runnable {

    private Thread myTh;
    // private Thread currentThread;
    private boolean halt_;
    pgg2morals game;
    drawPattern2morals draw;

    static int maxSize = 600; // width of window in pixels
    static int size = 200; // lattice size; can be any divisor of maxSize
    static boolean restartCtrl=false;
    /* グラフィック関係変数 */
    JButton startBtn, stopBtn, restartBtn, exitBtn;
    JLabel label_r, label_gamma, label_beta;
    JSlider set_r, set_gamma, set_beta;
    double scale1 = 100.0, scale2 = 50.0, scale_gamma=1000.0; /* スライダーのスケール */

    int mcs,iteration; /* Monte Carlo Step & # of iteration */


  /* コンストラクタ */
  pgg2moralsGr() {
    /* パラメータ初期値 */
    double ini_r = 4.4, ini_gamma = 0.05, ini_beta = 0.1;

    draw = new drawPattern2morals(maxSize, size);  // ゲームのパターン描画オブジェクト

    /* ボタン生成 */
    startBtn = new JButton("start");
    stopBtn = new JButton("stop");
    restartBtn = new JButton("restart");

    exitBtn = new JButton("終了");

    /* スライドバー生成 */
    set_r = new JSlider(JSlider.HORIZONTAL, 0, 600, (int) (ini_r * scale1));
    set_beta = new JSlider(JSlider.HORIZONTAL, 0, 100,
        (int) (ini_beta * scale1));
    set_gamma = new JSlider(JSlider.HORIZONTAL, 0, 100,
        (int) (ini_gamma * scale_gamma));

    /* ラベル生成 */
    label_r = new JLabel(String.valueOf(ini_r));
    label_gamma = new JLabel(String.valueOf(ini_gamma));
    label_beta = new JLabel(String.valueOf(ini_beta));

    /* パネルにスライドバー、ラベルを貼る */
    /* 各パネルに、スライドバーとラベルを横に並べる */
    JPanel panel_r = new JPanel();
    panel_r.add(new JLabel("r"));
    panel_r.add(set_r);
    panel_r.add(label_r);
    JPanel panel_beta = new JPanel();
    panel_beta.add(new JLabel("beta"));
    panel_beta.add(set_beta);
    panel_beta.add(label_beta);
    JPanel panel_gamma = new JPanel();
    panel_gamma.add(new JLabel("gamma"));
    panel_gamma.add(set_gamma);
    panel_gamma.add(label_gamma);

    /* 親パネルにボタンと、スライドバー・ラベル を並べる */
    JPanel p = new JPanel();
    p.setLayout(new GridLayout(8, 1));
    p.add(startBtn);
    p.add(stopBtn);
    p.add(restartBtn);
    p.add(panel_r);
    p.add(panel_gamma);
    p.add(panel_beta);
    p.add(exitBtn);

    add(p, BorderLayout.NORTH);

    /* スライダーやボタンにリスナーをつける */
    set_r.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_r.setText(Double.toString(set_r.getValue() / scale1));
      }
    });
    set_gamma.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_gamma.setText(Double.toString(set_gamma.getValue()
            / scale_gamma));
      }
    });
    set_beta.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_beta.setText(Double.toString(set_beta.getValue() / scale1));
      }
    });
    startBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        /*
         * startボタンが押されたら、ゲームオブジェクトを作成し、 スレッドをスタートさせる
         */
          restartCtrl = false;
        game = new pgg2morals(size);
        game.setParameters(set_gamma.getValue() / scale_gamma,
            set_beta.getValue() / scale1,
            set_r.getValue() / scale1);
        thread_start();
      }
    });
    restartBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
          restartCtrl = true;
          thread_start();
      }
    });
    stopBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        stop();
      }
    });
    exitBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        System.exit(0);
      }
    });
  }

  /* main */
  public static void main(String[] args) {


    // パラメータセットのGUIを作成し、表示
    JFrame setParamFrame = new JFrame("パラメータセット");
    pgg2moralsGr ctr = new pgg2moralsGr();
    setParamFrame.getContentPane().add(ctr, BorderLayout.CENTER);
    setParamFrame.setSize(300, 300);
    setParamFrame.setLocation(600, 20);
    setParamFrame.setVisible(true);

  }

  /* *************** End of Main ******************** */

  /* GUIで操作できるようにrunnableインターフェイスに基づいてスレッドを操作をする */
  public void thread_start() { /* startボタンにより呼び出す */
    halt_ = false;
    myTh = new Thread(this);
    myTh.start(); /* start()によりrun()が実行される */
  }

  public void stop() { /* stopボタンで呼び出す */
    halt_ = true;
    myTh.interrupt();
  }

  public void run() {
    int i, j;

    if(!restartCtrl) { /* restartでなければ、初期化 */
        game.initializePlayers();
        mcs =0;
        iteration =0;
    }

    /* halt_==falseの間、繰り返し */
    while (!halt_) {
        for(iteration=0; iteration<size*size; iteration++) {
      i = (int) (Math.random() * size); // (i,j)をランダムに選んで、
      j = (int) (Math.random() * size); // 戦略アップデートを実行
      if (game.update_strategy(i, j))
          this.draw.colorSquare(i, j, game.s[i][j]);
        }
        mcs++;
        this.draw.showString("Time="+mcs);
        if(mcs!=0 && mcs%10==0) { /* 一定間隔で中断 */
      stop();
        }
    }
  }
}