Register
It is currently Thu Oct 30, 2014 6:02 pm

game of life


All times are UTC - 6 hours


Post new topic Reply to topic  [ 16 posts ] 
Author Message
 PostPosted: Sun Jun 27, 2010 1:11 am   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
Hi guys,

I'm new here so please be kind to me :)
To start off, I'd like to submit some not useful but funny piece of awk code, the Game of Life.

Usage: life.sh < seed1
or: genlife.sh | life.sh (for random seed)
or: genlife.sh 15 15 | life.sh 20 (for random 15x15 seed and 20 itterations)
or: genlife.sh 20 20 | life.sh 50 0.1 (for 20x20, quick 50 itterations)
or: life.sh 100 0 < seed3 (for a very quick 100 itterations of seed3)

Code:
#!/bin/sh
## life.sh -- Jun 25 2010, by Patsie
# awk implementation of the Game of Life. A simple automata
# Usage: life.sh [<nr of runs> [<sleep interval>] ]
#
# On a rectangular grid, let each cell be either living or dead.
# Designate a living cell with a dot and a dead one with a blank space.
# Begin with an arbitrarily drawn dot-and-blank grid, and let this be
# the starting generation. Determine each successive generation by the
# following rules:
#  1) Each cell has 8 neighbors, the adjoining cells.
#  2) A living cell with either 2 or 3 living neighbors remains alive.
#  3) A dead cell with 3 living neighbors comes alive (a birth).
#  4) All other cases result in a dead cell for the next generation.


awk -v runs=${1:-10} -v sleep=${2:-0.5} '
BEGIN { DEAD = " "; ALIVE = "o"; }

  # return if a neighbor is alive
  function isAlive(cell, neighbor) {
    if ( (neighbor < 1) || (neighbor > size) ) return 0;         # above or below screen
    if ( ((cell%cols) == 1) && ((neighbor%cols) == 0) ) return 0; # left off screen
    if ( ((cell%cols) == 0) && ((neighbor%cols) == 1) ) return 0; # right off screen

    return (substr(data, neighbor, 1) == ALIVE)?1:0;
  }

  ## count number of alive neighbors
  function countAlive(cell) {
    cnt  = isAlive(cell, cell-cols-1) + isAlive(cell, cell-cols) + isAlive(cell, cell-cols+1);
    cnt += isAlive(cell, cell-1) + isAlive(cell, cell+1);
    cnt += isAlive(cell, cell+cols-1) + isAlive(cell, cell+cols) + isAlive(cell, cell+cols+1);

    return cnt;
  }

  # display playfield
  function display(field) {
    for (i=0; i<lines; i++)
      printf("%s\033[K\n", substr(field, i*cols+1, cols));
  }
{
  # get generation 0 from stdin
  lines++;              # count all lines
  data=data""$0;        # add read data
} END {

  ## clear screen
  printf("\033[2J");

  ## calc number of columns
  cols=int(length(data)/lines);
  if ( (length(data)/lines) != cols) { printf("Incorrect data\n"); exit(1); }
  size = cols*lines;

  ## do number of runs
  for (run=0; run<runs; run++) {
    printf("\033[HItteration %d:\033[K\n", run);
    display(data);

    ## generate new data
    newdata="";
    for (cell=1; cell<=size; cell++) {
      oldstate = substr(data, cell, 1); # get old cell state
      newstate = DEAD;                  # default state is dead

      cnt = countAlive(cell);           # number of 'alives' around cell
      if (cnt == 3) newstate = ALIVE;   # 3 is always alive
      if (cnt == 2) newstate = oldstate; # no change

      newdata=newdata""newstate;
    }

    ## put newdata back and take a break
    data = newdata;
    if (sleep > 0) system(sprintf("sleep %.1f", sleep));
  }

  # display final itteration
  printf("\033[HItteration %d:\033[K\n", run);
  display(data);
}'


And here's a seed generator for life.sh:
Code:
#!/bin/sh
## genlife.sh -- Jun 25 2010, by Patsie
# generates random data for a first generation of Life
# usage: genlife.sh [<width> [<height> [<fill percentage>] ] ]
# defaults to a grid of 15x10 with 25% filling

awk -v width=${1:-15} -v height=${2:-10} -v perc=${3:-25} '
BEGIN { DEAD=" "; ALIVE="o"; srand(); }
END {
  for (y=0; y<height; y++) {
    for (x=0; x<width; x++)
      printf("%c", (rand()*100<perc)?ALIVE:DEAD);
    printf("\n");
  }
}' </dev/null


and finally 3 basic, static seed files.
(I tried putting the seed files between code tags, but they were still mangled up, so you'll have to do with the seed generator)
Any feedback on the scripts is kindly appreciated.

Regards,

Patsie


Top
 Profile  
 PostPosted: Wed Sep 01, 2010 2:48 pm   
Site Admin

Joined: Tue May 17, 2005 7:31 pm
Posts: 251
Location: Georgia
very nice.

i think you would have liked working on the bashbot project :)


Top
 Profile  
 PostPosted: Thu Sep 02, 2010 10:58 am   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
Thank you, I enjoyed making and sharing it.
I've seen bits of the Bbot forum and must say I enjoyed reading parts.

Soon I'll have a new nice awk script ready to asynchronously encrypt/decrypt data. So you can only encrypt with a public key and only decrypt with a private key.


Top
 Profile  
 PostPosted: Sun Nov 14, 2010 6:02 pm   

Joined: Sun Nov 14, 2010 5:53 pm
Posts: 4
can you explain in simple steps how to run this script? i ve tried the usage instructions you have but it gives me errors.
thanks


