【问题标题】:How do I add a feature where I can get the generation in my game of life program?如何添加可以在我的生命游戏程序中获取生成的功能?
【发布时间】:2017-08-13 14:04:57
【问题描述】:

我正在尝试让我的程序在单元格更改其形式的每个步骤中显示(首先在控制台中测试)计数。因此,计数应该从 0 开始,并在每次单元格更改其形式时递增。我试过这个,使用count++但是它不会增加1,而是给我随机数。任何帮助都感激不尽。

import java.awt.Color;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Image;
import java.awt.Graphics;
import javax.swing.SwingUtilities;

public class GameOfLife extends javax.swing.JFrame {

final int wid = 100, hei = 50;
public static int count;
boolean[][] currentMove = new boolean[hei][wid], nextMove = new boolean[hei][wid];
boolean play;
Image offScrImg;
Graphics offScrGraph;

public GameOfLife() {
    initComponents();
    offScrImg = createImage(jPanel1.getWidth(), jPanel1.getHeight());
    offScrGraph = offScrImg.getGraphics();
    Timer time = new Timer();
    TimerTask task = new TimerTask(){
        public void run(){
            if(play){
                System.out.println(count);
                for(int i = 0; i < hei; i++){
                    for(int j = 0; j < wid; j++){
                        nextMove[i][j] = decide(i,j);

                    }
                }
                for(int i = 0; i < hei; i++){
                    for(int j = 0; j < wid; j++){
                        currentMove[i][j] = nextMove[i][j];

                    }
                }
                repain();
            }
        }
    };
    time.scheduleAtFixedRate(task, 0, 100);
    repain();
}

private boolean decide(int i, int j){
    int neighbors = 0;

    // top-left row-1,col-1

    if (currentMove[getTopRow(i - 1)][getLeftCol(j - 1)]) neighbors++;  //Uses getTopRow and getLeftCol methods to determine the indices of the top left cell

    // left row,col-1
    if (currentMove[i][getLeftCol(j - 1)]) neighbors++;

    // bottom left row+1,col-1
    if (currentMove[getBottomRow(i + 1)][getLeftCol(j - 1)] ) neighbors++;

    // bottom row+1,col
    if (currentMove[getBottomRow(i + 1)][j]) neighbors++;

    // bottom right row+1,col+1
    if (currentMove[getBottomRow(i + 1)][getRightCol(j + 1)]) neighbors++;

    // right row,col+1
    if (currentMove[i][getRightCol(j + 1)]) neighbors++;

    // top-right row-1,col+1
    if (currentMove[getTopRow(i - 1)][getRightCol(j + 1)])neighbors++;

    // top row-1, col
    if(currentMove[getTopRow(i - 1)][j]) neighbors++;


    if(neighbors == 3) {       
        count++;
        return true;                
    }
    if(currentMove[i][j] && neighbors == 2){   
        count++;
        return true;         
    }
    return false;
}
private int getLeftCol(int neighbourCol) {
    return neighbourCol < 0 ? (wid-1) : neighbourCol;   //If the index of leftCol is less than 0, it uses the right most col (columns - 1)
}

private int getRightCol(int neighbourCol) {
    return neighbourCol > (wid-1) ? 0 : neighbourCol;
}

private int getTopRow(int neighbourRow) {
    return neighbourRow < 0 ? (hei - 1) : neighbourRow; //If the index of topRow is less than 0, it uses the bottom last row (rows - 1)
}

private int getBottomRow(int neighbourRow) {
    return neighbourRow > (hei - 1) ? 0 : neighbourRow;
}

private void repain(){
    offScrGraph.setColor(Color.RED);
    offScrGraph.fillRect(0, 0, jPanel1.getWidth(), jPanel1.getHeight());
    for(int i = 0 ; i < hei ; i++){
        for(int j = 0 ; j < wid; j++){
            if(currentMove[i][j]){
                offScrGraph.setColor(Color.GREEN);
                int x = j * jPanel1.getWidth()/wid;
                int y = i * jPanel1.getHeight()/hei;
                offScrGraph.fillRect(x, y, jPanel1.getWidth()/wid, jPanel1.getHeight()/hei);
            }
        }
    }
    offScrGraph.setColor(Color.BLACK);
    for(int i = 1; i < hei;i++){
        int y = i * jPanel1.getHeight()/hei;
        offScrGraph.drawLine(0, y, jPanel1.getWidth(), y);
    }
    for(int j = 1; j < wid;j++){
        int x = j * jPanel1.getWidth()/wid;
        offScrGraph.drawLine(x, 0, x, jPanel1.getHeight());
    }
    jPanel1.getGraphics().drawImage(offScrImg, 0, 0, jPanel1);
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jButton1 = new javax.swing.JButton();
    jButton2 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setBackground(new java.awt.Color(102, 102, 102));
    jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
        public void mouseDragged(java.awt.event.MouseEvent evt) {
            jPanel1MouseDragged(evt);
        }
    });
    jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            jPanel1MouseClicked(evt);
        }
    });
    jPanel1.addComponentListener(new java.awt.event.ComponentAdapter() {
        public void componentResized(java.awt.event.ComponentEvent evt) {
            jPanel1ComponentResized(evt);
        }
    });

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
            );
    jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 293, Short.MAX_VALUE)
            );

    jButton1.setText("Play");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    jButton2.setText("Reset");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton2ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 323, Short.MAX_VALUE)
                                    .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addContainerGap())
            );
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton1)
                            .addComponent(jButton2))
                    .addContainerGap())
            );

    pack();
}// </editor-fold>//GEN-END:initComponents

