Если вы не знаете, что такое игра жизни Конвея, проверьте это, это игра для нулевого игрока и клеточная автоматизация.https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
Мне нужна помощь Отладка Следующие проблемы в моем коде.При необходимости я могу отредактировать этот вопрос, включив в него более старые версии моей программы, которые не предназначены для расширения.
Я также приму советы по улучшению моей программы, в том числе (но не ограничиваясь) эффективностью времени, (однако не по теме, так как это не главный вопрос) и некорректное использование существующих методов.(Мой метод paint ())
Проблемы:
Изучите планер A на изображении 1. (Ожидаемое поведение) Весь смысл программы состоял в том, чтобы уменьшить ячейки в JFrameи добавьте еще одну строку или столбец мертвых клеток в ArrayList<ArrayList<Boolean>> grid
.Этот планер, к сожалению, не вызывает этого.Вместо этого результат (неожиданное поведение) состоял в том, что он просто «сплющился в квадрат», как показано на рисунке 2 (квадрат помечен буквой A).
Изучите планер B на рисунке 1. (Ожидаемое поведение) ВидяРезультаты Glider A на изображении 1 заставили меня думать, что планер B закончится так же.Однако это далеко не так.Посмотрите на планер B на рисунке 2. По какой-то причине он даже не достигает границы.(Неожиданно)
Для чего предназначена и предназначена эта программа: игра жизни Конвея находится в бесконечной 2D-плоскости, поэтому я хотел повторить это.В других моих программах использовался фиксированный размер массива, но для расширения использовались вложенные списки ArrayLists, и они действительно были бесконечными (до тех пор, пока не достигнуто ограничение памяти)
К сожалению, эта программа расширения просто не может расширить границу.(Граница на самом деле меньше, чем кажется. По сути, (притворяясь, что моя сетка 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 сплющен к границе.(Граница находится под сеткой ячеек, где серые линии отсутствуют)
Изображение 1 Изображение 2
Эти изображения соответствуют друг другу;планер A из изображения 1 Заголовок создает квадрат на изображении 2, также помеченный как A. Если вы видите какие-либо слова, описывающие «линию 74», указывающие на «линию 74», или такие слова, как «ВВЕРХ» (без какого-либо другого значения) в комментариях вкод, пожалуйста, скажите мне, чтобы я мог удалить их.Это была отдельная, уже исправленная ошибка.
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);
}
}
}
}
}