Java 中的生命游戏,人口过剩但不明白为什么

2024-04-26

这是家庭作业。我在底部添加了相关代码。

Problem:在试图允许用户调整网格大小时,网格现在被绘制得严重过度填充。

截图:“人口过剩”——https://i.stack.imgur.com/0Ilrq.png https://i.stack.imgur.com/0Ilrq.png“所需人口”-https://i.stack.imgur.com/FZD38.png https://i.stack.imgur.com/FZD38.png

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

在动作监听器之外初始化 LifePanel 会产生正常的填充,但在动作监听器中初始化 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();
    }
}


}

生命框架类

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 的单元格设置为“活动”(或“占用”),这就是“人口过多”状态的样子。

“所需种群”屏幕截图包含许多“生命”工件,例如“蜂箱”、“滑翔机”、“红绿灯”等,并且要么是手动构建的,要么是在最初 50% 的随机种群上运行多次迭代的结果。由于邻近规则,第一代占据了 50% 的人口,将导致许多很多细胞的大规模清除(“死亡”)。

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

我认为你的代码根本没有被破坏,只是你对初始人口的期望。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中的生命游戏,人口过剩但不明白为什么 的相关文章

  • Java 中如何将 long 转换为 int?

    Java 中如何将 long 转换为 int 在 Java 8 中更新 Math toIntExact value 原答案 简单的类型转换应该可以做到 long l 100000 int i int l 但请注意 较大的数字 通常大于214
  • Maven:在项目之间共享源

    我有两个项目 它们是一个共同父项目的子项目 还有一个生成器项目和生成器对应的maven插件项目 此外 两个子项目都使用相同的输入文件 该文件用于代码生成 parent pom child1 jar src main generator in
  • Java 拖放图像并在拖动时显示图像缩略图

    我有一个带有图像节点的网格布局 我想在我的应用程序中添加 dnd 功能 例如 当我将图像节点拖放到目标 JPanel 时 进行一些操作 例如以原始大小显示 删除等 我已经实现了这与一种使用 Transferhandler 的方法和一种使用
  • 我的代码中出现 ArrayIndexOutOfBoundsException 的原因是什么?

    我正在 Java 中实现凸包的格雷厄姆扫描算法 我在运行代码时收到此错误 对于输入字符串 10 18 Exception in thread main java lang ArrayIndexOutOfBoundsException 0 a
  • C# 到 Java:Base64String、MemoryStream、GZipStream

    我有一个在 NET 中压缩的 Base64 字符串 我想将其转换回 Java 中的字符串 我正在寻找一些与 C 语法等效的 Java 语法 特别是 Convert FromBase64String 内存流 压缩流 这是我想要转换的方法 pu
  • 何时使用环境变量与系统属性?

    我想知道以下哪种方法是首选方法 我们可以将事情设置为APP HOME path to file export in profile或类似的东西 并将其访问为System getenv APP HOME 或者 也可以使用属性作为 DAPP H
  • Java俄罗斯方块旋转

    我知道这个问题已经被问了很多 但我想知道如何旋转俄罗斯方块 我已经做了一个又长又糟糕的解决方案 大约 170 行代码 但应该有更简单的方法来做到这一点 我的俄罗斯方块由 4 个块组成 它们都知道它们在矩阵中的位置 行和列 Matrix本身是
  • Apache POI - JAVA - 迭代 Excel 中的列

    这里是java新手 我正在编写一个代码 该代码读取 Excel 文件 查看列中的单元格 然后编写如下表所示的内容 我有一个 Excel 文件 如下所示 col1 col2 col3 col4 row1 2 3 1 1 w row2 3 2
  • 如何配置jackson属性命名策略?

    此代码不起作用 Configuration public class RepositoryRestMvcConfig extends RepositoryRestMvcConfiguration Bean Override public O
  • 在 JSON 转换为 CSV 期间保持 JSON 键的顺序

    我正在使用此处提供的 JSON 库http www json org java index html http www json org java index html为了将 json 字符串转换为 CSV 但我遇到的问题是 转换后键的顺序
  • Java中的字符算术

    在玩的过程中 我遇到了一些对我来说似乎很奇怪的事情 以下不是有效的 Java 代码 char x A x x 1 possible loss of precision 因为其中一个操作数是整数 所以另一个操作数被转换为整数 结果无法分配给字
  • 当从搜索表单动态构建 WHERE 子句时,如何防止 SQL 注入?

    我知道在 Java 中保护 SQL 查询免受 SQL 注入的唯一真正正确的方法是使用准备好的语句 然而 这样的语句要求基本结构 选择的属性 连接的表 WHERE条件的结构 不会改变 我这里有一个 JSP 应用程序 其中包含一个带有大约十几个
  • 如果表不存在,如何使用 Derby Db 创建表

    我是新来的apache derby我似乎无法工作 CREATE TABLE IF NOT EXISTS table1 可以实现MySql等等我得到了 Syntax error Encountered NOT at line 1 column
  • 需要在 java api 中的 Solr 搜索中搜索文本及其周围的几行

    我正在使用 solr 7 7 2 并且我使用 solrj 在 Solr 中编写了一个 Java 程序 该程序在一个巨大的文本文件中搜索单词 我使用以下代码来显示代表整个文本的搜索结果 SolrQuery params new SolrQue
  • 如何将 Java 字节数组转换为 Scala 字节数组?

    我是 Scala 新手 目前正在从事一个涉及 Java 和 Scala 模块的项目 现在我想使用 byte 类型的参数从 Java 调用 Scala 方法 Scala 方法的签名为 def foo data Array Byte Java
  • JVM 是否会内联对象的实例变量和方法?

    假设我有一个非常紧密的内部循环 每次迭代都会访问和改变一个簿记对象 该对象存储有关算法的一些简单数据 并具有用于操作它的简单逻辑 簿记对象是私有的和最终的 并且它的所有方法都是私有的 最终的和 inline 下面是一个示例 Scala 语法
  • 尝试将过滤器添加到 Grizzly+Jersey 应用程序时出现问题

    我有这个服务器初始化类 package magic app main import org glassfish grizzly http server HttpServer import org glassfish jersey grizz
  • 如何在 JUnit5 中为测试套件设置自定义测试执行顺序?

    我在 JUnit5 上进行了大量测试 并在多个线程中并行运行 还有有关每次测试时间的信息 我想在最长的测试开始时运行 并将最快的测试留在最后以优化公共执行时间 我还没有找到在 JUnit5 中执行此操作的方法 版本中5 4有一个org ju
  • GAE、JPA、XG 事务、实体组过多异常

    我知道 GAE 上的 XG 交易有 5 个实体组的限制 但我认为我在一项交易中仅使用 3 个组 商品 类别 商品类别 但仍然遇到此异常 引起原因 java lang IllegalArgumentException 在单个事务中对太多实体组
  • “您的安全设置已阻止本地应用程序运行”Java 8

    我正在尝试在 Chrome 窗口中运行一个小小程序 但收到错误消息 我确实看到所有回复都告诉我将安全性更改为中级 但版本 8 中不存在该选项 到目前为止 几个小时的谷歌搜索和向同学寻求帮助没有带来任何进展 有人可以建议一下吗 Medium在

