mboost-dp1
Java Hjælp..
- Forside
- ⟨
- Forum
- ⟨
- Programmering
Hej derude... jeg har set mig blind på min kode efterhånden.
Jeg er ved at lave spillet "Game of life" hvis det siger Jer noget.
Hvor om alting er så skal jeg have fundet ud af hvor mange celler der er i live, i et område af 3x3 felter.
Hvis den pågældende celle har 2 naboer, og selv er i live, så overlever han. Hvis han ikke er i live så forbliver han død.
Hvis han derimod har 3 naboer, og han er død, liver han op. Hvis han er levende forbliver han levende. Alle andre muligheder vil dræbe den pågældende celle.
koden er som følger:
Håber der er nogen som kan tyde min kode og som har nogle friske øjne på den..
Kenn Stadager
Jeg er ved at lave spillet "Game of life" hvis det siger Jer noget.
Hvor om alting er så skal jeg have fundet ud af hvor mange celler der er i live, i et område af 3x3 felter.
Hvis den pågældende celle har 2 naboer, og selv er i live, så overlever han. Hvis han ikke er i live så forbliver han død.
Hvis han derimod har 3 naboer, og han er død, liver han op. Hvis han er levende forbliver han levende. Alle andre muligheder vil dræbe den pågældende celle.
koden er som følger:
public void findNeighbors(Cell[][] cell, int x, int y) {
int nrAlive = 0;
for (int col = x - 1; col < x + 2; col++) {
for (int row = y - 1; row < y + 2; row++) {
if (col >= 0 && col < cell.length && row >= 0 && row < cell[col].length) {
if (cell[col][row].isAlive()==true) {
nrAlive++;
}
}
}
}
if (cell[x][y].isAlive()==true) {
nrAlive--;
}
if (nrAlive==2 && cell[x][y].isAlive()==true){
cell[x][y].setAlive(true);
}
if (nrAlive==3){
cell[x][y].setAlive(true);
}else{
cell[x][y].setAlive(false);
}
}
Håber der er nogen som kan tyde min kode og som har nogle friske øjne på den..
Kenn Stadager
Denne kode har ikke nogen effekt:
Da den kun vil sætte cellen til "levende" hvis den er levende i forvejen.
Derfor vil denne kode:
Altid dræbe cellen hvis den har to naboer.
Det du mangler er en "else" mellem de to kodeblokke, så der kommer til at stå:
Men da det som sagt er lidt meningsløst at oplive cellen hvis den allerede er levende, burde du også bare kunne skrive følgende:
Så vil cellen bare beholde sin status hvis den har to naboer.
if (nrAlive==2 && cell[x][y].isAlive()==true) {
cell[x][y].setAlive(true);
}
Da den kun vil sætte cellen til "levende" hvis den er levende i forvejen.
Derfor vil denne kode:
if (nrAlive==3) {
cell[x][y].setAlive(true);
} else {
cell[x][y].setAlive(false);
}
Altid dræbe cellen hvis den har to naboer.
Det du mangler er en "else" mellem de to kodeblokke, så der kommer til at stå:
if (nrAlive==2 && cell[x][y].isAlive()==true) {
cell[x][y].setAlive(true);
} else if (nrAlive==3) {
cell[x][y].setAlive(true);
} else {
cell[x][y].setAlive(false);
}
Men da det som sagt er lidt meningsløst at oplive cellen hvis den allerede er levende, burde du også bare kunne skrive følgende:
if (nrAlive==3) {
cell[x][y].setAlive(true);
} else if (nrAlive != 2) {
cell[x][y].setAlive(false);
}
Så vil cellen bare beholde sin status hvis den har to naboer.
Nu siger du jo ikke noget om hvad problemet er, men jeg kan da kommentere din kode. Jo mere læsevenlig koden er, jo nemmere er det at finde fejl. (Det er sværere at skrive kode som både computer og menneske kan forstå, end kode som kun computeren kan forstå.)
Jeg har ikke ændret noget i koden, kun indsat kommentarer.
Jeg har ikke ændret noget i koden, kun indsat kommentarer.
public void findNeighbors(Cell[][] cell, int x, int y) {
int nrAlive = 0;
// Her forvirrer det mig at du kigger på "-1" og "+2". Jeg ville tælle til "<= x+1" i stedet for "< x+2".
for (int col = x - 1; col < x + 2; col++) {
// For at forkorte den lange betingelse i if-sætningen længere nede, kunne du allerede her tjekke om "col" er inden for din matrix. Det vil også performe ubetydeligt bedre. Fx:
// if (col < 0 || col >= cell.length) {
// continue;
// }
for (int row = y - 1; row < y + 2; row++) {
if (col >= 0 && col < cell.length && row >= 0 && row < cell[col].length) {
// Du skulle nok også tjekke om du er midt i din 3x3-matrix, da det jo kun er naboer du tæller. Du kan evt. gøre det i en selvstændig "if": if (col==x && row==y) continue;
if (cell[col][row].isAlive()==true) {
nrAlive++;
}
}
}
}
// Hvis du følger mit ovenstående råd, slipper du for at kompensere her, og kan slette de tre næste linjer.
if (cell[x][y].isAlive()==true) {
nrAlive--;
}
// De næste 3 linjer gør intet ud over at bruge CPU-tid.
if (nrAlive==2 && cell[x][y].isAlive()==true){
cell[x][y].setAlive(true);
}
// Her går der lidt ged i din indrykning. Især hos begyndere er det næsten garanti for at lave fejl senere.
if (nrAlive==3){
cell[x][y].setAlive(true);
}else{
cell[x][y].setAlive(false);
}
// Logikken for om om cellen er levende eller ej ville jeg nok lave som en switch:
// switch(nrAlive) {
// case 0:
// case 1:
// cell[x][y].setAlive(false);
// break;
// case 2:
// // No change
// break;
// case 3:
// cell[x][y].setAlive(true);
// break;
// default:
// cell[x][y].setAlive(false);
// }
}
...så fik jeg lige tid til at skrive lidt mere. :)
Tænk at når du beregner hvordan din matrix ser ud i trin 2, så skal du kigge på hvordan den så ud i trin 1.
Først beregner du felt 1,1. Alt OK. Så beregner du felt 1,2. For at beregner felt 1,2 skal du vide hvordan felt 1,1 så ud. Men det kan du ikke se længere, fordi du måske allerede har modificeret den.
Du er faktisk nødt til at lave en ny matrix. Når du beregner kigger du i den gamle, og gemmer resultaterne i den nye. Til sidst kan du så overføre fra den nye matrix til den gamle, eller returnere den nye matrix.
Tænk at når du beregner hvordan din matrix ser ud i trin 2, så skal du kigge på hvordan den så ud i trin 1.
Først beregner du felt 1,1. Alt OK. Så beregner du felt 1,2. For at beregner felt 1,2 skal du vide hvordan felt 1,1 så ud. Men det kan du ikke se længere, fordi du måske allerede har modificeret den.
Du er faktisk nødt til at lave en ny matrix. Når du beregner kigger du i den gamle, og gemmer resultaterne i den nye. Til sidst kan du så overføre fra den nye matrix til den gamle, eller returnere den nye matrix.
Hej alle sammen.. og tak for kommentarene..
Emil: Tak for forsøget... det virkede desværre ikke..
MyPlace.dk: Har også prøvet med en switch, dog uden held..
btw.. så godt at indrykningen var elendig. Dog blev den være efter jeg satte code tags om den..
ifølge reglerne for Game of life, så vil 3 celler på stribe være en stabil struktur idet, den skifter mellem følgende:
*
*
*
------------
* * *
------------
*
*
*
Lige nu opfører det sig således:
*
*
*
------------
*
*
* *
------------
* *
* *
Firkanten bliver der selvfølgelig..
Og jeg aner virkelig ikke hvor det er at det går galt..
Emil: Tak for forsøget... det virkede desværre ikke..
MyPlace.dk: Har også prøvet med en switch, dog uden held..
btw.. så godt at indrykningen var elendig. Dog blev den være efter jeg satte code tags om den..
ifølge reglerne for Game of life, så vil 3 celler på stribe være en stabil struktur idet, den skifter mellem følgende:
*
*
*
------------
* * *
------------
*
*
*
Lige nu opfører det sig således:
*
*
*
------------
*
*
* *
------------
* *
* *
Firkanten bliver der selvfølgelig..
Og jeg aner virkelig ikke hvor det er at det går galt..
hmmm... det kan der være noget om..
int nrAlive = 0;
for (int col = x - 1; col < x + 2; col++) {
for (int row = y - 1; row < y + 2; row++) {
if (col >= 0 && col < cell.length && row >= 0 && row < cell[col].length) {
if (cell[col][row].isAlive() == true) {
nrAlive++;
}
}
}
}
//Trækker sig selv fra naboer.
if (cell[x][y].isAlive() == true) {
nrAlive--;
}
//hvis der er 3 naboer, så skal den lives op.
if (nrAlive == 3) {
cell[x][y].setAlive(true);
//Hvis der ikke er 2 naboer skal den dø.
} else if (nrAlive != 2) {
cell[x][y].setAlive(false);
}
Simplified, skrevet som hjælp til en ven i Finland.
package game;
public class Game
{
/**
* Starts the Game of Life.
*
* @param args
*/
public static void main(String[] args)
{
int generations = 3;
char[][] start_data = {
new char[] { '.','.','.','.','.' },
new char[] { '.','o','.','o','.' },
new char[] { '.','.','o','.','.' },
new char[] { '.','.','.','.','.' },
new char[] { '.','.','.','.','.' },
};
for(int i = 0; i < generations; i++)
{
System.out.println("Evoloution #" + (i+1));
printData(start_data);
start_data = evolve(start_data);
System.out.print("\n");
}
}
/**
* Utility: Prints a evolution.
*
* @param data
*/
private static void printData(char[][] data)
{
for(int o=0;o<data.length;o++)
{
for(int i=0;i<data[0].length;i++)
{
System.out.print(data[o][i] + " ");
}
System.out.print("\n");
}
}
/**
* Utility: Copies a nested array.
*
* @param input
* @return
*/
private static char[][] deepArrayCopy(char[][] input)
{
char[][] tmp = new char[input.length][];
for(int i=0; i<tmp.length; i++)
{
tmp[i] = new char[input[i].length];
for(int t=0;t<input[i].length;t++)
{
tmp[i][t] = input[i][t];
}
}
return tmp;
}
/**
* Evolve a set of spicies.
*
* @param data
* @return
*/
private static char[][] evolve(char[][] data)
{
char[][] result = deepArrayCopy(data);
int neighbors = 0;
// Outer Iteration (Rows)
for(int o=0;o<data.length;o++)
{
// Inner Iteration (Columns)
for(int i=0;i<data[0].length;i++)
{
neighbors = countNeighbors(data, o, i);
// 1. Any live cell with fewer than two live neighbours dies,
// as if by needs caused by underpopulation
if(neighbors < 2)
{
result[o][i] = '.';
}
// 2. Any live cell with more than three live neighbours dies,
// as if by overcrowding.
else if(neighbors > 3)
{
result[o][i] = '.';
}
// 3. Any live cell with two or three live neighbours lives,
// unchanged, to the next generation.
else if((neighbors == 2 || neighbors == 3) && (data[o][i] == 'o'))
{
result[o][i] = 'o';
}
/// 4. Any dead cell with exactly three live neighbours becomes a live cell.
else if((neighbors == 3) && (data[o][i] == '.'))
{
result[o][i] = 'o';
}
}
}
return result;
}
/**
* Checks all 8 surrounding cells for life,
* and return the amount of neighbors.
*
* @param rowIndex
* @param columnIndex
*/
private static int countNeighbors(char[][] data, int rowIndex, int columnIndex)
{
int neighbors = 0;
// Horisontal (Left)
if((columnIndex > 0)
&& (data[rowIndex][columnIndex-1] == 'o'))
{
neighbors++;
}
// Horisontal (Right)
if((columnIndex < data[rowIndex].length-1)
&& (data[rowIndex][columnIndex+1] == 'o'))
{
neighbors++;
}
// Vertical (Top)
if((rowIndex > 0)
&& (data[rowIndex-1][columnIndex] == 'o'))
{
neighbors++;
}
// Vertical (Below)
if((rowIndex < data.length-1)
&& (data[rowIndex+1][columnIndex] == 'o'))
{
neighbors++;
}
// Dimensional
if(rowIndex > 0)
{
// Below-Left
if((columnIndex > 0)
&& (data[rowIndex-1][columnIndex-1] == 'o')) {
neighbors++;
}
// Below-Right
if((columnIndex < data[rowIndex].length-1)
&& (data[rowIndex-1][columnIndex+1] == 'o')) {
neighbors++;
}
}
// Dimensional
if(rowIndex < data.length-1)
{
// Top-Left
if((columnIndex > 0)
&& (data[rowIndex+1][columnIndex-1] == 'o')) {
neighbors++;
}
// Top-Right
if((columnIndex < data[rowIndex].length-1)
&& (data[rowIndex+1][columnIndex+1] == 'o')) {
neighbors++;
}
}
return neighbors;
}
}
http://pastebin.com/f690d393d
Jeg lavede lige en hurtig implementation, som bruger et to-dimentionelt array af booleans. Bemærk at jeg i min evolve()-metode, kun skal bekymre mig om en celle skal leve, da alle celler i tmp som default er false.
Jeg lavede lige en hurtig implementation, som bruger et to-dimentionelt array af booleans. Bemærk at jeg i min evolve()-metode, kun skal bekymre mig om en celle skal leve, da alle celler i tmp som default er false.
Gå til top
Opret dig som bruger i dag
Det er gratis, og du binder dig ikke til noget.
Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.