gpt4 book ai didi

java - 复制康威生命游戏的尝试无法扩展或正常运行

转载 作者:行者123 更新时间:2023-12-02 09:30:20 25 4
gpt4 key购买 nike

如果您不知道康威的生命游戏是什么,请查看此内容,这是一个零玩家游戏,并且是一种细胞自动化。 https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

我需要帮助调试代码中的以下问题。如果有必要,我可以编辑这个问题以包含我的程序的旧版本,这些版本不打算扩展。

我还将接受改进我的程序的提示,包括(但不限于)时间效率(但是偏离主题,因为这不是主要问题)以及现有方法的错误使用。 (我的paint()方法)

Problems:

Examine Glider A in image 1. (Expected behavior) The whole point of the program was to make the cells shrink in the JFrame and add another row or column of dead cells to the ArrayList<ArrayList<Boolean>> grid. This glider, unfortunately does not cause this to happen. Instead, the result (Unexpected behavior) was that it simply "flattened into a square" as shown in image 2 (the square marked with an A).

Examine Glider B in image 1. (Expected behavior) Seeing the results Glider A in image 1 made me think that glider B would end the same. However, this is not remotely true. Look at glider B in image 2. It, for some reason, does not even reach the border. (Unexpected)

这个程序的用途和目的:康威的生命游戏是在无限的 2D 平面上,所以我想复制这个。我的其他程序使用固定的数组大小,但这个使用嵌套的ArrayList来扩展,并且真正是无限的(直到内存限制到来)

不幸的是,这个扩展程序根本无法扩展边界。 (边框实际上比看起来要小。基本上,(假装我的 ArrayList> 网格是一个数组)grid[0][0 to grid.length-1] 包括、grid[grid.length-1][0 to grid.length-1] 包括、grid[1 to grid.length-1][0] 包括、grid[1 to grid.length-1][grid.length-1] 包括。)而不是执行指定的操作为了腾出空间,图 1 中的滑翔机 A 压平了边框。 (边框位于单元格网格下方,其中不存在灰线)

图片 1 enter image description here图片 2 enter image description here