private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel1MouseClicked

}//GEN-LAST:event_jPanel1MouseClicked

private void jPanel1ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel1ComponentResized
    offScrImg = createImage(jPanel1.getWidth(), jPanel1.getHeight());
    offScrGraph = offScrImg.getGraphics();
    repain();
}//GEN-LAST:event_jPanel1ComponentResized

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
    play = !play;
    if(play) jButton1.setText("Pause");
    else jButton1.setText("Play");
    repain();
}//GEN-LAST:event_jButton1ActionPerformed

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
    currentMove = new boolean[hei][wid];
    repain();
}//GEN-LAST:event_jButton2ActionPerformed

private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel1MouseDragged
    int j = wid * evt.getX() / jPanel1.getWidth();
    int i = hei * evt.getY() / jPanel1.getHeight();
    if(SwingUtilities.isLeftMouseButton(evt)){
        currentMove[i][j] = true;
    }else currentMove[i][j] = false;
    repain();
}//GEN-LAST:event_jPanel1MouseDragged

public static void main(String args[]) {
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(GameOfLife.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new GameOfLife().setVisible(true);
        }
    });
}

// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JPanel jPanel1;
// End of variables declaration//GEN-END:variables
}

【问题讨论】:

  • @AndrewThompson 完成
  • 我使用了 repain,因为已经有一个内置的方法叫做 repaint。所以不想发生冲突。
  • 不错的编辑。 :) BTW - 没有仔细查看您的代码,但检查了this code 可以在几行代码中实现生成计数器。看看对你有帮助吗?
  • @AndrewThompson 是的,请。感谢您的帮助:)

标签: java swing iteration increment conways-game-of-life


【解决方案1】:

这就是使用related code example 的方法。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

public class GameOfLife extends JPanel {

    private int row, col;
    private boolean isLiving;
    private static int generation = 0;

    public static Random random = new Random();

