February 02, 2015
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
February 03, 2015
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
}


February 03, 2015
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!).
February 03, 2015
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
February 03, 2015
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').


February 03, 2015
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
1 2
Next ›   Last »