这些图像相互对应;图 1 中的滑翔机 A 标题产生了图 2 中的正方形,同时标记为 A。如果您在代码注释中看到任何描述“第 74 行”、指向“第 74 行”的单词或类似“UP”(没有任何其他含义)的单词,请告诉我,以便我删除它们。这是一个单独的、已经修复的错误。

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Expansion {
static int delay = 50;
static SquarePaint sp = new SquarePaint();
static int K = 75; // An integer used below to create the starting setup for the grid.
static{
// 001 101 011
boolean[][] array = new boolean [300][200];
// array[30][30]
array[K][K+2] = true;
array[K+1][K] = true;
array[K+1][K+2] = true;
array[K+2][K+1] = true;
array[K+2][K+2] = true;
sp.define(array); // Uses array to make first setup
}
public static void main (String[] args){
// It is possible to put this information in a constructor instead
JFrame j = new JFrame();
j.add(sp); // Must add a custom paint component overriding the paint component,
//a class could and will do this
j.setVisible(true);
j.setSize(2000, 1000);
j.setResizable(false);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static class SquarePaint extends Component{
static boolean VALUE = false;
public static final int screenX = 1000, screenY = 500;
static int cellSize = 5;
int cellsX = screenX / cellSize, cellsY = screenY / cellSize, frames = 0;

ArrayList<ArrayList<Boolean>> grid = new ArrayList<ArrayList<Boolean>>(); ////
Timer timer = new Timer(delay, new ActionListener(){
@Override
public void actionPerformed(ActionEvent A) {
//UPDATE FUNCTION
frames++;
boolean [][] oldGrid = new boolean[cellsX][cellsY];
for(int i=0; i<cellsX && i<grid.get(1).size(); i++){
for(int j=0; j<cellsY && j<grid.get(1).size(); j++){
oldGrid[i][j] = grid.get(i).get(j); // <<Line 74>><<Line 74>><<Line 74>>

}
}
/* These are notes
* How would I:
* Expand LinkedLists, for example
(Grid in a picture, 0 = variable, + = new cell)
0 0 0 +
0 0 0 +
0 0 0 +
0 0 0 +
* Adjust existing variables (and poorly coded methods if they exist) to suit this new change
*/
for(int i=1; i<cellsX-2; i++) {
for(int j=1; j<cellsY-2; j++) { // TODO
// System.out.println(i + " " + j);
int nearbyCells = nearbyCells(oldGrid, i, j);
/////////////////////////////////////////////
if(oldGrid[i][j]){
// If the cell is alive
// and is beside the no interact border, expand it by 1
// (Basically, to prevent ArrayOutOfBoundsException s,
// (the ArrayList equivalent) only cells from 1 to cellsX-1(-1)/cellsY-1(-1)
// are counted,)
// meaning that a whole row/column of cells is ignored and is not interacted with,
// until the grid expands.
ArrayList <Boolean> l = new ArrayList<Boolean>();
for(int k=0; k<cellsX; k++){
l.add(false);
}
if(i <= 1){ // You may notice that the above comments are wrong.
// This is because I thought this might be a small chance for it to succeed
// while I was frustrated this was not working.
grid.add(0, l);
cellSize = screenX / (cellSize + 1);
cellsX++;
VALUE = true;
repaint();
System.out.println("i<=5");
}
if(i >= cellsX-1){
grid.add(l);
cellSize = screenX / (cellSize + 1);
cellsX++;
VALUE = true;
repaint();
System.out.println("i>=cellsX");
}
if(j <= 1) {
for(int k=0; k<cellsY; k++){
grid.get(k).add(false);
}
cellSize = screenY / (cellSize + 1);
cellsY++;
VALUE = true;
System.out.println("j<=5");
repaint();
}
if(j >= cellsY-1) {
for(int k=0; k<cellsY; k++){
grid.get(k);
}
cellSize = screenY / (cellSize + 1);
cellsY++;
VALUE = true;
System.out.println("j>cellsY");
repaint();
}
//corner cases aren't a problem, it'll add to both sides
// && (i == 1 || i == cellsX-1 || j == 1 || j == cellsY-1)
/* i.e.
* 0 = dead cells
* 1 = annoying cells in the corner
* + = new cells
* First, it'll do this
* + + +
* 0 1 1
* 0 1 1 // Note that the square is a "still life form" meaning that it will
* 0 0 0 // simply sit there and do nothing for infinite generations if
* // untouched
* But the if statements above will return true more than once, so
* 0 0 0 +
* 0 1 1 +
* 0 1 1 +
* 0 0 0 +
*/
}
/////////////////////////////////////////////
if (oldGrid[i][j] && !(nearbyCells == 2 || nearbyCells == 3)){
// if it is alive, sustain rules
grid.get(i).set(j, false);
}
else if (!oldGrid[i][j] && nearbyCells == 3){ // if it is dead, birth rules
grid.get(i).set(j, true);
}
}
}
repaint(); // never erase, note that in bigger applications I assume that they
// draw to pictures that get slapped onto the screen so the paint function doesn't
// get called 9999 times and slow the fps down

}
});
int nearbyCells(boolean[][] oldGrid, int i, int j) { // A method that calculates how many cells are
//alive near it, i.e.
/* 0 = Dead
* 1 = Alive
* "+" = center
* 1 0 0
* 0 + 1
* 0 0 1
* If you called nearbyCells on the center in the example, then it would return 3.
*/
int nearbyCells = 0;

if(oldGrid[i+1][j+1]) nearbyCells++;
if(oldGrid[i+1][j]) nearbyCells++;
if(oldGrid[i+1][j-1]) nearbyCells++;

if(oldGrid[i][j+1]) nearbyCells++;
if(oldGrid[i][j-1]) nearbyCells++; // i, j is where the to-be-changed cell is, skip it

if(oldGrid[i-1][j+1]) nearbyCells++;
if(oldGrid[i-1][j]) nearbyCells++;
if(oldGrid[i-1][j-1]) nearbyCells++;
return nearbyCells;
}
public SquarePaint(boolean[][] grid){
define(grid);
timer.start();
}
public SquarePaint(){
timer.start();
}
public void define (boolean[][] grid){ // define cannot be called twice, not intended
for(int i=0; i<cellsX; i++){
ArrayList<Boolean> l = new ArrayList<Boolean>();
for(int j=0; j<cellsY; j++){
l.add(grid[i][j]);
}
this.grid.add(l);
}
}
@Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, screenX, screenY); // Warning: Color must be set
// each time if the paint command is ever to be called again


for(int i=0; i<cellsX-1; i++){
for(int j=0; j<cellsY-1; j++){
try{
if(grid.get(i).get(j)){
g.setColor(Color.WHITE);
g.fillRect(i * cellSize, j * cellSize, cellSize, cellSize);
} // Basically, 2 for loops
}// Nested for loops draw each cell on the potentially expanding ArrayList "grid" of cells

catch(java.lang.IndexOutOfBoundsException e){
System.out.println(i + " " + j);
e.getStackTrace();
}
g.setColor(Color.GRAY);
g.drawRect(i * cellSize, j * cellSize, cellSize, cellSize);
}
}


}

}

}