    public GameOfLife(int r, int c) {
        this.row = r;
        this.col = c;
        MouseListener listener = new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                isLiving = !isLiving;
                repaint();
            }
        };
        this.addMouseListener(listener);
        isLiving = random.nextBoolean();
    }

    public boolean isAlive(int neighbors) {
        boolean alive = false;
        if (this.isLiving) {
            if (neighbors < 2) {
                alive = false;
            } else if (neighbors == 2 || neighbors == 3) {
                alive = true;
            } else if (neighbors > 3) {
                alive = false;
            }
        } else {
            if (neighbors == 3) {
                alive = true;
            }
        }
        return alive;
    }

    public void setAlive(boolean alive) {
        isLiving = alive;
    }

    public boolean isLiving() {
        return this.isLiving;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (this.isLiving) {
            g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
        } else {
            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
        }
    }

    public static void main(String[] args) {
        final int s = 40;
        JPanel ui = new JPanel(new BorderLayout(4, 4));
        final JLabel generationLabel = new JLabel("0", JLabel.CENTER);
        ui.add(generationLabel, BorderLayout.PAGE_START);

        final GameOfLife[][] biosphere = new GameOfLife[s][s];
        final JPanel gui = new JPanel(new GridLayout(s, s, 2, 2));
        ui.add(gui);
        for (int ii = 0; ii < s; ii++) {
            for (int jj = 0; jj < s; jj++) {
                GameOfLife cell = new GameOfLife(ii, jj);
                cell.setPreferredSize(new Dimension(10, 10));
                gui.add(cell);
                biosphere[ii][jj] = cell;
            }
        }

        ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                boolean[][] living = new boolean[s][s];
                for (int ii = 0; ii < s; ii++) {
                    for (int jj = 0; jj < s; jj++) {
                        int top = (jj > 0 ? jj - 1 : s - 1);
                        int btm = (jj < s - 1 ? jj + 1 : 0);
                        int lft = (ii > 0 ? ii - 1 : s - 1);
                        int rgt = (ii < s - 1 ? ii + 1 : 0);
                        int neighbors = 0;
                        if (biosphere[ii][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[ii][btm].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][btm].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[lft][jj].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][jj].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][top].isLiving()) {
                            neighbors++;
                        }
                        if (biosphere[rgt][btm].isLiving()) {
                            neighbors++;
                        }
                        living[ii][jj] = biosphere[ii][jj].isAlive(neighbors);
                    }
                }
                for (int ii = 0; ii < s; ii++) {
                    for (int jj = 0; jj < s; jj++) {
                        biosphere[ii][jj].setAlive(living[ii][jj]);
                    }
                }
                generationLabel.setText("Generation: " + generation++);
                gui.repaint();
            }
        };

        Timer timer = new Timer(50, al);
        timer.start();

        JOptionPane.showMessageDialog(null, ui);
        timer.stop();
    }
}

