Search code examples
wolfram-mathematicaconways-game-of-life

Optimising the game of life


I'm writing a game of life program in mathematica however there is a caveat in that I need to be able to apply the reproduction rules to some percentage of the cells, I want to try a new method using MapAt but liveNeighbors doesn't work elementwise, and I can't think of a way of fixing it without doing exactly what I did before (lots of messy indexing), does anyone have any suggestions? (I am assuming this will be more efficient then the old method, which is listed below, if not please let me know, I am just a beginner!).

What I am trying to do:

 Map[ArrayPlot,FixedPointList[MapAt[update[#,liveNeighbors[#]]&,#,coords]&,Board, 1]]

What I have done already:

LifeGame[ n_Integer?Positive, steps_] := Module [{Board, liveNeighbors, update},
  Board = Table [Random [Integer], {n}, {n}];
  liveNeighbors[ mat_] := 
   Apply[Plus,Map[RotateRight[mat,#]&,{{-1,-1},{-1, 0},{-1,1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}]];
  update[1, 2] := 1;
  update[_, 3] := 1;
  update[ _, _] := 0;
  SetAttributes[update, Listable];
 Seed = RandomVariate[ProbabilityDistribution[0.7 UnitStep[x] + 0.3 UnitStep[x - 1], {x, 0, 1, 1}], {n, n}];
 FixedPointList[Table[If[Seed[[i, j]] == 1,update[#[[i, j]], liveNeighbors[#][[i, j]]],#[[i, j]]], {i, n}, {j, n}]&, Board, steps]]]

Thanks!


Solution

  • In[156]:= 
    LifeGame2[n_Integer?Positive, steps_] := 
     Module[{Board, liveNeighbors, update},
      Board = RandomInteger[1, {n, n}];
      liveNeighbors[mat_] := 
       ListConvolve[{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, 
        ArrayPad[mat, 1, "Periodic"]];
      SetAttributes[update, Listable];
      Seed = RandomVariate[BernoulliDistribution[0.3], {n, n}];
      update[0, el_, nei_] := el;
      update[1, 1, 2] := 1;
      update[1, _, 3] := 1;
      update[1, _, _] := 0;
      FixedPointList[MapThread[update, {Seed, #, liveNeighbors[#]}, 2] &, 
       Board, steps]
      ]
    

    This implementation does the same as yours, except is quite a lot faster:

    In[162]:= AbsoluteTiming[
     res1 = BlockRandom[SeedRandom[11]; LifeGame[20, 100]];]
    
    Out[162]= {6.3476347, Null}
    
    In[163]:= Timing[BlockRandom[Seed[11]; LifeGame2[20, 100]] == res1]
    
    Out[163]= {0.047, True}