Re: Conway's game of life

2015-02-03 Thread Paul via Digitalmars-d-learn

On Monday, 2 February 2015 at 16:58:43 UTC, bearophile wrote:


The quality of the D GC is not important for a simple Life 
implementation, you just need two arrays.


Here's my 30 minute sandwich-break version, sorry it's not very 
arractive 'D'...


import std.stdio;
import std.random;


void main(){

enum WORLDSIZE = 20;
enum INITIALPOP = 70;   //experimental
enum DEAD = 0;
enum ALIVE = 1;

int world[WORLDSIZE][WORLDSIZE];
int buffer[WORLDSIZE][WORLDSIZE];

//sprinkle life
foreach(i; 0..INITIALPOP){
//find an empty cell
int rX, rY;
do{
rX = uniform(0, WORLDSIZE);
rY = uniform(0, WORLDSIZE);
} while(world[rX][rY] == ALIVE);
world[rX][rY] = ALIVE;
}

//loop forever
while (true){

//work on the buffer
buffer = world;

foreach(x; 0..WORLDSIZE){
foreach(y; 0..WORLDSIZE){

int neighbourCount;

//get index to left, right, above and below current cell, 
wrapping if necessary

int left = (x == 0) ? WORLDSIZE-1 : x-1;
int right = (x == (WORLDSIZE-1) ) ? 0 : x+1;
int top = (y == 0) ? WORLDSIZE-1 : y-1;
int bottom = (y == (WORLDSIZE-1) ) ? 0 : y+1;

//add up surrounding cells
neighbourCount += world[left][y];
neighbourCount += world[left][top];
neighbourCount += world[left][bottom];
neighbourCount += world[x][top];
neighbourCount += world[x][bottom];
neighbourCount += world[right][top];
neighbourCount += world[right][y];
neighbourCount += world[right][bottom];


//if this cell is alive
if( world[x][y] == ALIVE){
//decide what to do
switch(neighbourCount){
case 2:
buffer[x][y] = ALIVE;
break;
case 3:
buffer[x][y] = ALIVE;
break;
default:
buffer[x][y] = DEAD;
}
}
else{
//just like today's news, newborn has 
three parents!
if(neighbourCount == 3) buffer[x][y] = 
ALIVE;
}
}   
}

//update world with contents of buffer
world = buffer;

//show current state of world with fancy graphics :P
foreach(x; 0..WORLDSIZE){
foreach(y; 0..WORLDSIZE){
write( world[x][y] == ALIVE ? X : . );
}
writeln();
}

readln();

}//end loop
}




Re: Conway's game of life

2015-02-03 Thread Paul via Digitalmars-d-learn

On Tuesday, 3 February 2015 at 13:35:37 UTC, Paul wrote:

On Monday, 2 February 2015 at 16:58:43 UTC, bearophile wrote:


The quality of the D GC is not important for a simple Life 
implementation, you just need two arrays.


Here's my 30 minute sandwich-break version, sorry it's not very 
arractive 'D'...


Meant to say - hold down return to avoid tedium and Ctrl+C to 
quit (of course!).


Re: Conway's game of life

2015-02-03 Thread Paul via Digitalmars-d-learn

On Tuesday, 3 February 2015 at 14:01:51 UTC, bearophile wrote:

Paul:


enum WORLDSIZE = 20;
enum INITIALPOP = 70;   //experimental
enum DEAD = 0;
enum ALIVE = 1;


D enums don't need to be ALL UPPERCASE :-)



int world[WORLDSIZE][WORLDSIZE];


Don't forget to compile with warnings active (it's a design 
error of the D compiler to have them disabled by default).




foreach(i; 0..INITIALPOP){


It's less bug-prone to make that index immutable:

foreach(immutable i; 0 .. initialPop) {

Bye,
bearophile


Thanks for the comments. The all-caps enums is just habit. I 
don't get any warnings using the dmd -w switch, I take it you 
mean use int[size][size] var instead?


Regarding the immutable loop variable, I've conditioned myself 
never to interfere with loop control values - it gives me the 
same bad feeling as goto/continue (and to a lesser extent 
'break').





Re: Conway's game of life

2015-02-03 Thread bearophile via Digitalmars-d-learn

Paul:

Regarding the immutable loop variable, I've conditioned myself 
never to interfere with loop control values


But adding immutable you don't risk modifying the variable by 
mistake.


It's another design mistake of D. Variables (like foreach loop 
indexes) must be immutable by default because otherwise 
programmers often don't bother making them immutable. It's a lost 
war.


Bye,
bearophile


Re: Conway's game of life

2015-02-03 Thread bearophile via Digitalmars-d-learn

Paul:


enum WORLDSIZE = 20;
enum INITIALPOP = 70;   //experimental
enum DEAD = 0;
enum ALIVE = 1;


D enums don't need to be ALL UPPERCASE :-)



int world[WORLDSIZE][WORLDSIZE];


Don't forget to compile with warnings active (it's a design error 
of the D compiler to have them disabled by default).




foreach(i; 0..INITIALPOP){


It's less bug-prone to make that index immutable:

foreach(immutable i; 0 .. initialPop) {

Bye,
bearophile


Re: Conway's game of life

2015-02-02 Thread FG via Digitalmars-d-learn

On 2015-02-02 at 12:23, FG wrote:

Cell(0,3) is not a neighbour bit fits the (diff1 == 1 || diff2 == 1) criterion.


s/bit/but/


Re: Conway's game of life

2015-02-02 Thread FG via Digitalmars-d-learn

Bloody Thunderbird has sent a reply to the OP and not to the NG.

On 2015-02-02 at 11:45, gedaiu wrote:

I don't think that the line of code is wrong. If use  the function will check 
for neighbours only on diagonals. Having || allows the search on the vertical and 
horizontal axis and diagonals.


In short: Yes,  alone would check only diagonals, but I forgot to tell you to 
also change the ==.

(diff1 == 1 || diff2 == 1) -- bad, accepts whole neighbouring rows and columns
(diff1 == 1  diff2 == 1) -- bad, accepts only neighbouring diagonals
(diff1 = 1  diff2 = 1) -- correct, I think :)

This unittest should show the difference:

unittest {
CellList world = [ Cell(0,0), Cell(0,1), Cell(0,2), Cell(0,3) ];
assertEqual(Cell(1,1).neighbours(world), 3);
}

Cell(0,3) is not a neighbour bit fits the (diff1 == 1 || diff2 == 1) criterion.


Re: Conway's game of life

2015-02-02 Thread gedaiu via Digitalmars-d-learn

Uf...  you are right!

I've fixed it.

Thanks!


On Monday, 2 February 2015 at 11:23:17 UTC, FG wrote:

Bloody Thunderbird has sent a reply to the OP and not to the NG.

On 2015-02-02 at 11:45, gedaiu wrote:
I don't think that the line of code is wrong. If use  the 
function will check for neighbours only on diagonals. Having 
|| allows the search on the vertical and horizontal axis and 
diagonals.


In short: Yes,  alone would check only diagonals, but I 
forgot to tell you to also change the ==.


(diff1 == 1 || diff2 == 1) -- bad, accepts whole neighbouring 
rows and columns
(diff1 == 1  diff2 == 1) -- bad, accepts only neighbouring 
diagonals

(diff1 = 1  diff2 = 1) -- correct, I think :)

This unittest should show the difference:

unittest {
CellList world = [ Cell(0,0), Cell(0,1), Cell(0,2), 
Cell(0,3) ];

assertEqual(Cell(1,1).neighbours(world), 3);
}

Cell(0,3) is not a neighbour bit fits the (diff1 == 1 || diff2 
== 1) criterion.




Re: Conway's game of life

2015-02-02 Thread gedaiu via Digitalmars-d-learn
I don't think that the line of code is wrong. If use  the 
function will check for neighbours only on diagonals. Having || 
allows the search on the vertical and horizontal axis and 
diagonals.


There are some tests that check the function:

unittest {
	CellList world = [ Cell(0,0), Cell(0,1), Cell(0,2), Cell(1,0), 
Cell(1,2), Cell(2,0), Cell(2,1), Cell(2,2) ];

assertEqual(Cell(1,1).neighbours(world), world.length);
}

unittest {
CellList world = [ Cell(0,0), Cell(1,1), Cell(2,2), Cell(3,3) ];
assertEqual(Cell(1,1).neighbours(world), 2);
}

I don't see a glitch.

Thanks,
Bogdan