最佳答案

我不知道你的应用程序中间的逻辑应该做什么。不应该那么复杂。这在另一个线程中运行模拟,因此可能有助于解决性能问题。

public class GameOfLife extends JFrame {
private static final long serialVersionUID = 1L;
private Thread thread;
private SimulationThread simulationThread;

public GameOfLife() {
super("GameOfLife");
}


class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;

public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
}

public Dimension getPreferredSize() {
return new Dimension(1000, 1000);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
simulationThread.drawScreenItems(g2d);
}
}
/**
* Create the GUI and show it. For thread safety, this method should be invoked
* from the event-dispatching thread.
*/
public void createAndShowGUI() {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

MyPanel myPanel = new MyPanel();
add(myPanel);

// Display the window.
pack();
setLocationRelativeTo(null);
setVisible(true);
// Create and set up the window.

// create thread with genetic reproduction callback code.
simulationThread = new SimulationThread(myPanel);
thread = new Thread(simulationThread);
thread.start();
}

public static void main(String[] args) {
final GameOfLife swingGa = new GameOfLife();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
swingGa.createAndShowGUI();
}
});
}
}

public class SimulationThread implements Runnable {
private MyPanel myPanel;
public boolean run = true;
static final int GAME_SIZE = 200;

boolean[][] cells;
boolean[][] newCells;

public SimulationThread(MyPanel myPanel) {
this.myPanel = myPanel;
cells = new boolean[GAME_SIZE][GAME_SIZE];
for (int i = 1; i < cells.length - 1; i++) {
for (int j = 1; j < cells[0].length - 1; j++) {
cells[i][j] = Math.random() > 0.5;
}
}
newCells = new boolean[GAME_SIZE][GAME_SIZE];
}

@Override
public void run() {
while (run) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Iterate through the array, follow game of life rules
for (int i = 1; i < cells.length - 1; i++) {
for (int j = 1; j < cells[0].length - 1; j++) {
int surrounding = 0;
if (cells[i - 1][j - 1]) surrounding++;
if (cells[i - 1][j]) surrounding++;
if (cells[i - 1][j + 1]) surrounding++;
if (cells[i][j - 1]) surrounding++;
if (cells[i][j + 1]) surrounding++;
if (cells[i + 1][j - 1]) surrounding++;
if (cells[i + 1][j]) surrounding++;
if (cells[i + 1][j + 1]) surrounding++;
newCells[i][j] = false;
if (cells[i][j]) {
// Cell is alive, Can the cell live? (2-3)
if ((surrounding == 2) || (surrounding == 3)) {
newCells[i][j] = true;
}
} else {
// Cell is dead, will the cell be given birth? (3)
if (surrounding == 3) {
newCells[i][j] = true;
}
}
}
}
synchronized(cells) {
for (int i = 1; i < cells.length - 1; i++) {
for (int j = 1; j < cells[0].length - 1; j++) {
cells[i][j] = newCells[i][j];
}
}
}
myPanel.repaint();
}

}

public void drawScreenItems(Graphics2D g2d) {
synchronized(cells) {
for (int i = 1; i < cells.length - 1; i++) {
for (int j = 1; j < cells[0].length - 1; j++) {
if (cells[i][j])
g2d.fillRect(i * (1000 / GAME_SIZE), j * (1000 / GAME_SIZE), 1000 / GAME_SIZE, 1000 / GAME_SIZE);
}
}
}
}
}

关于java - 复制康威生命游戏的尝试无法扩展或正常运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58037057/

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