Shop OBEX P1 Docs P2 Docs Learn Events
John Conway's Game of Life — Parallax Forums

John Conway's Game of Life

Spork FrogSpork Frog Posts: 212
edited 2007-09-07 22:52 in Propeller 1
Hello all!

This is a simple implementation of John Conway's Game of Life, using a 20x20 grid, on a Hydra with VGA output. Suprisingly, I don't think this has been done yet with the Hydra.

Wrtitten completley in Spin as a self programming test over about 6 hours.

Questions? Comments? Criticisms? Concerns? I'd like to hear them!

Attatched is the source and a picture. Here's a video of it in action (on youtube.):
EDITED: See new version below

Enjoy!
Spork

NEW VERSION UPLOADED: See posts below

Post Edited (LarryHedgehog) : 8/7/2007 9:31:54 PM GMT

Comments

  • mparkmpark Posts: 1,305
    edited 2007-08-06 05:37
    Kewl! One of these days I'm gonna have to hook up a VGA monitor; meanwhile, thanks for the youtube video.

    But do we call you Larry or Spork?
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-06 12:35
    lol whoops, forget about the little things like that... yeah either. doesn't matter.

    And I'm already working on the next version of this as well, which will hopefully go fullscreen instead of just 20x20 and with mouse control as well. We'll see though with the speed... I put some nasty "if" statements in there...
  • potatoheadpotatohead Posts: 10,260
    edited 2007-08-06 19:59
    I've an idea:

    Use a lookup table. Each cell has 8 neighbors right? So, collect their values and use them as a lookup into an array that has the resulting cell state already pre-computed.

    00000000 = 0
    00001010 = 1
    00010101 = 0

    etc...

    ..or would the bit mashing take up more compute time than simple if - then statements?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-07 12:23
    I don't think that's the problem. I believe the biggest problem is individually checking each cell's eight neighbors, making for a total of 3200 cells to check and tally. But, I'm still not sure there's a faster way.
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-07 21:41
    Alright, here's the next version. This version's gone fullscreen and added mouse support.

    youtube.com/watch?v=b6i8dxWyWgw

    TODO:
    -Fix speed issues. As seen in the first part of the video, it's horiffically slow. I think I'll split the screen into 4 parts and have 4 cogs render each part, with a fifth cog controlling them all. I'll also see what I can do about the actual loop, to see what can be improved.
    -Mouse action is a little jerky.

    Enjoy!
    Spork

    EDITED: Attatchment removed. Scroll down for newest version.

    Post Edited (Spork Frog) : 9/1/2007 1:32:45 AM GMT
    567 x 446 - 29K
  • AndreLAndreL Posts: 1,004
    edited 2007-08-08 02:38
    Life is a "cellular automata" of course with a specific rule, there are an infinite number of CAs that do all kinds of crazy things, you should set up a syntax for the rules and then let it select random rules, etc. and then draw the images on the screen. Check out the work of Rudy Rucker on this for example, he has a lot of publications on CAs.

    Andre'
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-08 12:27
    So basically you're suggesting I integrate options for more rules than just John Conway's set? Interesting idea. But I think I want to perfect what I have first. I definetly will do that in the future however.
  • deSilvadeSilva Posts: 2,967
    edited 2007-08-08 18:51
    Ken Pitts had the GoL in the Object Exchange since February obex.parallax.com/objects/141/.. As Andre remarked, CA are a small but interesting part of Computer Science. There is still a lot of research going on from time to time. A hot off-spring from CA are multi agent based simulations.

    John Conway is an esteemd great grand father of this all..
  • epmoyerepmoyer Posts: 314
    edited 2007-08-08 23:56
    Spork said...
    I don't think that's the problem. I believe the biggest problem is individually checking each cell's eight neighbors, making for a total of 3200 cells to check and tally. But, I'm still not sure there's a faster way.

    One way to speed the processing up considerably (for this particular set of CA rules) is to take advantage of the fact that 1) The patterns which evolve from life are never heavily populated (i.e. there are typically more empty cells than full) and 2) The rule set in life depends only upon the number of neighbors and not their relative positions. Having made those two observations, you can create a "neighbor count" array of 20 x 20 bytes (i.e. one for cell). For each pass you zero the neighbor count array, then search the cell array for populated cells. Most will be empty, and you can move on doing no math at all. When you do find a cell, increment the neighbor count for all surrounding cells. When done, make another pass and apply the spawn/survive/die logic to each cell based on its neighbor count. You'll end up having to access far fewer than 3200 (8x20x20) cells and should get a significant speed improvement. For very sparse screens you'll be down around 400 (cell check pass) + 200(incrementing adjacent cells on 25populated cells) = 600 or so cell accesses instead of 3200, which is about a 6x boost in execution speed.

    Well, actually theres also the pass to zero the array (400) and the pass to check the array when done (400), which puts you at 1400 instead of 3200 so perhaps its a 2x increase in speed, but you can do some things to speed that up as well. For one thing you can use nibbles instead of bytes (i.e. store two counts per byte) which will halve the size of your neighbor count array, and you can use a block fill to zero it which will be very fast.
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-09 12:31
    Very interesting idea. Might try to do that, but for now I found another problem that was a huge issue:

    The propeller can only do one-dimensional arrays. But, in this scenario, I needed a 2-dimensional array. So I was mapping one virtually onto the array using some quick math: array[noparse][[/noparse]x + (y * 20)]. While this works, because the propeller has no built-in multiply instruction, it has to add. A lot. So, instead, I decided on this: So you have a location array[noparse][[/noparse]i ]. To the left of it is array[noparse][[/noparse]i-1], right is array[noparse][[/noparse]i+1], below it is array[noparse][[/noparse]i+20]... and using only addition and subtraction there instead. That alone boosted performance about 3x.

    But the more I think of it, the more I realize that neighbor count array is a good idea. I'll try that.
  • epmoyerepmoyer Posts: 314
    edited 2007-08-09 15:31
    Very true! Even in a processor with a built-in multiply opcode multiplies can kill you because they still take much longer to run than other opcodes.

    It helps that in Life you are only ever looking at adjacent cells, so the offsets can be precomputed as you stated and you can avoid the multiplication altogether. In cases where you need rapid random access to to an array a useful trick is to dimension your array so the horizontal width is a power of two, and then use bit shifts instead of multiplies to calculated the offset. For instance, if you needed to randomly access a 20x20 array you would allocate space for a 32 wide (X) by 20 tall (Y) array and then the offset of any location can be quickly calculated by OFFSET = X << 5 + Y (where << is a left bit shift (in C; I Can't remember if the SPIN syntax for that operation is the same)). X << 5 is equivalent to X * 32 but it executes extremely fast and can be done by a single processor-native instruction.
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-10 01:38
    Believe it or not, I thought of that. But I didn't want to use up more RAM than was needed since it seems to come sparingly on the Propeller.

    By the way, I don't know if you saw v0.2, but the grid is now 98x46.

    I'm liking this. Actually forcing myself to learn efficient coding methods, versus PC programming where you can really write code (almost) as inefficiently as you want to and get away with it because of how fast the CPU is.
  • epmoyerepmoyer Posts: 314
    edited 2007-08-10 15:35
    I know what you mean. I was developing an embedded system for work and had spent the better part of a year working with a Motorola ColdFire running 66MHz. Then I started mucking about with OpenGL for fun and ended up developing a PC game just to learn my way around Visual Studio and OpenGL ( www.experimentalgameplay.com/game.php?g=339 ). At first I was very very conservative about multiplies and complex operations, and then about a quarter of the way into it I realized I had gobs more computing power than I was used to and I could pretty much just do whatever the heck I wanted! How liberating!

    So anyway, here's another trick; For the cost of TWO shifts and TWO adds you could (again, if you wanted general purpose random access to your array) drop you horizontal width by 2 and then decompose your 98-2=96 into two shifts and three adds (Offset = X << 6 + X << 4 + 5 + Y). X<<6 is equivalent to X * 64, and X<<5 is equivalent to X*32, so you get X*64 + X*32 = X * (64+32) = X * 96.

    If you don't want give up 2 columns, then reinterpret your array as being rotated 90 degrees, and imagine it as a 46x98 array (but still displayed as 98x46), add two to the new "width" to get 48 (so you're wasting two columns, but that's not too much overhead), then you can play the same trick using Y<<5 + Y<<4 = Y*32+Y*16 = Y*48.
  • Spork FrogSpork Frog Posts: 212
    edited 2007-08-29 21:29
    After a short break, I'm back to working on this again.

    I've refined the mouse movement so it's not quite as "jerky" as it was before. Bounds inside the mouse driver, such as the new version from Parallax, would have been nice, but it's still feasible without them.

    EDIT: I've refined the code as far as I wanted to. Not seeing quite as much speed increase as I anticipated. ASM port soon

    Post Edited (Spork Frog) : 8/30/2007 1:28:41 AM GMT
  • Spork FrogSpork Frog Posts: 212
    edited 2007-09-01 01:26
    Spin Game of Life v1.0. No real asthetical improvements here- just a few typos fixed and a whole lotta speed increase, up to about 0.72 seconds/frame (up from about 3 and a half seconds in the last version.) Still fullscreen grid (98x46). All multiplies and divides removed and replaced with adds and shifts.

    Started ASM development today. However, coding on this project will most likely be reduced because of school starting again soon.

    Post Edited (Spork Frog) : 9/1/2007 1:31:58 AM GMT
  • BamseBamse Posts: 561
    edited 2007-09-07 05:05
    This is awesome...

    I just got my Hydra hooked up to a VGA monitor and got it running...
    Pretty cool to see all the cells wandering around...

    My Hydra has been in a box for a while, got a new house and didn't unpack the Hydra until a couple of weeks ago.
    I was a little bit nervous for a while when I hooked it up to my TV and nothing, just a blank screen... wink.gif
    Luckily it was the TV that broke during the move and not the Hydra.
    So I managed to get a left over VGA monitor from my mother in law and I'm finally back to programming...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Living on the planet Earth might be expensive but it includes a free trip around the sun every year...

    Experience level:
    [noparse][[/noparse] ] Let's connect the motor to pin 1, it's a 6V motor so it should be fine.
    [noparse][[/noparse] ] OK, I got my resistors hooked up with the LEDs.
    [noparse][[/noparse]X] I got the Motor hooked up with the H-bridge and the 555 is supplying the PWM.
    [noparse][[/noparse] ] Now, if I can only program the BOE-BOT to interface with he Flux Capacitor.
    [noparse][[/noparse] ] I dream in SX28 assembler...

    /Bamse
  • Spork FrogSpork Frog Posts: 212
    edited 2007-09-07 22:52
    Thanks for the compliments.
Sign In or Register to comment.