On Sunday, 1 February 2015 at 22:51:42 UTC, FG wrote:

On 2015-02-01 at 22:00, gedaiu wrote:

I implemented Conway's game of life in D.


I think you are playing a different game here.

/// Count cell neighbours
long neighbours(Cell myCell, CellList list) {
long cnt;
foreach(cell; list) {
auto diff1 = abs(myCell.x - cell.x);
auto diff2 = abs(myCell.y - cell.y);
if(diff1 == 1 || diff2 == 1) cnt++;   // Why || 
instead of  ???

}
return cnt;
}




Re: Conway's game of life

2015-02-02 Thread gedaiu via Digitalmars-d-learn
It's true that I have to change that function. Thanks for the 
notice!


Why do you think that D's GC is crap?




On Sunday, 1 February 2015 at 21:54:43 UTC, Foo wrote:

On Sunday, 1 February 2015 at 21:00:07 UTC, gedaiu wrote:

Hi,

I implemented Conway's game of life in D. What do you think 
that

I can improve to this program to take advantage of more D
features?

https://github.com/gedaiu/Game-Of-Life-D

Thanks,
Bogdan


For each remove you create a new array. That is lavish. You 
should use a bool inside the struct Cell. If it's false, the 
cell is not displayed and is out of the game.
My suggestion: don't use the D GC, it's crap. Try to circumvent 
the GC wherever possible. Therefore you should use the -vgc 
compiler flag and the @nogc attribute.




Re: Conway's game of life

2015-02-02 Thread bearophile via Digitalmars-d-learn

gedaiu:


https://github.com/gedaiu/Game-Of-Life-D


A bare-bones implementation:
http://rosettacode.org/wiki/Conway%27s_Game_of_Life#Faster_Version

The quality of the D GC is not important for a simple Life 
implementation, you just need two arrays.


Bye,
bearophile


Re: Conway's game of life

2015-02-01 Thread Tobias Pankrath via Digitalmars-d-learn

1. I prefer

alias CellList = Cell[];
over
alias Cell[] CellList;

2. Do you really need to create a complete new CellList for every 
single removal? If so, you'd know the size of the new list in 
advance and can allocate it directly at the correct size.


I get the impression that you think Cell[] is a linked list but 
it's an array slice.





Re: Conway's game of life

2015-02-01 Thread FG via Digitalmars-d-learn

On 2015-02-01 at 22:00, gedaiu wrote:

I implemented Conway's game of life in D.


I think you are playing a different game here.

/// Count cell neighbours
long neighbours(Cell myCell, CellList list) {
long cnt;
foreach(cell; list) {
auto diff1 = abs(myCell.x - cell.x);
auto diff2 = abs(myCell.y - cell.y);
if(diff1 == 1 || diff2 == 1) cnt++;   // Why || instead of  ???
}
return cnt;
}


Conway's game of life

2015-02-01 Thread gedaiu via Digitalmars-d-learn

Hi,

I implemented Conway's game of life in D. What do you think that
I can improve to this program to take advantage of more D
features?

https://github.com/gedaiu/Game-Of-Life-D

Thanks,
Bogdan


Re: Conway's game of life

2015-02-01 Thread Foo via Digitalmars-d-learn

On Sunday, 1 February 2015 at 21:00:07 UTC, gedaiu wrote:

Hi,

I implemented Conway's game of life in D. What do you think that
I can improve to this program to take advantage of more D
features?

https://github.com/gedaiu/Game-Of-Life-D

Thanks,
Bogdan


For each remove you create a new array. That is lavish. You 
should use a bool inside the struct Cell. If it's false, the cell 
is not displayed and is out of the game.
My suggestion: don't use the D GC, it's crap. Try to circumvent 
the GC wherever possible. Therefore you should use the -vgc 
compiler flag and the @nogc attribute.


Re: Conway's game of life

2015-02-01 Thread data man via Digitalmars-d-learn

On Sunday, 1 February 2015 at 21:00:07 UTC, gedaiu wrote:

Hi,

I implemented Conway's game of life in D. What do you think that
I can improve to this program to take advantage of more D
features?

https://github.com/gedaiu/Game-Of-Life-D

Thanks,
Bogdan


If the subject of the game Life is interesting to you, look at 
these links:

http://en.wikipedia.org/wiki/Hashlife
http://golly.sourceforge.net