http://qs321.pair.com?node_id=11105910


in reply to simple game of life by new hand

glycine:

Just a few random notes on your implementation of Life:

In order to make code readable, naming is important. I found your code a little more difficult to understand than necessary, due to your subroutine names. If you revisit your program a few years from now, you may find the same difficulty. While having "interesting" names can be fun when programming is your hobby, it will be less so when you start coding with other people. Ideally, when you're reading code, you'd know pretty much what a subroutine does (in context) when you see the name of it. Once I read the implementation of magical_map() and lucky() and saw how they were used, I could tell what they were for. But that cost an extra couple of minutes.

You might want to read about object-oriented programming in perl, too. You're passing $world as a parameter to several functions, and in some cases that's a clue that you might have a natural class you could use. I'd consider making a World class, and then make light(), tomorrow(), twilight() and show_world() member functions for the class. Then you can make a constructor for your class that puts the size and cells in a hash so you don't have to pass the $size around all the time, too.
Something like:

{ package World; # Build a brand new world sub new { my ($class, $size) = @_; return bless { size=>$size, cells=>{ } }, $class; } sub light { my $world = shift; my $sparkle = shift; . . . } sub tomorrow { my $world = shift; my $size = $world->{size}; # Don't need to pass it as an arg! . . . } sub show_world { my $world = shift; my $size = $world->{size}; . . . } }

Then you can use it like this:

my $world; for my $cen (1...$exp) { $world = World->new(); my $live = magical_map($size, $creature); $world->light($live); $world->show_world(); . . . }

Now that I look at it a bit more, I'd suggest making magical_map be your constructor function, and pulling it into your class, too.

You don't use show_model() anywhere, so you may want to delete it. You don't use $today, either, so you could delete that, too. You nearly never use your log file, so you might consider either deleting it, or using it a bit more. In fact, you could add the date to the $log file, along with the parameters you used when you ran it, if you cared to do so.

Finally, I also found a bug in your code: When you're using the "-exp" option to do multiple life runs, the final result of the previous run is mixed in with the new initial board. You can fix it by clearing %world somewhere before calling light() the first time. I'd just do %world=(); immediately after the top-level for() statement.

Overall, it's a nifty little program. It's always interesting to me to see how other people approach a task I'm already familiar with. Sometimes you can offer helpful suggestions, and sometimes you can learn new ways to do things. You used a list of strings to encode the active cells, which is interesting in that it can let you have arbitrary board sizes without having to allocate a large rectangular array.

One thing I've seen in various Life implementations which you could try is to make the playing surface a "torus" such that the top and bottom are stitched together, as is the left and right border. That way, if you have a glider show up, it can fly off one border and have it wrap around and come in on the opposite side. To do so, is just a simple modification of your friends() function.

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: simple game of life by new hand
by glycine (Sexton) on Sep 10, 2019 at 10:42 UTC

    you are right, I had changed the name of subroutines and variables. and qx/date/ actually useless... thank you find the bug!

    I'm still learning about OOP perl, thank you for indicate this is good example to use OOP, I will rewrite it after.

    circular marginal is a interesting idea! when you find some big/beautiful pattern the wall is so annoying. infinite board maybe a good choice, but it need a dynamic display...

    have a nice day :)