gpt4 book ai didi

java - Java 中的生命游戏,人口过剩但无法弄清楚原因

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:29:40 25 4
gpt4 key购买 nike

这是作业。我在底部包含了相关代码。

问题:为了让用户调整网格大小,网格现在被绘制得严重过剩。

屏幕截图:“人口过剩”—— http://i.imgur.com/zshAC6n.png“期望人口”- http://i.imgur.com/5Rf6P42.png

背景:这是康威生命游戏的一个版本。在类里面,我们完成了 3 个类:处理游戏逻辑的 LifeState,包含游戏的 JPanel LifePanel,以及创建 JFrame 并添加 LifePanel 的驱动程序。任务是将其开发成具有各种要求的完整 GUI 应用程序。我的解决方案是扩展 JFrame 并在该类中完成我的大部分工作。

在 actionlistener 之外初始化 LifePanel 会产生正常填充,但在 actionlistener 中初始化 LifePanel 会“过度填充”网格。

问题:为什么会出现人口过剩?

生命面板类

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

public class LifePanel extends JPanel implements MouseListener
{
private int row;
private int col;
private int scale;
private LifeState life;
boolean state;
boolean wrap;
int delay;
Timer timer;

public LifePanel(int r, int c, int s, int d)
{
row = r;
col = c;
scale = s;
delay = d;
life = new LifeState(row,col);
Random rnd = new Random();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
life.setCell(i,j,rnd.nextBoolean());
timer = new Timer(delay, new UpdateListener());
setPreferredSize( new Dimension(scale*row, scale*col));
addMouseListener(this);
timer.start();
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
if(life.getCell(i,j))
g.fillRect(scale*i,scale*j,scale,scale);
}

public int getRow() {
return row;
}

public void setRow(int row) {
this.row = row;
}

public int getCol() {
return col;
}

public void setCol(int col) {
this.col = col;
}

public int getScale() {
return scale;
}

public void setScale(int scale) {
this.scale = scale;
}

public int getDelay() {
return delay;

}

public void setDelay(int delay) {
this.delay = delay;
timer.setDelay(delay);
}

public void pauseGame(){
timer.stop();
}
public void playGame(){
timer.restart();
}
public void setInitState(boolean set){
state = set;
if(state){
timer.stop();
}
}
public void setWrap(boolean set){
wrap = set;
if(wrap){
//implement allow wrap
}
}

@Override
public void mouseClicked(MouseEvent e) {
if(state){
int x=e.getX();
int y=e.getY();
boolean isFilled;
isFilled = life.getCell(x,y);
//Test pop-up
JOptionPane.showMessageDialog(this, x+","+y+"\n"+life.getCell(x,y));
if(isFilled){
life.setCell(x,y,false);
}else{
life.setCell(x,y,true);
}
repaint();
}
}


@Override
public void mousePressed(MouseEvent e) {}

@Override
public void mouseReleased(MouseEvent e) {}

@Override
public void mouseEntered(MouseEvent e) {}

@Override
public void mouseExited(MouseEvent e) {}

private class UpdateListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
life.iterate();
repaint();
}
}


}

LifeFrame 类

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