随机推荐

  • 从 uiwebview Xcode 获取选定的文本

    我有一个UIWebView从加载文本htmlString 我需要当用户选择文本的一部分并按下按钮时 我将能够提取它以便在其他地方使用它 所以我使用以下代码 The JS File NSString filePath NSBundle mai
  • 根据单元格位置将选择性字段从 Excel 批量插入到 SQL

    我有一个 SSIS 包 我必须从 Excel 工作表中选择一些值并将它们插入到 SQL Server 数据库表中 我是通过执行 sql 任务来完成的 这些是步骤 从映射表中选择所有记录 单元格位置是动态的 因此将其保留在 SQL 表中 大约
  • 如何使用 Keras 将图像文件夹转换为 X 和 Y 批次?

    假设我有一个图像文件夹 例如 PetData Dog images Cat images 我如何将其转换为 x train y train x test y test 格式 我看到这种格式广泛用于 MNIST 数据集 如下所示 mnist
  • 如何与多个 ViewModel 共享多个 ObservableCollections?

    我正在编写一个有 4 个视图的程序 公司视图 会员查看 周视图 and 报告查看 每个都有对应的ViewModel和Model 我使用 PRISM BindableBase 来创建 ViewModel 数据绑定正确 公司视图模型包含一个对象
  • 如何使用 gliderlabs/alpine:3.3 在 Dockerfile 中设置时区

    我的 Dockerfile 是 FROM gliderlabs alpine 3 3 RUN set x buildDeps python dev py pip build base apk update add python py lxm
  • WPF 将“菜单”键称为什么?

    我正在查看此处定义的键 http msdn microsoft com en us library system windows input key aspx http msdn microsoft com en us library sy
  • javascript - 将字符串与正则表达式数组进行匹配

    JavaScript 中有没有一种方法可以获取字符串与正则表达式数组的匹配的布尔值 示例如下 其中 if 语句代表我想要实现的目标 var thisExpressions something something else and somet
  • Ruby:检查字符串是否可以转换为整数[重复]

    这个问题在这里已经有答案了 可能的重复 使用 Ruby 测试字符串是否基本上是引号中的整数 https stackoverflow com questions 1235863 test if a string is basically an
  • Vim NerdCommenter:在 vimrc 中添加新文件类型

    有没有办法在 vimrc 中为 NerdCommenter 定义新的文件类型注释 它已经可以工作了 但是如果我可以将其直接放入 vimrc 中 备份配置会更容易 Thanks NERDCommenter 能够解析commentstring选
  • 为什么我的 git 自动更新 Expect 脚本不起作用?

    我想制作一个脚本来更新我所有的 GitHub 存储库 我只需要输入我的用户名和密码 脚本将遍历存储库列表 调用git push并通过补充 Expect 脚本提供必要的信息 这是我的 bash 脚本 bin bash echo Updatin
  • 释放保留视图的最佳实践?

    这是释放保留的视图的正确 最好 方法吗 viewDidLoad 在 iOS 4 x 或更低版本中 还有什么需要考虑的吗 void viewDidUnload super viewDidUnload self releaseViews voi
  • VSTS 构建已过期

    我创建了一个拉取请求 它触发构建并且构建成功 但一段时间后我的构建状态更改为 构建已过期 因此要完成拉取请求 我需要再次触发它 所以问题是 为什么会发生这种情况以及如何避免构建过期 构建过期 是分支机构政策的一个特点 设置构建到期时间 以确
  • 是否可以将 scipy CSR 矩阵的 dtype 转换为 NPY_FLOAT?

    我有一个 scipy CSR 矩阵 它是由 COO 矩阵构建的 如下所示 coord mat coo matrix data row col dtype np float64 它被用作具有底层 C 实现的库的输入 我相信我的矩阵的 dtyp
  • Mysql AVG 忽略零

    我需要对一列执行平均值 但我知道该列中的大多数值都为零 在所有可能的行中 只有两行可能具有正值 我如何告诉 mySQL 忽略零并仅平均实际值 假设您可能不想完全排除此类行 也许它们在您想要聚合的其他列中具有值 SELECT AVG NULL
  • 在 html 文档中,使用高度和宽度标签调整图像大小是一种不好的做法吗?

    如果我有一个徽标图像 并且我想在另一个需要较小尺寸的页面上使用它 我的直觉是创建一个新图像 并使用图形编辑器调整大小 但是 我听说如果我参考原始图像并通过更改图像标签中的高度和宽度来使用浏览器调整其大小 对用户来说会更好 所以我问大家 这里
  • XDocument.Save() 无法访问文件

    希望我能够得到一些帮助来解决一个令人恼火的问题 我似乎无法在任何地方找到明确的答案 我使用 XDocument 对象将数据附加到 xml 文档 然后使用 xDoc save path 覆盖现有文件 但由于某种原因 我第一次运行代码时会抛出错
  • Grails 与 MongoDB、对象 id 和脚手架

    我使用集成测试和 Grails 脚手架将数据写入 mongoDB 数据库时遇到问题 当尝试从 列表 类型页面中选择域实例时 我收到错误 未找到 id null 的 域名 我确信这是因为 Grails url controller actio
  • XML 站点地图从 url 标记中删除 xmlns

    我正在使用下面的行来生成站点地图 但谷歌说有一个错误 我知道错误 但我无法弄清楚如何删除标签 THe code using System Xml Linq Layout null var urls new List
  • 从霍夫线中选择线

    I m using Hough Lines to do corner detection for this image i plan to find the intersection of the lines as the corner T
  • Java 中的生命游戏,人口过剩但不明白为什么

    这是家庭作业 我在底部添加了相关代码 Problem 在试图允许用户调整网格大小时 网格现在被绘制得严重过度填充 截图 人口过剩 https i stack imgur com 0Ilrq png https i stack imgur c