スナップショット取得用pgg2PunishGr.java

/**
 * A public goods game simulation defined in
 * "Competition of individual and institutional punishments in spatial public goods game"
 * By A. Szolnoki, et. al, Phys. Rev. E84, 046106 (2011)
 *
 **/

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

public class pgg2PunishGr extends JPanel implements Runnable {

  private Thread myTh;
  // private Thread currentThread;
  private boolean halt_;
  pgg2Punishments game;
  drawPattern2Punishments draw;

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

    /* 繰り返しカウンターとスタート/リスタート切り替え変数 */
    int mcs,iteration; /* Monte Carlo Step & # of iteration */
    boolean restartCtrl = false;

  /* コンストラクタ */
  pgg2PunishGr() {
    /* パラメータ初期値 */
    double ini_r = 2.1, ini_m = 1.0, ini_gamma = 1.0, ini_beta = 2.5, ini_K = 0.5;

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

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

    /* スライドバー生成 */
    set_r = new JSlider(JSlider.HORIZONTAL, 0, 300, (int) (ini_r * scale1));
    set_beta = new JSlider(JSlider.HORIZONTAL, 0, 300,
        (int) (ini_beta * scale1));
    set_gamma = new JSlider(JSlider.HORIZONTAL, 0, 300,
        (int) (ini_gamma * scale1));
    set_K = new JSlider(JSlider.HORIZONTAL, 0, 100, (int) (ini_K * scale2));
    set_m = new JSlider(JSlider.HORIZONTAL, 0, 100, (int) (ini_m * scale1));

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

    /* パネルにスライドバー、ラベルを貼る */
    /* 各パネルに、スライドバーとラベルを横に並べる */
    JPanel panel_K = new JPanel();
    panel_K.add(new JLabel("K"));
    panel_K.add(set_K);
    panel_K.add(label_K);
    JPanel panel_m = new JPanel();
    panel_m.add(new JLabel("m"));
    panel_m.add(set_m);
    panel_m.add(label_m);
    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(9, 1));
    p.add(startBtn);
    p.add(stopBtn);
    p.add(restartBtn);
    p.add(panel_K);
    p.add(panel_m);
    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()
            / scale1));
      }
    });
    set_beta.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_beta.setText(Double.toString(set_beta.getValue() / scale1));
      }
    });
    set_K.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_K.setText(Double.toString(set_K.getValue() / scale2));
      }
    });
    set_m.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        label_m.setText(Double.toString(set_m.getValue() / scale1));
      }
    });
    startBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        /*
         * startボタンが押されたら、ゲームオブジェクトを作成し、 スレッドをスタートさせる
         */
          restartCtrl = false;
        game = new pgg2Punishments(size);
        game.setParameters(set_gamma.getValue() / scale1,
            set_beta.getValue() / scale1,
            set_r.getValue() / scale1, set_K.getValue() / scale2,
            set_m.getValue() / scale1);
          restartCtrl = false;
        thread_start();
      }
    });

    restartBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        /*
         * restartボタンが押されたら、初期化せず再開
         */
        game.setParameters(set_gamma.getValue() / scale1,
            set_beta.getValue() / scale1,
            set_r.getValue() / scale1, set_K.getValue() / scale2,
            set_m.getValue() / scale1);
        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("パラメータセット");
    pgg2PunishGr ctr = new pgg2PunishGr();
    setParamFrame.getContentPane().add(ctr, BorderLayout.CENTER);
    setParamFrame.setSize(300, 350);
    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;
    // int dummy;

    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==10) this.draw.saveImage("temp.png","png");
        if(mcs!=0 && mcs%10==0) { /* 一定間隔で中断 */
      stop();
        }
    }
  }
}