Conway's Game Of Life


Closed Thread
Results 1 to 40 of 46

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default 1024 led Code optimisation: Conway's Game Of Life

    This is progressing very nicely and I now have 1024 leds in colour.

    In order to conserve RAM I got rid of two of the colour arrays for the NeoPixels and just kept a single array with RGB info in bits 5,6,7 and brightness info in bit 0-4.


    So optimising code is my next priority.

    The actual WS2812B led driving code is limited by strict timing protocols and is already in assembler so we will ignore that for now.

    Evaluation of the 1024 grid life matrix must take some time so perhaps you can have a look at the code and if any glaring time sucking stuff leaps out make suggestions?

    This part evaluates the primary 32 x 32 matrix and poulates a secondary 32 x 32 matrix with the updated information based on 'life' standard rules.

    Code:
    '----------------------- Also creating a newled data array to be displayed on next generation -------------
    
    FOR counter = 0 TO 1023
    
    	population = 0 :topedge = 0 :botedge = 0 :lefedge = 0 :rigedge = 0
    
    'Grid Edge Detection
    	
    	IF counter < 32 THEN botedge = 1
    
    	IF counter > 991 THEN topedge = 1
    	
    	IF counter = 0 OR counter = 32 OR counter = 64 OR counter = 96 OR counter = 128 OR counter = 160 OR counter = 192 OR counter = 224_ 
        or counter = 256 OR counter = 288 OR counter = 320 OR counter = 352 OR counter = 384 OR counter = 416 OR counter = 448 OR counter = 480_
        or counter = 512 OR counter = 544 OR counter = 576 OR counter = 608 OR counter = 640 OR counter = 672 OR counter = 704 OR counter = 736_
        or counter = 768 OR counter = 800 OR counter = 832 OR counter = 864 OR counter = 896 OR counter = 928 OR counter = 960 OR counter = 992_
        THEN     
        lefedge = 1
    	ENDIF 	
    	
      	IF counter = 31 OR counter = 63 OR counter = 95 OR counter = 127 OR counter = 159 OR counter = 191 OR counter = 223_ 
        or counter = 255 OR counter = 287 OR counter = 319 OR counter = 351 OR counter = 383 OR counter = 415 OR counter = 447 OR counter = 479_
        or counter = 511 OR counter = 543 OR counter = 575 OR counter = 607 OR counter = 639 OR counter = 671 OR counter = 703 OR counter = 735_
        or counter = 767 OR counter = 799 OR counter = 831 OR counter = 863 OR counter = 895 OR counter = 927 OR counter = 959 OR counter = 991_
        THEN    
        rigedge = 1
    	ENDIF    
    	
    'Grid Evaluation	
    	        	
    	
    	IF led [counter-1] > 0 AND counter > 0 THEN
    	    Colour[population] = led[counter-1]
    		population = population + 1
    	ENDIF
    	
    	IF led [counter+1] > 0 AND counter < 1023 THEN
    	    Colour[population] = led[counter+1]
    		population = population + 1  		
    	ENDIF
    	
    	IF botedge = 0 THEN
    		IF led [counter-31] > 0 THEN
    		    Colour[population] = led[counter-31]
    			population = population + 1			
    		ENDIF
    		IF led [counter-32] > 0 THEN
    		    Colour[population] = led[counter-32]  
    			population = population + 1
    		ENDIF
    		IF  rigedge = 0 and led [counter-33] > 0 THEN
    		    Colour[population] = led[counter-33]
    			population = population + 1
    		ENDIF
    	ENDIF
    	
    	IF topedge = 0 THEN
    		IF led [counter+31] > 0 THEN
    		    Colour[population] = led[counter+31]
    			population = population + 1
    		ENDIF
    		IF led [counter+32] > 0 THEN
    		    Colour[population] = led[counter+32]
    			population = population + 1
    		ENDIF
    		IF  rigedge = 0 and led [counter+33] > 0 THEN 
    		    Colour[population] = led[counter+33]
    			population = population + 1
    		ENDIF
    	ENDIF
    	
    	lednew[counter] = led[counter]
    	
    	IF led[counter] > 0 THEN
    		IF population > 3 OR population < 2 THEN
    			lednew[counter] = 0
    		ENDIF
    	ENDIF
    	
    	IF led[counter] = 0 THEN
    		IF population = 3 THEN
    		
    		    if Colour[0] = Colour[1] then
    		    lednew[counter] = Colour[0]
    		    
    		    elseif Colour[0] = Colour[2] then
                lednew[counter] = Colour[0]
                
                elseif Colour[1] = Colour[2] then
                lednew[counter] = Colour[1]
                
                else   
                
                lednew[counter] = led[counter]     'White LED
    		    
    		    endif   	
    			
    		ENDIF
    	ENDIF
    NEXT counter

    The second section moves data from the led matrix into the NeoPixel led array for display.
    I previously posted about this due to the led matrix and NeoPixel matrix having a different layout.

    It all works well at about 3hz but i'm looking for speed increases if possible.

    Code:
       	alive = 0	            'Clears alive accumulator
    	dead = 0                'Clears dead checksum accumulator
    
      FOR Row = 0 to 31			' Cycle thru 32 rows
        
         FOR Col = 0 to 31			' of 32 pixels each          
           InPtr = (Row * 32) + Col   '  
           led[InPtr] = lednew[InPtr]         
           IF Row.0 = 0 THEN	' If the row number is even   
             OutPtr =  InPtr        ' Output pixels in true order       
           ELSE
             OutPtr = (Row * 32) + (31-Col)   ' Output pixels in reversed order        
           ENDIF
           
           IF led[InPtr] > 0 THEN
           NeoLed(OutPtr) = Led[InPtr]	
           alive = alive + 1
           dead = dead + InPtr
    	   else 
           NeoLed(OutPtr) = 0	
    	   ENDIF
          
         NEXT
      NEXT

    The current colour code can be seen running in this short video.


  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    Hi,
    It might very well be that I don't quite understand what you're doing in the code but replacing all that OR logic with some math increases the performance in that particulat section of the code by a factor of 8 or so (won't help if it doesn't do what you want but by all means do try it):
    Code:
    '----------------------- Also creating a newled data array to be displayed on next generation -------------
    
    FOR counter = 0 TO 1023
    
    	population = 0 :topedge = 0 :botedge = 0 :lefedge = 0 :rigedge = 0
    
    'Grid Edge Detection
    	
      Temp = Counter // 32
    
      If Temp = 0 THEN
        lefedge = 1
      ENDIF
    
      IF Temp = 31 THEN
        rigedge = 1
      ENDIF    
    	
    'Grid Evaluation
    There's likely some cycles to squeze here and there but try the above for starters.

    /Henrik.

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,645


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    would this work too ?

    Temp = Counter & 65504
    If Temp = 0 THEN
    lefedge = 1
    ENDIF


    IF Temp = 31 THEN
    rigedge = 1
    ENDIF
    Warning I'm not a teacher

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    Here's another tiny tweak to the array transformation routine that makes quite a difference:
    Code:
      FOR Row = 0 to 31			' Cycle thru 32 rows
         
         TempW = ROW * 32       ' Precalculate this instead of doing it every time thru the loop
         
         FOR Col = 0 to 31			' of 32 pixels each          
           InPtr = (TempW) + Col   '  
           led[InPtr] = lednew[InPtr]         
           IF Row.0 = 0 THEN	' If the row number is even   
             OutPtr =  InPtr        ' Output pixels in true order       
           ELSE
             OutPtr = (TempW) + (31-Col)   ' Output pixels in reversed order        
           ENDIF
           
           IF led[InPtr] > 0 THEN
           NeoLed(OutPtr) = Led[InPtr]	
           alive = alive + 1
           dead = dead + InPtr
    	   else 
           NeoLed(OutPtr) = 0	
    	   ENDIF
          
         NEXT
         NEXT

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    What size are all the different arrays?

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    In the Grid Evalutaion section, precalculating the Array index values and replacing the AND-logic with nested IF/THEN saves Another bunch of cycles
    Code:
    'Grid Evaluation	
    
    CntPlus33 VAR WORD
    CntPlus32 VAR WORD
    CntPlus31 VAR WORD
    CntPlus1  VAR WORD
    
    CntMinus33 VAR WORD
    CntMinus32 VAR WORD
    CntMinus31 VAR WORD
    CntMinus1  VAR WORD
    
    CntPlus33 = Counter + 33
    CntPlus32 = Counter + 32
    CntPlus31 = Counter + 31
    CntPlus1 = Counter +1
    
    CntMinus33 = Counter - 33
    CntMinus32 = Counter - 32
    CntMinus31 = Counter - 31
    CntMinus1 = Counter - 1	        	
    	
    	IF led[CntMinus1] > 0 THEN
          IF counter > 0 THEN
    	    Colour[population] = led[CntMinus1]
    		population = population + 1
    	  ENDIF
    	ENDIF
    	
    	IF led[CntPlus1] > 0 THEN
          IF counter < 1023 THEN
    	    Colour[population] = led[CntPlus1]
    		population = population + 1  		
           ENDIF
        ENDIF
    	
    	IF botedge = 0 THEN
    		IF led [CntMinus33] > 0 THEN
    		    Colour[population] = led[CntMinus33]
    			population = population + 1			
    		ENDIF
    		IF led [CntMinus32] > 0 THEN
    		    Colour[population] = led[CntMinus32]  
    			population = population + 1
    		ENDIF
    		IF  rigedge = 0 and led [CntMinus33] > 0 THEN
    		    Colour[population] = led[CntMinus33]
    			population = population + 1
    		ENDIF
    	ENDIF
    	
    	IF topedge = 0 THEN
    		IF led [CntPlus31] > 0 THEN
    		    Colour[population] = led[CntPlus31]
    			population = population + 1
    		ENDIF
    		IF led [CntPlus32] > 0 THEN
    		    Colour[population] = led[CntPlus32]
    			population = population + 1
    		ENDIF
    		IF  rigedge = 0 and led [CntPlus33] > 0 THEN 
    		    Colour[population] = led[CntPlus33]
    			population = population + 1
    		ENDIF
    	ENDIF
    It's not nearly as elegant but it does increase the performance a bit. All in all that 1024 iteration FOR/NEXT loop took 265ms to execute on my test board, now it's 67. Obviously I don't know if it still WORKS so it might all be for nothing :-)

    /Henrik.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    I'm very grateful for all these interesting replies. Thank you.

    There are three basic 1024 element byte arrays.


    Led var byte[1024] used to hold the current generation of cells


    LedNew var byte [1024] used to to hold the next generation of cells (This is copied into the Led array after evaluation is completed)


    NeoLed var byte [1024] used to hold the NeoPixel led data.

    This third array is required because the layout of the NeoPixels grid is one continuous string of 1024 leds arranged like a snakes and ladders board.

    This is different to the other two arrays which are a conventional X/Y grid layout, so the Led data has to be parsed and re-organised to display correctly on the neopixel grid.


    How are people timing the loops etc.
    I would be interested in that code so I can see what difference changes make.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Conway's Game Of Life

    There's also an array called colour, how large is that?

    For this I just toggle an output and measure it with the scope but for more precise measurements I use one of the onboard timers. Reset it, start it, execute code, stop it, output its value.
    Doing that it's important to have SOME idea about what you're measuring in order to set up the timer with proper prescaling value to make sure you don't overflow, giving you false readings.

Similar Threads

  1. programming jumping game
    By bokken in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 17th February 2012, 06:40
  2. Simon Game
    By flotulopex in forum Code Examples
    Replies: 1
    Last Post: - 4th November 2010, 06:25
  3. EEPROM life expectancy?
    By muddy0409 in forum General
    Replies: 3
    Last Post: - 1st May 2007, 12:44
  4. home brew game console W interface
    By PICMAN in forum General
    Replies: 1
    Last Post: - 15th March 2005, 22:25
  5. Game port to USB adaptor
    By Squibcakes in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 24th September 2004, 03:16

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts