Jump to content

The game of life


tinguely
 Share

You are about to reply to a thread that has been inactive for 2372 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

This is something i have been experimenting with for a bit, it took a while just to get it working. I put it here in-case any one can improve it as i made it to use a fix grid size that one has to make before dragging the script in. It can go on forever as it should if the generation cap i put in is removed.

Feel free to use it and improve it, to all those who like conway's game of life.

// tinguely 2017
// check for false group so no further checks made, or stride to avoid making string groups
// so far, about 10 seconds per generation...
key u_key;
integer width = 15;
integer height = 15; 

// just use this grid instead of making a new one each time
list cells;

// for searching rows/cols
integer step = width;

//list test_pattern = ["4#5","5#5","3#6","4#6","4#7","4#8"];
list test_pattern = ["3#6","4#6","5#6","4#5","5#4"];
// insert patterns here when cells is built, e.g "r pentomino"
        //   ## 
        //  ##
        //   #
        //
        //          (4,5) (5,5)
        //    (3,6) (4,6)
        //          (4,7)


// frequently updated lists used for testing cells 
list new_cells;
list test_cells;
list rects_blank;
list rects;
list test_cell;// only for get neighbours, one cell element

// for building the empty base_grid
list sqr_empty(){
    rects_blank = [];
    
    integer x;
    integer y;

    for(x = 0; x < width; ++x){
        for(y =0; y < height; ++y){
            rects_blank = rects_blank + [(string)x+"#"+(string)y+"?"+"FALSE"]; 
        }
    }
    return rects_blank;
}
// a base grid but with a 'test_pattern' added
list sqr()
{
    // both outer loops
    rects = [];
    
    integer i;
    integer j;
    // inner pattern loop
    integer a; 
    integer b = llGetListLength(test_pattern);
    
    //
    string rect_str;
    integer match;
    integer bool_marker;
    string rect_coords;
    string pattern;
    
    for(i = 0; i < width; ++i){
        for(j =0; j < height; ++j){
            rect_str = (string)i+"#"+(string)j+"?"+"FALSE";
            match = 0;
            for(a= 0; a < b; ++a){
                
                bool_marker = llSubStringIndex(rect_str, "?");
                rect_coords = llGetSubString(rect_str, 0, bool_marker-1);
                pattern = llList2String(test_pattern, a);
                if (rect_coords == pattern){
                    
                    rects = rects+[pattern+"?TRUE"];
                    match = 1;
                }
            }
            // if match is still 0 here, add as usual
            if (match == 0){
                rects = rects+[rect_str];
            }
            
        }
    }

    return rects;   
}


//helper for get_neighbours
list get_cell(integer x, list c) 
{
    // plumbing, uses markers in cell string to get values needed
    string cell_str = llList2String(c, x); 
    integer num_marker = llSubStringIndex(cell_str, "#");
    string x_coord = llGetSubString(cell_str, 0, num_marker-1); //inc
    integer bool_marker = llSubStringIndex(cell_str, "?");
    string y_coord =  llGetSubString(cell_str, num_marker+1, bool_marker-1); //inc
    string bool_str = llGetSubString(cell_str, bool_marker+1, -1); //inc
    
    return [x_coord, y_coord, bool_str];
}
string get_cell_coords(integer x, list c) 
{
    string cell_str = llList2String(c, x); 
    integer bool_marker = llSubStringIndex(cell_str, "?");
    string coords = llGetSubString(cell_str, 0, bool_marker-1);
    
    return coords;
    
    
}
string get_cell_single_coord(integer x, list c, string get_coord) 
{
    string cell_str = llList2String(c, x); 
    integer num_marker = llSubStringIndex(cell_str, "#");
    string x_coord = llGetSubString(cell_str, 0, num_marker-1); //inc
    integer bool_marker = llSubStringIndex(cell_str, "?");
    string y_coord =  llGetSubString(cell_str, num_marker+1, bool_marker-1); //inc
    
    if (get_coord == "X"){
        return x_coord;
    }
    if (get_coord == "Y"){
        return y_coord;
    }
    
    else{return "e";} // check for e later
    
}

string get_cell_bool(integer x, list c) 
{
    string cell_str = llList2String(c, x); 
    integer bool_marker = llSubStringIndex(cell_str, "?");
    string booly = llGetSubString(cell_str, bool_marker+1,-1);
    
    return booly;
    
    
}
// checking true / false on individual cells
integer get_neighbours(integer i)
{
    integer alive_neighbours = 0;
    
    test_cell = get_cell(i, cells); // dont want to call get_cell_single_coord() twice here
     
    // more plumbing
    integer x = (integer)llList2String(test_cell, 0);
    integer y = (integer)llList2String(test_cell, 1);
    
    // now check
    if (x > 0 && x < width - 1 && y > 0 && y < height - 1){
        //left
        if (get_cell_bool(i-1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        // right
        if (get_cell_bool(i+1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        //top
        if (get_cell_bool(i-step, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        //top left
        if ( get_cell_bool(i-step-1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        //top right
        if ( get_cell_bool(i-step+1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        // bottom
        if ( get_cell_bool(i+step, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        //bottom left
        if (get_cell_bool(i+step-1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
        //bottom right
        if (get_cell_bool(i+step+1, cells) == "TRUE"){
            alive_neighbours += 1;
        }
    }
    test_cell=[];
    return alive_neighbours;
       
}
// use helper method get_neighbours  to change states of each cell
list check_alive_cells()
{

    //cant nest lists
    test_cells = sqr_empty();
    
    integer i;
    integer max = llGetListLength(cells);
    string replacement;
    
    for(i = 0; i < max; ++i){
        
        if (get_cell_bool(i, cells) == "FALSE"){
            integer alive_neighbours = get_neighbours(i);
            if(alive_neighbours == 3){
                // set to TRUE
                replacement = get_cell_coords(i,test_cells) +  "?TRUE";
                test_cells = llListReplaceList(test_cells,[replacement],i,i);
                replacement="";
            }
        }
        // -----
        if (get_cell_bool(i, cells) == "TRUE"){
            
            integer alive_neighbours = get_neighbours(i);
            
            if(alive_neighbours > 3 || alive_neighbours < 2){
                
                replacement = get_cell_coords(i,test_cells) + "?FALSE";;
                test_cells = llListReplaceList(test_cells,[replacement],i,i);
                replacement="";
            }
             
            if(alive_neighbours == 2 || alive_neighbours == 3){

                replacement = get_cell_coords(i,test_cells) + "?TRUE";;
                test_cells = llListReplaceList(test_cells,[replacement],i,i);
                replacement="";
            }
        }
        
    }
    // now change cells
    cells = test_cells;
    
    return test_cells; // a snapshot of what was just done
}

// start producing
begin(integer n){
    
    integer gen; // number of evolution steps
    integer max = llGetListLength(new_cells);
    integer i;
    string row;
    
    while(gen < n){
        //llOwnerSay( llGetTimestamp() );
        
        // test one generation per touch for now
        new_cells = check_alive_cells();
        max = llGetListLength(new_cells);
        //test with link colours
        
        for(i = 0; i < max; ++i){
            //llOwnerSay((string)i + " "+ get_cell_bool(i, new_cells) );
            
            if(get_cell_bool(i, new_cells) == "TRUE" ){
                
                llSetLinkColor(i+1,<0.0,0.0,0.0>,ALL_SIDES);
            }
            if(get_cell_bool(i, new_cells) == "FALSE" ){
                
                llSetLinkColor(i+1,<1.0,1.0,1.0>,ALL_SIDES);
            }
            
        }
       
        llSetText("Game of life:\n***\n Generation: " + (string)gen+"\n***", <1,1,1>, 1.5);
        gen += 1;
        
        //llOwnerSay( "memory use: " +(string)llGetUsedMemory() ); 
        //llOwnerSay( "Done..."+(string)gen);
    } 
}
default
{
    state_entry()
    {
        u_key = llGetOwner();
        // set info text
        llSetText("", <1,1,1>, 1.5);
        // reset all linked prims, link number starts at 1, so 1 to 226
        integer a;
        integer b = llGetNumberOfPrims();
        for(a =0; a < b;++a){llSetLinkColor(a+1,<1.0,1.0,1.0>,ALL_SIDES);}
        cells = sqr();
        begin(15); // integer generations
        
        
    }

    touch_start(integer total_number)
    {
        //begin();
        if(llDetectedKey(0) == u_key){
            llResetScript();
            llOwnerSay( "Done..."); 
        }
    }
}

 

  • Like 5
Link to comment
Share on other sites

It's a little surprising that it has taken this long for the Game of Life to find its way into SL. This game was briefly popular back in the 1980s as an illustrative application of the Boltzmann equation ( S = k log W ) to simulate chaos and "life". If you can find a copy of P.W. Atkins, The Second Law, W.H. Freeman & Co., New York, 1984 , you will find it in the Appendix  among a collection of programs written in BASIC for the Apple IIe computer. I remember putting it on my own computer for my children (who were not much impressed) and my students (who were).  BASIC and the Apple IIe are relics of history now, but this is still a fascinating routine.  Thank you for modernizing it and bringing it in world.

  • Like 4
Link to comment
Share on other sites

Oooh, The Game of Life was, I think, the first time magic appeared from a computer under my direction. I modified an algorithm that was published in a magazine to run on Dad's PDP-11, using ASCII characters as pixels. Dunno about the rest of you but, even with all the advances in computing and graphics, the magic of Life's cellular automatons still fills me with wonder.

Edited by Madelaine McMasters
  • Like 4
Link to comment
Share on other sites

I still find the subject to be fascinating, there's so many youtube videos of different ways of applying the game of life, from the clock to the game making a version of itself and all the possibilities it can render... it never ends. Never got to use a pdp11 even though i think there are emulators.

And this will be a good read A discussion of The Game of Life thanks. I haven't seen a fully fledged 3D implementation yet, should be fun.

  • Like 1
Link to comment
Share on other sites

The PDP-11 was a true workhorse for its time. It was a step before the era of minicomputers but dramatically smaller than the mainframes that were the standard before then. It was in a price range that made it accessible to small businesses and labs, and it was relatively easy to tack peripherals onto -- although you had to write your own interface routines.  I remember moving from a PDP-8S (with 8K of memory!) to the PDP-11 and marveling at the flexibility.

  • Like 4
Link to comment
Share on other sites

Dad's PDP-11 had two terminals, one in his office and one in his shop. The computer controlled his CNC milling machine and ran various mysterious programs he conjured up to make things. He usually didn't mind me looking over his shoulder while eating graham crackers, so long as I shared with him. But, there were times he needed quiet. Then he'd plunk me down at one of the terminals. If I wanted to chat, I'd have to learn to type. Where there's a will, there's a way. I'm still at it.

He had a more colorful computer before that, probably a PDP-8. I know it had paper tape because I loved to stick my fingers in the little plastic cup that caught the dots, to stir them around and get them all over the place. It's been 40 years, but I still find dots around the house.

  • Like 3
  • Haha 1
Link to comment
Share on other sites

  • 4 weeks later...
On 9/29/2017 at 6:29 PM, Madelaine McMasters said:

Dad's PDP-11 had two terminals, one in his office and one in his shop. The computer controlled his CNC milling machine and ran various mysterious programs he conjured up to make things. He usually didn't mind me looking over his shoulder while eating graham crackers, so long as I shared with him. But, there were times he needed quiet. Then he'd plunk me down at one of the terminals. If I wanted to chat, I'd have to learn to type. Where there's a will, there's a way. I'm still at it.

He had a more colorful computer before that, probably a PDP-8. I know it had paper tape because I loved to stick my fingers in the little plastic cup that caught the dots, to stir them around and get them all over the place. It's been 40 years, but I still find dots around the house.

DOTS! WE NEED MORE DOTS!!

(sowwy .. couldna resist)

Link to comment
Share on other sites

3 minutes ago, Love Zhaoying said:

I suppose the color adds a quantum dimension.

I'm uncertain about that.

ETA: Thanks for bringing my attention to the colors, which run for six dots. So, I needn't stick two strips together, I can just bite dots out of each color section to make three characters. The strip will read like a mix of English and Chinese.

Edited by Madelaine McMasters
Link to comment
Share on other sites

26 minutes ago, Madelaine McMasters said:

I'm uncertain about that.

ETA: Thanks for bringing my attention to the colors, which run for six dots. So, I needn't stick two strips together, I can just bite dots out of each color section to make three characters. The strip will read like a mix of English and Chinese.

Maybe Octal is another possibility, following the theme of ancient technology?

Link to comment
Share on other sites

3 hours ago, Madelaine McMasters said:

Outside of weddings, I wonder how often full-duplex eating of sweets actually happens...

Parents- toddlers, small children, hormone filled teenagers, new lovers - and as above - from that point on only full-duplex bashing and beating :D

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 2372 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...