public class LifeFrame extends JFrame implements ActionListener{

JMenuBar menuBar;
JMenu mainMenu, helpMenu;
JMenuItem restartItem, quitItem, helpItem;
JButton stopButton, playButton, pauseButton, startButton;
CardLayout cardLayout = new MyCardLayout();
CardLayout cardLayout2 = new MyCardLayout();
SetupPanel setupPanel; //panel for input
LifePanel gamePanel; //game panel
JPanel controls = new JPanel(); //controls for game
JPanel controls2 = new JPanel(); //controls for input panel
JPanel cardPanel = new JPanel(cardLayout);
JPanel cardPanel2 = new JPanel(cardLayout2);
int gridRow=480;
int gridCol=480;
int scale=1;
int delay=2;
boolean setState = false;
boolean setWrap = false;

public LifeFrame() {
setTitle("Game of Life");
setLayout(new BorderLayout());

//Add the Panels
setupPanel = new SetupPanel();
gamePanel = new LifePanel(gridRow,gridCol,scale,delay);
cardPanel.add(setupPanel, "1");
cardPanel.add(gamePanel, "2");
add(cardPanel, BorderLayout.NORTH);

cardPanel2.add(controls2, "1");
cardPanel2.add(controls, "2");
add(cardPanel2, BorderLayout.SOUTH);
//init menu
menuBar = new JMenuBar();

//button listener setup
stopButton = new JButton("Stop");
pauseButton = new JButton("Pause");
playButton = new JButton("Play");
startButton = new JButton("Start");
stopButton.addActionListener(this);
pauseButton.addActionListener(this);
playButton.addActionListener(this);
startButton.addActionListener(this);
//menu listener setup
restartItem = new JMenuItem("Restart", KeyEvent.VK_R);
quitItem = new JMenuItem("Quit", KeyEvent.VK_Q);
helpItem = new JMenuItem("Help", KeyEvent.VK_H);
restartItem.addActionListener(this);
quitItem.addActionListener(this);
helpItem.addActionListener(this);
//add buttons
controls.add(stopButton);
controls.add(pauseButton);
controls.add(playButton);
controls2.add(startButton);
//build the menus
mainMenu = new JMenu("Menu");
mainMenu.setMnemonic(KeyEvent.VK_M);
helpMenu = new JMenu("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);
menuBar.add(mainMenu);
menuBar.add(helpMenu);
setJMenuBar(menuBar);
//add JMenuItems
restartItem.getAccessibleContext().setAccessibleDescription("Return to setup screen");
mainMenu.add(restartItem);
mainMenu.add(quitItem);
helpMenu.add(helpItem);


this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});

pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
try{
gridRow = setupPanel.getRowSize();
gridCol = setupPanel.getColSize();
scale = setupPanel.getScale();
delay = setupPanel.getDelay();
setWrap = setupPanel.getSetWrap();
setState = setupPanel.getSetState();
}catch (NumberFormatException n){
JOptionPane.showMessageDialog(LifeFrame.this, "Make sure the fields contain only digits and are completed!");
return;
}
if(e.getSource() == pauseButton){
gamePanel.pauseGame();
}else if(e.getSource() == playButton){
gamePanel.playGame();
}else if(e.getSource() == quitItem){
System.exit(0);
}else if(e.getSource() == restartItem || e.getSource() == stopButton){
cardLayout.show(cardPanel, "1");
cardLayout2.show(cardPanel2, "1");
pack();
setLocationRelativeTo(null);
}else if(e.getSource() == helpItem){
String helpText = "Help\nPlease make sure every field is completed and contains only digits\nCurrent Stats:\nGrid Size: "+gamePanel.getRow()+" by "+gamePanel.getCol()+"\nScale: "+ gamePanel.getScale() +"\nDelay: "+gamePanel.getDelay()+"\nManual Initial State: "+setState+"\nEnable Wrapping: "+setWrap;
JOptionPane.showMessageDialog(LifeFrame.this, helpText);
}else if(e.getSource() == startButton){

gamePanel = new LifePanel(gridRow,gridCol,scale,delay);
cardPanel.add(gamePanel, "2");
/*
* Alternate solution, throws array index out of bounds due to array usage in the LifePanel, but properly
* populates the grid.
*
gamePanel.setRow(gridRow);
gamePanel.setCol(gridCol);
gamePanel.setScale(scale);
gamePanel.setDelay(delay);
*/
if(setWrap){
gamePanel.setWrap(true);
gamePanel.playGame();
}else if(setState){
gamePanel.setInitState(true);
}else{
gamePanel.setWrap(false);
gamePanel.setInitState(false);
gamePanel.playGame();
}
gamePanel.repaint();
cardLayout.show(cardPanel, "2");
cardLayout2.show(cardPanel2, "2");
pack();
setLocationRelativeTo(null);
}
}
public static class MyCardLayout extends CardLayout {

@Override
public Dimension preferredLayoutSize(Container parent) {

Component current = findCurrentComponent(parent);
if (current != null) {
Insets insets = parent.getInsets();
Dimension pref = current.getPreferredSize();
pref.width += insets.left + insets.right;
pref.height += insets.top + insets.bottom;
return pref;
}
return super.preferredLayoutSize(parent);
}

public Component findCurrentComponent(Container parent) {
for (Component comp : parent.getComponents()) {
if (comp.isVisible()) {
return comp;
}
}
return null;
}

}
}

感谢您阅读所有这些内容,并提前感谢您提供的任何帮助/建议。

编辑:添加了屏幕截图和改进的问题。

最佳答案

根据您如何初始化 LifePanel

Random rnd = new Random();
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
life.setCell(i,j,rnd.nextBoolean());

你所说的“人口过剩”是预期的状态。上面的代码会将大约 1/2 的单元格设置为“活着”(或“占用”),这就是你的“人口过剩”状态的样子。

“所需人口”屏幕截图包含许多“生命”工件,如“ hive ”、“滑翔机”、“交通灯”等,要么是手动构建的,要么是在最初的 50% 上运行多次迭代的结果随机人口。由于邻近规则,第一代人口占 50% 时,将导致大量大量细胞被彻底清除(“死亡”)。

最重要的是,考虑到在启动时,您的程序不会绘制初始配置。在第一次 repaint() 调用之前至少发生一次迭代。

我认为您的代码根本没有问题,只是您对初始种群的期望。

关于java - Java 中的生命游戏,人口过剩但无法弄清楚原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16048239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com