Last edited by ScullShot on Thu Jan 20, 2011 11:02 am, edited 1 time in total.

Top
 Profile  
 PostPosted: Sun Nov 14, 2010 11:35 pm   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
Just saying that 'it gives you errors', isn't very useful. I might as well be saying: 'it works fine here!'
What kind of errors? How did you start it up?


Top
 Profile  
 PostPosted: Thu Nov 18, 2010 3:57 pm   

Joined: Sun Nov 14, 2010 5:53 pm
Posts: 4
I tried something like ./genlife.sh | ./life.sh or ./genlife.sh 15 15 | ./life.sh 20 is that correct or did i messed it up? :P


Last edited by ScullShot on Thu Jan 20, 2011 11:03 am, edited 1 time in total.

Top
 Profile  
 PostPosted: Fri Nov 19, 2010 2:21 pm   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
That seems a perfectly fine way to start up some scripts, but without error message it will still be guessing with the lights off.


Top
 Profile  
 PostPosted: Fri Nov 19, 2010 5:22 pm   

Joined: Sun Nov 14, 2010 5:53 pm
Posts: 4
awk: cmd. line:36: fatal: division by zero attempted
i tried the other ways too but i get the same error. I didn't tried with <seed though because i dont understand what this is


Last edited by ScullShot on Thu Jan 20, 2011 11:03 am, edited 1 time in total.

Top
 Profile  
 PostPosted: Sat Nov 20, 2010 1:29 am   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
So it failed at the line cols = int(size/lines); with a division by zero, which means the number of lines read from the pipe (genlife.sh) is zero. It looks like genlife.sh is producing zero output on your PC.
I think it could be because the scripts use /bin/sh as a shell, your default sh isn't bash and I'm using bash'ism parameters for the default width, height and percentage parsing.
If the output of genlife is empty, try to change the sha-bang to #!/bin/bash and try again.
The same goes for life.sh ofcourse.
I also don't know if cygwin's version of sleep can handle floating point arguments (sleep 0.5)

<rant>
Cygwin is a really bad excuse for a *nix-like environment in my opinion. If you're running some form of Microsoft product and want to play with a *nix OS, I suggest running it through something like Virtualbox.
</rant>


Top
 Profile  
 PostPosted: Sat Nov 20, 2010 1:47 pm   

Joined: Sun Nov 14, 2010 5:53 pm
Posts: 4
i tried changing the sha-bang to #!/bin/bash but no change. i wish i knew more and figure it out myself..
Anyway thanks again for your help ill let you know if i manage to get this to work :)


Top
 Profile  
 PostPosted: Tue Apr 12, 2011 2:39 pm   

Joined: Tue Apr 12, 2011 2:36 pm
Posts: 3
Hello.
I tried to run this script , although it runs without any problem i thought that it would do another thing
I thought that there would be rows running like the authentic game of life
Can someone explain to me how does this works?

thats what i get : http://img16.imageshack.us/i/gameoflife.png/


Top
 Profile  
 PostPosted: Tue Apr 12, 2011 3:57 pm   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
What should happen you can see in the animated image here.
In your image I only see a static screen and no animation, so I can't really tell what's happening.
I do see that you're using Ubuntu. The default /bin/sh in Ubuntu is 'dash' (and not bash). Since those to shells are not 100% compatible with each other, you could try to change the first line of both scripts to #!/bin/bash instead of the #!/bin/sh that is there now.


Top
 Profile  
 PostPosted: Wed Apr 13, 2011 5:19 am   

Joined: Tue Apr 12, 2011 2:36 pm
Posts: 3
It is with #!/bin/bash both but as u say i see just a static image


Top
 Profile  
 PostPosted: Wed Apr 13, 2011 11:48 pm   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
well, it's clear now. you have switched around your scripts. First time around I thought that your printscreen looked funny. you run ./test 30 30 but the field doesn't neerly look anything like a 30x30 screen. More like something 50'ish by 10. Then I noticed that you pipe it through ./test2 50
Your 'test2' script is actually the seed generator and your 'test' script is the life.sh script.
So please name them accordingly and switch the order of them around (it's ./genlife.sh 30 30 | ./life.sh 50 not the other way around ;) )


Top
 Profile  
 PostPosted: Thu Apr 14, 2011 6:46 am   

Joined: Tue Apr 12, 2011 2:36 pm
Posts: 3
Yes thank you that was the mistake

Now i have 2 more questions

Is it easy to make these 2 scripts as 1? becouse i want to try it.
and
can u explain to me what do the numbers at the genlife script mean? its the number of the slots? for example if its 10 10 there will be 100 slots? and the start alive slots will be random?


Top
 Profile  
 PostPosted: Thu Apr 14, 2011 12:03 pm   
User avatar

Joined: Sun Jun 27, 2010 12:57 am
Posts: 192
Well, in my personal opinion it shouldn't be too hard to integrate both scripts into one. But that's of course if you have an intermediary knowledge level of awk.
As for your second question, the (first) 2 numbers for 'genlife.sh' are the width and height of the generated grid. So yes, genlife.sh 10 10 will create a field of 10 by 10 cells for a total of 100 cells.
This is also described in the first couple of comment lines of the script itself
Code:
# usage: genlife.sh [<width> [<height> [<fill percentage>] ] ]

You can optionally also pass a third parameter telling genlife how 'full' the grid must be. The number 0 will keep the grid empty, while 100 will fill every cell of the grid. Usually something between 15 and 75 percent fillrate will work best with 'life.sh' script.
You can run genlife.sh as a standalone script so you can see what it does. There is no need to pipe the output to life.sh.


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP