+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Software Libraries (/forum-10.html)
+--- Forum: HP Prime Software Library (/forum-15.html)
+--- Thread: Conway's game of life [faster version] (/thread-555.html)
Conway's game of life [faster version] - patrice - 01-28-201408:05 AM
Here is a Conway's Game of Life.
The code of the starting sets is the RLE coding usually found on Internet.
Version 1.0 Time per generation: 5226 ms
The board is 80x80 and with zoom by 3x
The number of neighbors is stored in the color scheme. It avoid the need of other storage.
Optimization:
- Each pixel/cell stores neighbors only horizontally, so each partial count is used in 3 different cells.
But it is still highly unoptimized.
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
Black, White;
LNext()
BEGIN
LOCAL px, py, Clr, Tmp;
// Calcul Voisins
FOR py FROM 1 TO 78 DO
FOR px FROM 1 TO 78 DO
Tmp:= BITAND(GETPIX_P(px-1, py),#800h)+BITAND(GETPIX_P(px, py),#800h)+BITAND(GETPIX_P(px+1, py),#800h);
Tmp:=BITAND(GETPIX_P(px, py),White)+#18h-BITSR(Tmp,8);
PIXON_P(px, py, Tmp);
END;
END;
FOR py FROM 1 TO 78 DO
FOR px FROM 1 TO 78 DO
Tmp:= BITAND(GETPIX_P(px, py-1),#18h)+BITAND(GETPIX_P(px, py),#18h)+BITAND(GETPIX_P(px, py+1),#18h);
IF (Tmp == #18h AND BITAND(GETPIX_P(px, py),#800h) <> 0) OR ((Tmp == #20h OR Tmp == #18h) AND BITAND(GETPIX_P(px, py),#800h) == 0) THEN
Clr:= Black;
ELSE
Clr:= White;
END;
PIXON_P(px, py, Clr+BITAND(GETPIX_P(px, py),#18h));
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,0,79,79);
END;
RLEMap (px, py, RLE, ClrOn)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= 0; Col:= 0; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1); // pour debogage
CASE
IF INSTRING("0123456789", MID(RLE, Ptr, 1)) <> 0 THEN Cnt:= Cnt*10+EXPR(MID(RLE, Ptr, 1)); END;
IF MID(RLE, Ptr, 1) == "$" THEN Row:= Row+MAX(1, Cnt); Col:= 0; Cnt:= 0; END;
IF INSTRING("b.", MID(RLE, Ptr, 1)) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", MID(RLE, Ptr, 1)) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
PIXON_P(px+Col, py+Row, ClrOn);
END;
Cnt:= 0; END;
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,0,79,79);
END;
EXPORT Life(St)
BEGIN
LOCAL Kb;
Black:= #0h; White:= #F8F8E0h;
RECT_P(0,0,319,239,White);
IF St == 1 THEN
RLEMap (10, 11, "3o!", Black); // Blinker
RLEMap (23, 14, "bo$3o$obo$3o$bo!", Black); // Pulsar
LNext();
RLEMap (10, 16, "b3o$3o!", Black); // Toad
RLEMap (40, 14, "bo$3o$obo$3o$bo!", Black); // Pulsar
RLEMap (10, 26, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!", Black); // Canon
END;
IF St == 2 THEN
RLEMap (27, 18, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!", Black);
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!", Black);
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!", Black); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (50, 60, "bo$3bo$2o2b3o!", Black); // Acorn
END;
REPEAT LNext(); Kb:= GETKEY(); UNTIL Kb==4;
END;
Version 1.1 Time per generation: 2184 ms
Optimizations:
- avoid empty lines recalc.
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
Lignes, Black, White;
LNext()
BEGIN
LOCAL px, py, Clr, Tmp;
// Calcul Voisins
FOR py FROM 1 TO 78 DO
CASE
IF Lignes[py+1] == 1 THEN
LINE_P(0,py,79,py,White);
Lignes[py+1] := 0;
END;
IF Lignes[py+1] == 2 THEN
FOR px FROM 1 TO 78 DO
Tmp:= BITAND(GETPIX_P(px-1, py),#800h)+BITAND(GETPIX_P(px, py),#800h)+BITAND(GETPIX_P(px+1, py),#800h);
Tmp:=BITAND(GETPIX_P(px, py),White)+#18h-BITSR(Tmp,8);
PIXON_P(px, py, Tmp);
END;
END;
END;
END;
FOR py FROM 1 TO 78 DO
IF Lignes[py]+Lignes[py+1]+Lignes[py+2] <> 0 THEN
IF Lignes[py+1] == 2 THEN Lignes[py+1] := 1; END;
FOR px FROM 1 TO 78 DO
Tmp:= BITAND(GETPIX_P(px, py-1),#18h)+BITAND(GETPIX_P(px, py),#18h)+BITAND(GETPIX_P(px, py+1),#18h);
IF (Tmp == #18h AND BITAND(GETPIX_P(px, py),#800h) <> 0) OR ((Tmp == #20h OR Tmp == #18h) AND BITAND(GETPIX_P(px, py),#800h) == 0) THEN
Clr:= Black; Lignes[py+1] := 2;
ELSE
Clr:= White;
END;
PIXON_P(px, py, Clr+BITAND(GETPIX_P(px, py),#18h));
END;
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,0,79,79);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= 0; Col:= 0; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1); // pour debogage
CASE
IF INSTRING("0123456789", MID(RLE, Ptr, 1)) <> 0 THEN Cnt:= Cnt*10+EXPR(MID(RLE, Ptr, 1)); END;
IF MID(RLE, Ptr, 1) == "$" THEN Row:= Row+MAX(1, Cnt); Col:= 0; Cnt:= 0; END;
IF INSTRING("b.", MID(RLE, Ptr, 1)) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", MID(RLE, Ptr, 1)) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
PIXON_P(px+Col, py+Row, Black);
END;
Cnt:= 0; Lignes[py+Row+1]:= 2;
END;
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,0,79,79);
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, Lap;
Black:= #0h; White:= #F8F8E0h;
Lignes:= MAKELIST(0,A,0,79);
RECT_P(0,0,319,239,White);
IF St == 1 THEN
RLEMap (10, 11, "3o!"); // Blinker
RLEMap (23, 14, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (10, 16, "b3o$3o!"); // Toad
RLEMap (40, 14, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (10, 26, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Canon
END;
IF St == 2 THEN
RLEMap (27, 18, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!");
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!");
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (50, 60, "bo$3bo$2o2b3o!"); // Acorn
END;
REPEAT
Lap:= TICKS();
LNext();
Lap:= TICKS()-Lap;
// to display time between screen updates
TEXTOUT_P(Lap,0,160,0,Black,80,White);
Kb:= GETKEY();
UNTIL Kb==4;
END;
Version 1.2 Time per generation: 763 ms
Optimizations:
- avoid empty lines and empty trails recalc.
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// 1.1 2014/02 Little optimization for speed to avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed to avoid recalc of empty left and right
Lignes, Black, White;
LNext()
BEGIN
LOCAL px, py, db, fn, Clr, Tmp;
// Calcul Voisins
FOR py FROM 2 TO 81 DO
CASE
IF Lignes[py,1] == 1 THEN
LINE_P(0,py,79,py,White);
Lignes[py] := {0,80,0};
END;
IF Lignes[py,1] == 2 THEN
db:= MAX(Lignes[py,2]-1,1); fn:= MIN(Lignes[py,3]+1,78);
Lignes[py] := {2,80,0};
FOR px FROM db TO fn DO
Tmp:= #18h-BITSR(BITAND(GETPIX_P(px-1, py),#800h)+BITAND(GETPIX_P(px, py),#800h)+BITAND(GETPIX_P(px+1, py),#800h),8);
IF Tmp <> #0 THEN Lignes[py] := {2,MIN(Lignes[py,2],px),MAX(Lignes[py,3],px)}; END;
PIXON_P(px, py, BITAND(GETPIX_P(px, py),White)+Tmp);
END;
END;
END;
END;
FOR py FROM 2 TO 81 DO
IF Lignes[py-1,1]+Lignes[py,1]+Lignes[py+1,1] <> 0 THEN
db:= MIN(Lignes[py-1,2],Lignes[py,2],Lignes[py+1,2]); fn:=MAX(Lignes[py-1,3],Lignes[py,3],Lignes[py+1,3]);
IF Lignes[py,1] == 2 THEN Lignes[py,1]:= 1; END;
FOR px FROM db TO fn DO
Tmp:= BITAND(GETPIX_P(px, py-1),#18h)+BITAND(GETPIX_P(px, py),#18h)+BITAND(GETPIX_P(px, py+1),#18h);
IF (Tmp == #18h AND BITAND(GETPIX_P(px, py),#800h) <> 0) OR ((Tmp == #20h OR Tmp == #18h) AND BITAND(GETPIX_P(px, py),#800h) == 0) THEN
Clr:= Black; Lignes[py] := {2,MIN(Lignes[py,2],px),MAX(Lignes[py,3],px)};
ELSE
Clr:= White;
END;
PIXON_P(px, py, Clr+BITAND(GETPIX_P(px, py),#18h));
END;
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,2,79,81);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= py+2; Col:= px+1; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1); // for debug
CASE
IF INSTRING("0123456789", MID(RLE, Ptr, 1)) <> 0 THEN Cnt:= Cnt*10+EXPR(MID(RLE, Ptr, 1)); END;
IF MID(RLE, Ptr, 1) == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px+1; Cnt:= 0; END;
IF INSTRING("b.", MID(RLE, Ptr, 1)) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", MID(RLE, Ptr, 1)) <> 0 THEN
Lignes[Row,1]:= 2; Lignes[Row,2]:= MIN(Lignes[Row,2],Col);
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
PIXON_P(Col, Row, Black);
END;
Cnt:= 0; Lignes[Row,3]:= MAX(Lignes[Row,3],Col);
END;
END;
END;
BLIT_P(G0,80,0,319,239,G0,0,2,79,81);
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, Lap;
Black:= #0h; White:= #F8F8E0h;
Lignes:= MAKELIST({0,80,0},A,0,83);
RECT_P(0,0,319,239,White);
IF St == 1 THEN
RLEMap (10, 11, "3o!"); // Blinker
RLEMap (23, 14, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (10, 16, "b3o$3o!"); // Toad
RLEMap (40, 14, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (10, 26, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Canon
END;
IF St == 2 THEN
RLEMap (0, 0, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!");
END;
IF St == 3 THEN
RLEMap (0, 0, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
REPEAT
Lap:= TICKS();
LNext();
Lap:= TICKS()-Lap;
// to display time between screen updates
TEXTOUT_P(Lap,0,160,0,Black,80,White);
Kb:= GETKEY();
UNTIL Kb==4;
END;
Version 2.0 Time per generation: 218 ms
New method: The board is stored as a bitmap
The board is 80x80 and with zoom by 3x
Optimization: counting is done by bitwise operations only
Calc need to be set as Hexadecimal 64 bits (rev 6030: not needed anymore thanks to new pragme feature)
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// The 2 lower bits of each pixels is used to store neighb on right and left.
// 1.1 2014/02 Little optimization for speed
// Avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed
// Avoid recalc of empty left and right
// 2.0 2014/02 Even faster, better scaling
// using bitmap storage and bitwise operations
Lignes;
LOcc(Lst) // Occurence
BEGIN
LOCAL v1, v2, v3, v4, sx, cx;
v1:= #0; v2:= #0; v3:= #0; v4:= #0;
FOR sx FROM 1 TO SIZE(Lst) DO
cx:= Lst(sx);
v4:= BITOR(v4,BITAND(v3,cx)); v3:= BITOR(v3,BITAND(v2,cx));
v2:= BITOR(v2,BITAND(v1,cx)); v1:= BITOR(v1,cx);
END;
RETURN {v1, v2, v3, v4};
END;
LNext()
BEGIN
LOCAL T1, T2, T3, L, Tmp;
Tmp:= MAKELIST({#0,#0},A,1,82);
FOR L FROM 2 TO 81 DO
IF BITOR(Lignes(L-1,1),Lignes(L,1),Lignes(L+1,1)) <> #0 THEN
T1:= LOcc({BITSL(Lignes(L-1,1),1),Lignes(L-1,1),BITSR(Lignes(L-1,1),1), BITSL(Lignes(L,1),1),BITSR(Lignes(L,1),1), BITSL(Lignes(L+1,1),1),Lignes(L+1,1),BITSR(Lignes(L+1,1),1)});
T2:= BITAND(BITOR(BITXOR(T1(3),T1(4)), BITAND(BITXOR(T1(2),T1(3)),Lignes(L,1))),#1FFFFFFFFFE);
//IF BITAND(T2, #10000000000) <> #0 THEN T3:= #1; ELSE T3:= #0; END;
T3:= BITSR(T2, 40);
ELSE
T2:= #0; T3:= #0;
END;
IF BITOR(Lignes(L-1,2),Lignes(L,2),Lignes(L+1,2)) <> #0 THEN
T1:= LOcc({BITSL(Lignes(L-1,2),1),Lignes(L-1,2),BITSR(Lignes(L-1,2),1), BITSL(Lignes(L,2),1),BITSR(Lignes(L,2),1), BITSL(Lignes(L+1,2),1),Lignes(L+1,2),BITSR(Lignes(L+1,2),1)});
T3:= BITOR(T3,BITAND(BITOR(BITXOR(T1(3),T1(4)), BITAND(BITXOR(T1(2),T1(3)),Lignes(L,2))),#1FFFFFFFFFE));
IF BITAND(T3, #2) <> #0 THEN T2:= BITOR(T2,#20000000000) END;
END;
Tmp(L):={T2,T3};
END;
Lignes:= Tmp;
END;
LDisp()
BEGIN
LOCAL T1, L, L2, C2;
RECT_P(0,0,79,82,#F8F8E0h);
FOR L FROM 2 TO 81 DO
FOR L2 FROM 1 TO 2 DO
T1:= Lignes(L,L2); C2:= (L2-1)*40;
WHILE T1 <> 0 DO
IF BITAND(T1,#1) THEN PIXON_P(C2, L, #0); END;
T1:= BITSR(T1,1); C2:= C2+1;
END;
END;
END;
BLIT_P(G0,80,0,320,240,G0,0,2,80,82);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= py+2; Col:= px; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1); // for debug
CASE
IF INSTRING("0123456789", MID(RLE, Ptr, 1)) <> 0 THEN Cnt:= Cnt*10+EXPR(MID(RLE, Ptr, 1)); END;
IF MID(RLE, Ptr, 1) == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px; Cnt:= 0; END;
IF INSTRING("b.", MID(RLE, Ptr, 1)) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", MID(RLE, Ptr, 1)) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
Lignes(Row, IP(Col/40)+1):= BITOR(Lignes(Row, IP(Col/40)+1), BITSL(#1,(Col MOD 40)+1 ));
END;
Cnt:= 0;
END;
END;
END;
FOR Row FROM 2 TO 81 DO
IF BITAND(Lignes(Row,1), #10000000000) <> #0 THEN Lignes(Row,2):= BITOR(Lignes(Row,2),#1) END;
IF BITAND(Lignes(Row,2), #2) <> #0 THEN Lignes(Row,1):= BITOR(Lignes(Row,1),#20000000000) END;
END;
LDisp();
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, Lap;
Lignes:= MAKELIST({#0,#0},A,1,82);
RECT_P(0,0,319,239,#F8F8E0h);
IF St == 1 THEN
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon
END;
IF St == 2 THEN
RLEMap (1, 1, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!"); // Pre-pulsar shuttle 29
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
REPEAT
Lap:= TICKS();
LNext(); LDisp();
Lap:= TICKS()-Lap;
// to display time between screen updates
TEXTOUT_P(Lap,0,160,0,#0,80,#F8F8E0h);
Kb:= GETKEY();
UNTIL Kb==4;
END;
Version 2.2 Time per generation: 331 ms
added screen trail (green)
Optimization:
- unrolled the loop and removed unneeded operations in LOcc
Calc need to be set as Hexadecimal 64 bits (rev 6030: not needed anymore thanks to new pragme feature)
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// The 2 lower bits of each pixels is used to store neighb on right and left.
// 1.1 2014/02 Little optimization for speed
// Avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed
// Avoid recalc of empty left and right
// 2.0 2014/02 Even faster, better scaling
// using bitmap storage and bitwise operations
// 2.1 2014/02 with trail
// show life span in green
// 2.2 A little optimization in LOcc
// Unrolled the loop and removed unneeded ops
// the Game of Life play field is 80*80 cells
// each ligne is stored in 2 integers using 2 time 40 bits
// Slice = 40
// Mask = 2^41-2= #1FFFFFFFFFEh
// LeftBit = 2^41 = #10000000000h
// RightLink= 2^42 = #20000000000h
// LeftLink = 1 = 1h
// RightBit = 2 = 2h
LNext()
BEGIN
LOCAL T1, T2, T3, L;
Trail:= Lignes;
FOR L FROM 2 TO 81 DO
IF BITOR(Trail(L-1,1),Trail(L,1),Trail(L+1,1)) <> #0 THEN
T1:= LOcc(Trail(L-1,1),Trail(L,1),Trail(L+1,1));
T2:= BITAND(BITOR(BITXOR(T1(3),T1(4)), BITAND(BITXOR(T1(2),T1(3)),Trail(L,1))),#1FFFFFFFFFE);
//IF BITAND(T2, #10000000000) <> #0 THEN T3:= #1; ELSE T3:= #0; END;
T3:= BITSR(T2, 40);
ELSE
T2:= #0; T3:= #0;
END;
IF BITOR(Trail(L-1,2),Trail(L,2),Trail(L+1,2)) <> #0 THEN
T1:= LOcc(Trail(L-1,2),Trail(L,2),Trail(L+1,2));
T3:= BITOR(T3,BITAND(BITOR(BITXOR(T1(3),T1(4)), BITAND(BITXOR(T1(2),T1(3)),Trail(L,2))),#1FFFFFFFFFE));
IF BITAND(T3, #2) <> #0 THEN T2:= BITOR(T2,#20000000000) END;
END;
Lignes(L):={T2,T3};
END;
END;
LDisp()
BEGIN
LOCAL T1, Tr, L, L2, C2;
//RECT_P(0,0,79,82,#F8F8E0h);
FOR L FROM 2 TO 81 DO
FOR L2 FROM 1 TO 2 DO
T1:= Lignes(L,L2); Tr:= Trail(L,L2); C2:= (L2-1)*40-1;
WHILE T1 <> #0 OR Tr <> #0 DO
IF BITAND(T1,#1) THEN PIXON_P(C2, L, #0);
ELSE
IF BITAND(Tr,#1) THEN PIXON_P(C2, L, #F800); END;
END;
T1:= BITSR(T1,1); Tr:= BITSR(Tr,1); C2:= C2+1;
END;
END;
END;
BLIT_P(G0,80,0,320,240,G0,0,2,80,82);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= py+2; Col:= px; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1); // for debug
CASE
IF INSTRING("0123456789", MID(RLE, Ptr, 1)) <> 0 THEN Cnt:= Cnt*10+EXPR(MID(RLE, Ptr, 1)); END;
IF MID(RLE, Ptr, 1) == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px; Cnt:= 0; END;
IF INSTRING("b.", MID(RLE, Ptr, 1)) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", MID(RLE, Ptr, 1)) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
Lignes(Row, IP(Col/40)+1):= BITOR(Lignes(Row, IP(Col/40)+1), BITSL(#1,(Col MOD 40)+1 ));
END;
Cnt:= 0;
END;
END;
END;
FOR Row FROM 2 TO 81 DO
IF BITAND(Lignes(Row,1), #10000000000) <> #0 THEN Lignes(Row,2):= BITOR(Lignes(Row,2),#1) END;
IF BITAND(Lignes(Row,2), #2) <> #0 THEN Lignes(Row,1):= BITOR(Lignes(Row,1),#20000000000) END;
END;
LDisp();
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, Lap;
Lignes:= MAKELIST({#0,#0},A,1,82);
Trail:= MAKELIST({#0,#0},A,1,82);
RECT_P(0,0,319,239,#F8F8E0h);
IF St == 1 THEN
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon
END;
IF St == 2 THEN
RLEMap (1, 1, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!"); // Pre-pulsar shuttle 29
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (38, 38, "bo$3bo$2o2b3o!"); // Acorn
END;
REPEAT
Lap:= TICKS();
LNext(); LDisp();
Lap:= TICKS()-Lap;
// to display time between screen updates
TEXTOUT_P(Lap,0,160,0,#0,80,#F8F8E0h);
Kb:= GETKEY();
UNTIL Kb==4;
END;
Version 2.3 Time per generation: 350 ms
The board is now 120x100 and with zoom by 2x
the Next Generation is now computed in constant time, the difference in timing now depend on the number of cells alive to display.
Optimization:
- Taking advantage of lists special handling, it compensate a board twice as big
Look at set 6 (Acorn Set)
Calc need to be set as Hexadecimal 64 bits (rev 6030: not needed anymore thanks to new pragme feature)
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// The 2 lower bits of each pixels is used to store neighb on right and left.
// 1.1 2014/02 Little optimization for speed
// Avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed
// Avoid recalc of empty left and right
// 2.0 2014/02 Even faster, better scaling
// using bitmap storage and bitwise operations
// 2.1 2014/02 with trail
// show life span in green
// 2.2 A little optimization in LOcc
// Unrolled the loop and removed unneeded ops
// 2.3 board is now 120*100 and zoom x2 and
// Next Gen takes advantage of calc on lists
LNext() // Next Generation
BEGIN
LOCAL T1, T2, Row;
Trail:= Lignes;
Trail(1):= BITOR(Trail(1),BITSL(BITAND(Trail(2),#2),60));
Trail(2):= BITOR(Trail(2),BITSR(Trail(1),60));
FOR Row FROM 1 TO 2 DO
T1:= LOcc(SUB(Trail(Row),1,100),SUB(Trail(Row),2,101),SUB(Trail(Row),3,102));
T2:= BITAND(BITOR(BITXOR(T1(3),T1(4)), BITAND(BITXOR(T1(2),T1(3)),SUB(Trail(Row),2,101))),#1FFFFFFFFFFFFFFE);
Lignes(Row):= CONCAT(#0,T2,#0);
END;
END;
LDisp()
BEGIN
LOCAL T1, Tr, L, L2, C2;
FOR L2 FROM 1 TO 2 DO
FOR L FROM 0 TO 99 DO
T1:= Lignes(L2,L+1); Tr:= Trail(L2,L+1); C2:= (L2-1)*60-1;
WHILE T1 <> #0 OR Tr <> #0 DO
IF BITAND(T1,#1) THEN PIXON_P(L, C2, #0);
ELSE
IF BITAND(Tr,#1) THEN PIXON_P(L, C2, #F800); END;
END;
T1:= BITSR(T1,1); Tr:= BITSR(Tr,1); C2:= C2+1;
END;
END;
END;
BLIT_P(G0,120,0,320,240,G0,0,0,100,120);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod;
Row:= py; Col:= px+2; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1);
CASE
IF INSTRING("0123456789", Cod) <> 0 THEN Cnt:= Cnt*10+EXPR(Cod); END;
IF Cod == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px+2; Cnt:= 0; END;
IF INSTRING("b.", Cod) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", Cod) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
Lignes(IP(Row/60)+1, Col):= BITOR(Lignes(IP(Row/60)+1, Col), BITSL(#2,(Row MOD 60) ));
END;
Cnt:= 0;
END;
END;
END;
LDisp();
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, Lap;
Lignes:= MAKELIST(MAKELIST(#0,B,1,102),A,1,2);
Trail:= Lignes;
RECT_P(0,0,319,239,#F8F8E0h);
IF St == 1 THEN
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon
END;
IF St == 2 THEN
RLEMap (1, 1, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!"); // Pre-pulsar shuttle 29
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (50, 60, "bo$3bo$2o2b3o!"); // Acorn
END;
IF St == 6 THEN
RLEMap (52, 80, "o$obo$$bo$o$o$o!"); // Acorn vertical
END;
REPEAT
Lap:= TICKS();
LNext(); LDisp();
Lap:= TICKS()-Lap;
// to display time between screen updates
TEXTOUT_P(Lap,0,225,0,#0,80,#F8F8E0h);
Kb:= GETKEY();
UNTIL Kb==4;
END;
Version 2.4 zoom x 2 Time per generation: 350 ms
The board is now 120x160 and with zoom by 2x
Optimization:
- LDisp now detects changes since last generation and only draw the changes.
- LNext now detects changes since last generation and only calc thoses places
- LNext1 is LNext version that handle lists, rename to LNext to test it
Look at set 7 (Snark Glider Reflector Loop), this set is Fast and Furious.
Acorn sets (5 and 6) are also impressives.
Calc need to be set as Hexadecimal 64 bits (rev 6030: not needed anymore thanks to new pragme feature)
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// The 2 lower bits of each pixels is used to store neighb on right and left.
// 1.1 2014/02 Little optimization for speed
// Avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed
// Avoid recalc of empty left and right
// 2.0 2014/02 Even faster, better scaling
// using bitmap storage and bitwise operations
// 2.1 2014/02 with PrevN
// show life span in green
// 2.2 A little optimization in LOcc
// Unrolled the loop and removed unneeded ops
// 2.3 board is now 120*160 and zoom x2 and
// Next Gen takes advantage of lists handling
// 2.4 Getting Fast and Furious on large sets
// the Game of Life play field is 120*160 cells
// each ligne is stored in 2 integers using 2 time 60 bits
// Slice = 60
// Mask = 2^61-2= #1FFFFFFFFFFFFFFEh
//This routine is good with small sets but do degrade with big ones.
LNext() // Next Generation one by one elements
BEGIN
LOCAL R, Row;
LOCAL P1, P2, P3, v1, v2, v3, v4;
// Link between columns
FOR R FROM 1 TO 2 DO
Tmp:= Lignes(R);
IF R <> 1 THEN Tmp:= BITOR(Tmp,BITAND(BITSR(PrevN(R-1),60),#1)); END;
IF R <> 2 THEN Tmp:= BITOR(Tmp,BITSL(BITAND(Lignes(R+1),#2),60)); END;
Delta:= BITXOR(PrevN(R),Tmp);
PrevN(R):=Tmp;
FOR Row FROM 2 TO 161 DO
IF BITOR(Delta(Row-1),Delta(Row),Delta(Row+1)) <> #0 THEN
P1:= PrevN(R,Row-1); P2:= PrevN(R,Row); P3:= PrevN(R,Row+1);
v2:= BITAND(P1,P3); v1:= BITOR(P1,P3);
P1:= BITSL(P1); P2:= BITSL(P2); P3:= BITSL(P3);
v3:= BITAND(v2,P1); v2:= BITOR(v2,BITAND(v1,P1)); v1:= BITOR(v1,P1);
v4:= BITAND(v3,P2); v3:= BITOR(v3,BITAND(v2,P2)); v2:= BITOR(v2,BITAND(v1,P2)); v1:= BITOR(v1,P2);
v4:= BITOR(v4,BITAND(v3,P3)); v3:= BITOR(v3,BITAND(v2,P3)); v2:= BITOR(v2,BITAND(v1,P3)); v1:= BITOR(v1,P3);
P1:= BITSR(P1,2); P2:= BITSR(P2,2); P3:= BITSR(P3,2);
v4:= BITOR(v4,BITAND(v3,P1)); v3:= BITOR(v3,BITAND(v2,P1)); v2:= BITOR(v2,BITAND(v1,P1)); v1:= BITOR(v1,P1);
v4:= BITOR(v4,BITAND(v3,P2)); v3:= BITOR(v3,BITAND(v2,P2)); v2:= BITOR(v2,BITAND(v1,P2)); v1:= BITOR(v1,P2);
v4:= BITOR(v4,BITAND(v3,P3)); v3:= BITOR(v3,BITAND(v2,P3)); v2:= BITOR(v2,BITAND(v1,P3)); // v1:= BITOR(v1,P3);
Lignes(R,Row):= BITAND(BITXOR(BITOR(v3,BITAND(v2,PrevN(R,Row))),v4),#1FFFFFFFFFFFFFFE);
END;
END;
END;
END;
LDisp()
BEGIN
LOCAL T1, Tx, C, R2, R;
FOR R2 FROM 1 TO 2 DO
Delta:= BITXOR(Lignes(R2),PrevD(R2));
FOR C FROM 0 TO 159 DO
T1:= Lignes(R2,C+2); Tx:= Delta(C+2); R:= (R2-1)*60;
WHILE Tx > #1 DO
IF BITAND(Tx,#2) THEN
IF BITAND(T1,#2) THEN PIXON_P(G1, C, R, #0);
ELSE PIXON_P(G1, C, R, #F800);
END;
END;
T1:= BITSR(T1,1); Tx:= BITSR(Tx,1); R:= R+1;
END;
END;
END;
PrevD:= Lignes;
BLIT_P(G0,G1);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod, Tmp;
Row:= py; Col:= px+2; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1);
CASE
IF INSTRING("0123456789", Cod) <> 0 THEN Cnt:= Cnt*10+EXPR(Cod); END;
IF Cod == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px+2; Cnt:= 0; END;
IF INSTRING("b.", Cod) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", Cod) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
Tmp:= BITOR(Lignes(IP(Row/60)+1, Col), BITSL(#2,(Row MOD 60) ));
Lignes(IP(Row/60)+1, Col):= Tmp;
END;
Cnt:= 0;
END;
END;
END;
LDisp();
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, LapN, LapD;
LOCAL Tm:=0, Gen:=0;
Gen:=0;
Lignes:= MAKELIST(MAKELIST(#0,B,1,322),A,1,4);
PrevN:= Lignes; PrevD:= Lignes;
DIMGROB(G1,160,120); RECT_P(G1);
RECT_P(0,0,159,119,#F8F8E0h);
IF St == 1 THEN
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon
END;
IF St == 2 THEN
RLEMap (1, 1, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!"); // Pre-pulsar shuttle 29
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (80, 80, "bo$3bo$2o2b3o!"); // Acorn
END;
IF St == 6 THEN
RLEMap (80, 80, "o$obo$$bo$o$o$o!"); // Acorn vertical
END;
IF St == 7 THEN
RLEMap (1, 1, "26b2o3b2o$24b3obo2b2o$23bo4bo$23bo2b2ob4o$22b2obobobo2bo$23bobobobo$23bobob2o$24bo2$37b2o$28b2o7bo$28b2o5bobo$9bo25b2o$9b3o$12bo15b2o$11b2o15bobo$28bo2$2ob2o$2obo21b2o$3bo22bo$3b3o4b2o11b3o$b2o3bo3b2o11bo22bo$o2b4o21b2o14b5o$2obo15b2o8bo13bo5bo$bo2b3o12bobo7bobo12b3o2bo$bo5bo13bo8b2o15bob2o$2b5o14b2o21b4o2bo$4bo22bo11b2o3bo3b2o$25b3o11b2o4b3o$24bo22bo$24b2o21bob2o$46b2ob2o3$38b2o$38bo$39b3o$14b2o25bo$13bobo5b2o$13bo7b2o$12b2o2$26bo$22b2obobo$21bobobobo$18bo2bobobob2o$18b4ob2o2bo$22bo4bo$18b2o2bob3o$18b2o3b2o!"); // Snark Glider Reflector Loop
END;
IF St == 8 THEN
RLEMap (50, 50, "b2o$2o$bo!"); // R pentamino
END;
IF St == 9 THEN
RLEMap (80, 800, "o3b3o$3o2bo$bo!"); // Rabits
END;
REPEAT
LapN:= TICKS(); LNext(); LapN:= TICKS()-LapN;
LapD:= TICKS(); LDisp(); LapD:= TICKS()-LapD;
Tm:=Tm+LapN+LapD; Gen:= Gen+1; IF Gen == IterMax THEN RETURN Tm/IterMax; END;
// to display time between screen updates
TEXTOUT_P(STRING(Gen,2,0)+"-"+STRING(LapN,2,0)+"-"+STRING(LapD,2,0),0,225,0,#0,160,#F8F8E0h);
Kb:= GETKEY();
UNTIL Kb==4;
Lignes:= 0; PrevN:= 0; PrevD:= 0;
END;
Version 2.4 zoom x 1
The same in full screen size, I recommand sets 6 and 9.
Timing depend on set size.
Code:
#pragma mode( separator(.,;) integer(h64) )
// Conway's Game of Life B3/S23
// Author: Patrice Torchet
// 1.0 2014/01 First release.
// The 2 lower bits of each pixels is used to store neighb on right and left.
// 1.1 2014/02 Little optimization for speed
// Avoid recalc of empty lines.
// 1.2 2014/02 Better optimization for speed
// Avoid recalc of empty left and right
// 2.0 2014/02 Even faster, better scaling
// using bitmap storage and bitwise operations
// 2.1 2014/02 with PrevN
// show life span in green
// 2.2 A little optimization in LOcc
// Unrolled the loop and removed unneeded ops
// 2.3 board is now 120*160 and zoom x2 and
// Next Gen takes advantage of lists handling
// 2.4 Getting Fast and Furious on large sets
// the Game of Life play field is 120*160 cells
// each ligne is stored in 2 integers using 2 time 60 bits
// Slice = 60
// Mask = 2^61-2= #1FFFFFFFFFFFFFFEh
//This routine is good with small sets but do degrade with big ones.
LNext() // Next Generation one by one elements
BEGIN
LOCAL R, Row;
LOCAL P1, P2, P3, v1, v2, v3, v4;
// Link between columns
FOR R FROM 1 TO 4 DO
Tmp:= Lignes(R);
IF R <> 1 THEN Tmp:= BITOR(Tmp,BITAND(BITSR(PrevN(R-1),60),#1)); END;
IF R <> 4 THEN Tmp:= BITOR(Tmp,BITSL(BITAND(Lignes(R+1),#2),60)); END;
Delta:= BITXOR(PrevN(R),Tmp);
PrevN(R):=Tmp;
FOR Row FROM 2 TO 321 DO
IF BITOR(Delta(Row-1),Delta(Row),Delta(Row+1)) <> #0 THEN
P1:= PrevN(R,Row-1); P2:= PrevN(R,Row); P3:= PrevN(R,Row+1);
v2:= BITAND(P1,P3); v1:= BITOR(P1,P3);
P1:= BITSL(P1); P2:= BITSL(P2); P3:= BITSL(P3);
v3:= BITAND(v2,P1); v2:= BITOR(v2,BITAND(v1,P1)); v1:= BITOR(v1,P1);
v4:= BITAND(v3,P2); v3:= BITOR(v3,BITAND(v2,P2)); v2:= BITOR(v2,BITAND(v1,P2)); v1:= BITOR(v1,P2);
v4:= BITOR(v4,BITAND(v3,P3)); v3:= BITOR(v3,BITAND(v2,P3)); v2:= BITOR(v2,BITAND(v1,P3)); v1:= BITOR(v1,P3);
P1:= BITSR(P1,2); P2:= BITSR(P2,2); P3:= BITSR(P3,2);
v4:= BITOR(v4,BITAND(v3,P1)); v3:= BITOR(v3,BITAND(v2,P1)); v2:= BITOR(v2,BITAND(v1,P1)); v1:= BITOR(v1,P1);
v4:= BITOR(v4,BITAND(v3,P2)); v3:= BITOR(v3,BITAND(v2,P2)); v2:= BITOR(v2,BITAND(v1,P2)); v1:= BITOR(v1,P2);
v4:= BITOR(v4,BITAND(v3,P3)); v3:= BITOR(v3,BITAND(v2,P3)); v2:= BITOR(v2,BITAND(v1,P3)); // v1:= BITOR(v1,P3);
Lignes(R,Row):= BITAND(BITXOR(BITOR(v3,BITAND(v2,PrevN(R,Row))),v4),#1FFFFFFFFFFFFFFE);
END;
END;
END;
END;
LDisp()
BEGIN
LOCAL T1, Tx, C, R2, R;
FOR R2 FROM 1 TO 4 DO
Delta:= BITXOR(Lignes(R2),PrevD(R2));
FOR C FROM 0 TO 319 DO
T1:= Lignes(R2,C+2); Tx:= Delta(C+2); R:= (R2-1)*60;
WHILE Tx > #1 DO
IF BITAND(Tx,#2) THEN
IF BITAND(T1,#2) THEN PIXON_P(G1, C, R, #0);
ELSE PIXON_P(G1, C, R, #F800);
END;
END;
T1:= BITSR(T1,1); Tx:= BITSR(Tx,1); R:= R+1;
END;
END;
END;
PrevD:= Lignes;
BLIT_P(G0,G1);
END;
RLEMap (px, py, RLE)
BEGIN
LOCAL Row, Col, Ptr, Cnt, Cod, Tmp;
Row:= py; Col:= px+2; Cnt:= 0;
FOR Ptr FROM 1 TO DIM(RLE) DO
Cod:= MID(RLE, Ptr, 1);
CASE
IF INSTRING("0123456789", Cod) <> 0 THEN Cnt:= Cnt*10+EXPR(Cod); END;
IF Cod == "$" THEN Row:= Row+MAX(1, Cnt); Col:= px+2; Cnt:= 0; END;
IF INSTRING("b.", Cod) <> 0 THEN Col:= Col+MAX(1, Cnt); Cnt:= 0; END;
IF INSTRING("oA", Cod) <> 0 THEN
FOR Col FROM Col TO Col+MAX(1, Cnt)-1 DO
Tmp:= BITOR(Lignes(IP(Row/60)+1, Col), BITSL(#2,(Row MOD 60) ));
Lignes(IP(Row/60)+1, Col):= Tmp;
END;
Cnt:= 0;
END;
END;
END;
LDisp();
END;
EXPORT Life(St)
BEGIN
LOCAL Kb, LapN, LapD;
LOCAL Tm:=0, Gen:=0;
Gen:=0;
Lignes:= MAKELIST(MAKELIST(#0,B,1,322),A,1,4);
PrevN:= Lignes; PrevD:= Lignes;
DIMGROB(G1,320,240); RECT_P(G1);
RECT_P(0,0,319,239,#F8F8E0h);
IF St == 1 THEN
RLEMap (1, 1, "3o!"); // Blinker
RLEMap (13, 5, "bo$3o$obo$3o$bo!"); // Pulsar
LNext();
RLEMap (1, 6, "b3o$3o!"); // Toad
RLEMap (30, 5, "bo$3o$obo$3o$bo!"); // Pulsar
RLEMap (1, 17, "24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8bo3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o!"); // Glider Canon
END;
IF St == 2 THEN
RLEMap (1, 1, "10b2o3b2o10b$9bo2bobo2bo9b$5b2o3b2o3b2o3b2o5b$5bo15bo5b$2b2obo15bob2o2b$o2bob2o13b2obo2bo$2obo19bob2o$3bo19bo3b$3b2o17b2o3b$9b3o3b3o9b$9bobo3bobo9b$9b3o3b3o9b4$9bo7bo9b$8bobo5bobo8b$9bo7bo!"); // Pre-pulsar shuttle 29
END;
IF St == 3 THEN
RLEMap (1, 1, "13bo20b$13b3o7b2o9b$16bo6bo10b$9bo5b2o4bobo10b$9b3o9b2o11b$12bo4b3o6b2o6b$5bo5b2o4b3o6bo7b$5b3o16bobo7b$8bo15b2o8b$bo5b2o4b3o13b2o3b$b3o9b3o4b3o6bo4b$4bo4b3o8b3o4bobo4b$3b2o4b3o4b3o8b2o5b$16b3o4b3o6b2o$23b3o6bob$5b3o22bobob$5b3o4b3o15b2o2b$2b2o8b3o4b3o12b$bobo4b3o8b3o4b3o5b$bo6b3o4b3o8b3o5b$2o13b3o4b3o9b$5b2o15b3o4b2o3b$4bobo22bo4b$4bo6b3o16b3ob$3b2o6b3o4b3o4b2o5bob$8b2o8b3o4bo8b$7bobo4b3o9b3o5b$7bo6b3o4b2o5bo5b$6b2o13bo12b$11b2o9b3o9b$10bobo4b2o5bo9b$10bo6bo16b$9b2o7b3o13b$20bo!"); // Extended dinner table
END;
IF St == 4 THEN
RLEMap (0, 0, "11bo7bo39bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo9b2o17b2o9bo7bo11b$29bo19bo29b$27bobo19bobo27b$27b2o21b2o27b$6bo17bo29bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo11bobobobo11bo17bo6b$2b2o31bo2bobo2bo31b2o2b$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$2o34bobobobo34b2o$37bo3bo37b$7b2o13b2o31b2o13b2o7b$7b2o13b2o31b2o13b2o7b$37bo3bo37b$2o34bobobobo34b2o$bo8bo3bobo3bo14bo2bobo2bo14bo3bobo3bo8bob$bobo7b3o3b3o15bo7bo15b3o3b3o7bobob$2b2o31bo2bobo2bo31b2o2b$6bo17bo11bobobobo11bo17bo6b$6bo17bo12bo3bo12bo17bo6b$6bo17bo29bo17bo6b$27b2o21b2o27b$27bobo19bobo27b$29bo19bo29b$11bo7bo9b2o17b2o9bo7bo11b$10bobo5bobo37bobo5bobo10b$11bo7bo39bo7bo!"); // Pre-pulsar shuttle 47
END;
IF St == 5 THEN
RLEMap (160, 150, "bo$3bo$2o2b3o!"); // Acorn
END;
IF St == 6 THEN
RLEMap (160, 150, "o$obo$$bo$o$o$o!"); // Acorn vertical
END;
IF St == 7 THEN
RLEMap (1, 1, "26b2o3b2o$24b3obo2b2o$23bo4bo$23bo2b2ob4o$22b2obobobo2bo$23bobobobo$23bobob2o$24bo2$37b2o$28b2o7bo$28b2o5bobo$9bo25b2o$9b3o$12bo15b2o$11b2o15bobo$28bo2$2ob2o$2obo21b2o$3bo22bo$3b3o4b2o11b3o$b2o3bo3b2o11bo22bo$o2b4o21b2o14b5o$2obo15b2o8bo13bo5bo$bo2b3o12bobo7bobo12b3o2bo$bo5bo13bo8b2o15bob2o$2b5o14b2o21b4o2bo$4bo22bo11b2o3bo3b2o$25b3o11b2o4b3o$24bo22bo$24b2o21bob2o$46b2ob2o3$38b2o$38bo$39b3o$14b2o25bo$13bobo5b2o$13bo7b2o$12b2o2$26bo$22b2obobo$21bobobobo$18bo2bobobob2o$18b4ob2o2bo$22bo4bo$18b2o2bob3o$18b2o3b2o!"); // Snark Glider Reflector Loop
END;
IF St == 8 THEN
RLEMap (50, 50, "b2o$2o$bo!"); // R pentamino
END;
IF St == 9 THEN
RLEMap (160, 150, "o3b3o$3o2bo$bo!"); // Rabits
END;
REPEAT
LapN:= TICKS(); LNext(); LapN:= TICKS()-LapN;
LapD:= TICKS(); LDisp(); LapD:= TICKS()-LapD;
Tm:=Tm+LapN+LapD; Gen:= Gen+1; IF Gen == IterMax THEN RETURN Tm/IterMax; END;
// to display time between screen updates
TEXTOUT_P(STRING(Gen,2,0)+"-"+STRING(LapN,2,0)+"-"+STRING(LapD,2,0),0,225,0,#0,160,#F8F8E0h);
Kb:= GETKEY();
UNTIL Kb==4;
Lignes:= 0; PrevN:= 0; PrevD:= 0;
END;
RE: Conway's game of life - Kevin Ouellet - 01-29-201406:37 AM
Good job so far. Hopefully you can manage to get it to run faster eventually.
RE: Conway's game of life - Kevin Ouellet - 02-10-201412:44 AM
Wow good job! This one runs like 8 times faster than the original version.
RE: Conway's game of life - patrice - 02-12-201412:38 PM
(02-10-2014 12:44 AM)Kevin Ouellet Wrote: Wow good job! This one runs like 8 times faster than the original version.
And I think there is still a few drops to squeeze from the lemon.
RE: Conway's game of life - ArielPalazzesi - 02-12-201412:39 PM
Congratulations. I always learn something new watching your code You're a great programmer!
RE: Conway's game of life - patrice - 02-12-201412:49 PM
(02-12-2014 12:39 PM)ArielPalazzesi Wrote: Congratulations. I always learn something new watching your code You're a great programmer!
Nice to see that my post is appreciated.
By the way, how is doing Sokoban? Did you manage to use the RLE compression?
RE: Conway's game of life - ArielPalazzesi - 02-12-201401:30 PM
I have not got the time to get with it.
I'm studying (at 45 years old ... ha ha), and I'm giving final exams: (
But next month I hope to change the theme of the RLE compression and make some more changes. I have also implemented a cute version of "Pipe Dream"
RE: Conway's game of life - Kevin Ouellet - 02-13-201412:23 AM
Yeah I noticed that a lot of the HP programmers who used to release games and programs stopped or disappeared entirely since January began, but they were active in December. On Omnimaga last month, every single active HP Prime user vanished overnight, then we got invaded by TI-Nspire users who needed OS downgrade help. In contrast, the TI programmers get active around this time of the year as well as around October-November, but in June-August, along with December, they'll be inactive.
I assume this has to do with different school schedule patterns for the HP fanbase which is older plus work shifts, since most TI users only work during Summer. I was surprised at how active HP game coders were in December, though, considering most people are usually busy shopping for Christmas gifts and having to work more hours due to the shopping rush.
RE: Conway's game of life [faster version] - Joe Horn - 02-14-201411:54 PM
After re-compiling with Bits set to 64, it ran perfectly, and very fast! Good work, Patrice! We all benefit greatly from reading your code. Thanks!
RE: Conway's game of life [faster version] - patrice - 02-16-201403:32 PM
(02-14-2014 11:54 PM)Joe Horn Wrote: After re-compiling with Bits set to 64, it ran perfectly, and very fast! Good work, Patrice! We all benefit greatly from reading your code. Thanks!
Thank you Joe.
Still tuning the program, I have found a few drops to squeeze, posting soon.
RE: Conway's game of life [faster version] - Jim Horn - 02-18-201409:14 PM
Holy smokes! I spent a ridiculous number of hours many years ago tweaking an HP-67 program to do a 10x23 life field at about one generation per minute (earlier programs handled 10x10 slower). I knew the Prime would be bigger and faster but, Wow! I am impressed with the speed on an emulated Prime. Will have to see if it will run on my 39gII. Thanks
RE: Conway's game of life [faster version] - patrice - 02-19-201406:59 PM
(02-18-2014 09:14 PM)Jim Horn Wrote: Holy smokes! I spent a ridiculous number of hours many years ago tweaking an HP-67 program to do a 10x23 life field at about one generation per minute (earlier programs handled 10x10 slower). I knew the Prime would be bigger and faster but, Wow! I am impressed with the speed on an emulated Prime.
Indeed, the problem, with theses memory constrained beast, is to find a memory efficient storage while being able to compute the next generation fast.
(02-18-2014 09:14 PM)Jim Horn Wrote: Will have to see if it will run on my 39gII. Thanks
I guess that the main change is on the color scheme. and faster too
RE: Conway's game of life [faster version] - Kevin Ouellet - 02-20-201406:59 PM
(02-19-2014 06:59 PM)patrice Wrote:
(02-18-2014 09:14 PM)Jim Horn Wrote: Will have to see if it will run on my 39gII. Thanks
I guess that the main change is on the color scheme. and faster too
The HP Prime is much less buggy too (even the first firmware). I think DIMGROB_P or BLIT_P didn't even work in the latest 39gII revision >.<
RE: Conway's game of life [faster version] - Han - 02-20-201407:33 PM
(02-20-2014 06:59 PM)Kevin Ouellet Wrote:
(02-19-2014 06:59 PM)patrice Wrote: I guess that the main change is on the color scheme. and faster too
The HP Prime is much less buggy too (even the first firmware). I think DIMGROB_P or BLIT_P didn't even work in the latest 39gII revision >.<
Are you using color masks? If you remove the color masking, do they work?
RE: Conway's game of life [faster version] - patrice - 02-20-201410:00 PM
(02-20-2014 07:33 PM)Han Wrote:
(02-20-2014 06:59 PM)Kevin Ouellet Wrote: The HP Prime is much less buggy too (even the first firmware). I think DIMGROB_P or BLIT_P didn't even work in the latest 39gII revision >.<
Are you using color masks? If you remove the color masking, do they work?
No color mask for me.
In this program, just using BLIT_P for zoom
RE: Conway's game of life [faster version] - Kevin Ouellet - 02-21-201404:50 AM
(02-20-2014 07:33 PM)Han Wrote:
(02-20-2014 06:59 PM)Kevin Ouellet Wrote: The HP Prime is much less buggy too (even the first firmware). I think DIMGROB_P or BLIT_P didn't even work in the latest 39gII revision >.<
Are you using color masks? If you remove the color masking, do they work?
Regardless of if I setup a color (which is 0, 1, 2 or 3 on the 39gII), usually nothing happens or the calc freezes. I think HP has pretty much completely abandoned the 39gII now.
RE: Conway's game of life [faster version] - patrice - 02-21-201406:13 PM
Yet another version in first post
New board is now 120x100 for same speed
RE: Conway's game of life [faster version] - patrice - 02-25-201412:02 PM
Yet another version in first post
Version is 2.4
New board is now 120x160
Improvement is done for big sets
try sets 5 (Acorn),6 (Acorn vertical) and 7 (Snark Glider Reflector Loop)
Mean time per generation with set 1 and set 7
\begin{array}{|c|c|c|c|}
\hline Version & Play Field & Set 1 & Set 7 \\\hline
1.0 & 80x80 & 5226ms & \\\hline
1.1 & 80x80 & 2184ms & \\\hline
1.2 & 80x80 & 763ms & \\\hline
2.0 & 80x80 & 324ms & 493ms \\\hline
2.2 & 80x80 & 418ms & 583ms \\\hline
2.3 & 120x100 & 432ms & 589ms \\\hline
2.4 & 120x160 & 399ms & 211ms \\\hline
\end{array}
RE: Conway's game of life [faster version] - eried - 03-04-201408:32 PM
heheheh
RE: Conway's game of life [faster version] - patrice - 03-05-201406:35 PM
It is amazing to see how modest is this guy who invented something that is the suject of very serious studies by mathematician teams all over the word since created.
on set 1, you can see 2 quasars and a glider gun as seen on this video.