【讨论】:

    【解决方案2】:

    我认为您一定会遇到错误。你永远不会初始化你的计数器。 改变

    public static int count;
    

    public static int count = 0;
    

    试试会发生什么

    【讨论】:

      【解决方案3】:

      这是我之前实现的方式,我使用 2 个布尔数组来检查电路板的当前状态并将其保存到新数组中,然后将新数组值复制到当前状态数组并重新绘制电路板:

      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.GridLayout;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.MouseEvent;
      import java.awt.event.MouseListener;
      import java.util.Random;
      
      import javax.swing.BorderFactory;
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JSlider;
      import javax.swing.SwingUtilities;
      import javax.swing.Timer;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;
      
      public class GameOfLife {
      
          public static final int ROWS = 30;
          public static final int COLS = 30;
      
          private JFrame frame;
          private JPanel pane;
          private Cell[][] cells;
          private boolean[][] currentState;
          private boolean[][] newState;
          private boolean isAlive = false;
          private JButton startButton;
          private JButton stopButton;
          private Timer timer;
          private JSlider slider;
          private JLabel label;
          private int interations;
      
          public static void main(String[] args) {
              SwingUtilities.invokeLater(() -> new GameOfLife().createAndShowGui());
          }
      
          public void randomGeneration() {
              Random r = new Random();
              for (int i = 0; i < ROWS; i++) {
                  for (int j = 0; j < COLS; j++) {
                      currentState[i][j] = r.nextBoolean();
                      cells[i][j].setAlive(currentState[i][j]);
                  }
              }
          }
      
          public void createAndShowGui() {
              frame = new JFrame(getClass().getSimpleName());     
      
              slider = new JSlider(JSlider.HORIZONTAL, 0, 1000, 500);
      
              slider.addChangeListener(new ChangeListener() {
                  @Override
                  public void stateChanged(ChangeEvent e) {
                      timer.setDelay(slider.getValue());
                  }
              });
      
              label = new JLabel("Number of iterations: " + interations);
      
              timer = new Timer(slider.getValue(), listener);
              timer.setInitialDelay(slider.getValue());
      
              pane = new JPanel(new GridLayout(ROWS, COLS));
      
              cells = new Cell[ROWS][COLS];
              currentState = new boolean[ROWS][COLS];
              newState = new boolean[ROWS][COLS];
      
              startButton = new JButton("Start");
              stopButton = new JButton("Stop");
      
              for (int i = 0; i < ROWS; i++) {
                  for (int j = 0; j < COLS; j++) {
                      currentState[i][j] = false;
                      newState[i][j] = false;
      
                      isAlive = currentState[i][j];
                      cells[i][j] = new Cell(isAlive);
      
                      cells[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
                      cells[i][j].addMouseListener(mouseListener);
                      pane.add(cells[i][j]);
                  }
              }
      
              startButton.addActionListener(listener);
              stopButton.addActionListener(listener);
      
              frame.add(slider, BorderLayout.NORTH);
              frame.add(pane);
              frame.add(startButton, BorderLayout.WEST);
              frame.add(stopButton, BorderLayout.EAST);
              frame.add(label, BorderLayout.SOUTH);
      
              randomGeneration();
      
              frame.pack();
              frame.setVisible(true);
      
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setLocationRelativeTo(null);
          }
      
          public void updateState(int i, int j) {
              currentState[i][j] = !currentState[i][j];
      
              cells[i][j].setAlive(currentState[i][j]);
              cells[i][j].repaint();
          }
      
          ActionListener listener = new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                  if (e.getSource().equals(startButton)) {
                      if (!timer.isRunning()) {
                          timer.start();
                      } else {
                          timer.restart();
                      }
                  } else if (e.getSource().equals(stopButton)) {
                      timer.stop();
                  } else {
                      for (int i = 0; i < ROWS; i++) {
                          for (int j = 0; j < COLS; j++) {
                              int neighbors = 0;
      
                              if (i - 1 > 0) {
                                  if (j - 1 > 0) {
                                      if (currentState[i - 1][j - 1]) {
                                          neighbors++;
                                      }
                                  }
                                  if (j + 1 < COLS) {
                                      if (currentState[i - 1][j + 1]) {
                                          neighbors++;
                                      }
                                  }
                                  if (currentState[i - 1][j]) {
                                      neighbors++;
                                  }
                              }
                              if (i + 1 < ROWS) {
                                  if (j - 1 > 0) {
                                      if (currentState[i + 1][j - 1]) {
                                          neighbors++;
                                      }
                                  }
                                  if (j + 1 < COLS) {
                                      if (currentState[i + 1][j + 1]) {
                                          neighbors++;
                                      }
                                  }
                                  if (currentState[i + 1][j]) {
                                      neighbors++;
                                  }
                              }
                              if (j - 1 > 0) {
                                  if (currentState[i][j - 1]) {
                                      neighbors++;
                                  }
                              }
                              if (j + 1 < COLS) {
                                  if (currentState[i][j + 1]) {
                                      neighbors++;
                                  }
                              }
      
                              if (currentState[i][j]) {
                                  if (neighbors < 2 || neighbors >= 4) {
                                      newState[i][j] = false;
                                  } else {
                                      newState[i][j] = true;
                                  }
                              } else {
                                  if (neighbors == 3) {
                                      newState[i][j] = true;
                                  }
                              }
                          }
                      }
      
                      for (int i = 0; i < ROWS; i++) {
                          for (int j = 0; j < COLS; j++) {
                              currentState[i][j] = newState[i][j];
                              cells[i][j].setAlive(currentState[i][j]);
                              cells[i][j].revalidate();
                              cells[i][j].repaint();
                          }
                      }
      
                      interations++;
                      label.setText("Number of iterations: " + interations);
                      pane.revalidate();
                      pane.repaint();
                  }
              }
          };
      
          MouseListener mouseListener = new MouseListener() {
      
      
      
              @Override
              public void mouseReleased(MouseEvent e) {
      
              }
      
              @Override
              public void mousePressed(MouseEvent e) {
      
              }
      
              @Override
              public void mouseExited(MouseEvent e) {
      
              }
      
              @Override
              public void mouseEntered(MouseEvent e) {
      
              }
      
              @Override
              public void mouseClicked(MouseEvent e) {
                  for (int i = 0; i < ROWS; i++) {
                      for (int j = 0; j < COLS; j++) {
                          if (e.getSource().equals(cells[i][j])) {
                              updateState(i, j);
                              break;
                          }
                      }
                  }
              }
          };
      }
      
      @SuppressWarnings("serial")
      class Cell extends JPanel {
          private boolean isAlive;
      
          public Cell(boolean isAlive) {
              this.isAlive = isAlive;
          }
      
          public boolean isAlive() {
              return isAlive;
          }
      
          public void setAlive(boolean isAlive) {
              this.isAlive = isAlive;
          }
      
          @Override
          public Dimension getPreferredSize() {
              return new Dimension(20, 20);
          }
      
          @Override
          public Color getBackground() {
              return isAlive ? Color.GREEN : Color.GRAY;
          }
      }
      

      它还包括一个JSlider 来管理处理速度:

      玩得开心,请注意我使用了Swing Timer,而不是您正在使用的Util Timer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 2013-11-30
        • 1970-01-01
        • 1970-01-01
        • 2020-09-19
        • 2016-10-17
        • 1970-01-01
        相关资源
        最近更新 更多