QB64.org Forum

Active Forums => Programs => Topic started by: bplus on September 25, 2019, 09:01:12 am

Title: Hexagonal Life
Post by: bplus on September 25, 2019, 09:01:12 am
Same set of rules as Conway's Life played out with Hexagonal Cells that have 6 neighbors to count, it seems to have a space filling and stabilizing nature for small seed starts:
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-09-23 from Hex Minesweeper Custom Field
  2. DEFINT A-Z
  3. CONST cellR = 20 ' which makes the following constant
  4. CONST xspacing! = 2 * cellR * COS(_D2R(30))
  5. CONST yspacing! = cellR * (1 + SIN(_D2R(30)))
  6.  
  7. TYPE cell
  8.     x AS INTEGER
  9.     y AS INTEGER
  10.     L AS INTEGER
  11.  
  12. DIM SHARED xmax, ymax, Xarrd, Yarrd 'set all this in customField sub
  13.  
  14.  
  15. '      note: To preserve symmetry when cells hit boundries with a symmetric seed started in middle:
  16. '            y should be odd for 1 cell center x axis, on a shorter inner row
  17. '            If x is odd then one cell is marked in center.
  18. '            If x is even the left one of two center cells will be marked, toggle the one to right also (for symmetric seed).
  19.  
  20. Xarrd = 21 ' the top left cell has been hacked to duplicate the top right cell, to preserve symmetric seeds through a run
  21.  
  22. Yarrd = 21 'y should always be odd top preserve symmetry of center symmetric seed
  23.  
  24. xmax = (Xarrd + 2) * xspacing!: ymax = (Yarrd + 2) * yspacing!
  25.  
  26. SCREEN _NEWIMAGE(xmax, ymax, 32)
  27. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  28. DIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS cell, ng(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS INTEGER 'oversize the board to make it easy to count
  29. DIM x, y, xoffset!, xStop, nc, c, r, mb, kh&
  30.  
  31.     _TITLE "Hexagon Life: Left Click to Toggle Cells On/Off, Right Click to Start Run, Escape to Quit"
  32.     ' set x, y for cells and mark ceter cell(s)
  33.     FOR y = 1 TO Yarrd
  34.         IF y MOD 2 = 0 THEN
  35.             xoffset! = .5 * xspacing!: xStop = Xarrd - 1
  36.         ELSE
  37.             xoffset! = 0: xStop = Xarrd
  38.         END IF
  39.         FOR x = 1 TO xStop
  40.             b(x, y).x = x * xspacing! + xoffset! + .5 * xspacing!
  41.             b(x, y).y = y * yspacing! + .5 * yspacing!
  42.             IF x = INT(Xarrd / 2 + .5) AND y = INT(Yarrd / 2 + .5) THEN b(x, y).L = 1 ELSE b(x, y).L = 0 'mark middle cell
  43.             showCell x, y
  44.         NEXT
  45.     NEXT
  46.     _DISPLAY
  47.  
  48.     'setup seed by toggling cells on and off
  49.     WHILE mb <> 2
  50.         kh& = _KEYHIT
  51.         IF kh& = 27 THEN EXIT DO
  52.         mb = 0: c = 0: r = 0
  53.         getCell c, r, mb
  54.         IF mb = 1 THEN
  55.             b(c, r).L = 1 - b(c, r).L
  56.             showCell c, r
  57.         END IF
  58.         _DISPLAY
  59.         _LIMIT 60
  60.     WEND
  61.     mb = 0
  62.     _TITLE "Hexagon Life: Spacebar to Restart/Reseed, Escape to Quit"
  63.     WHILE kh& <> 32 AND kh& <> 27
  64.         kh& = _KEYHIT
  65.         'count the neighbors
  66.         FOR y = 1 TO Yarrd
  67.             IF y MOD 2 = 0 THEN
  68.                 xoffset! = .5 * xspacing!: xStop = Xarrd - 1
  69.             ELSE
  70.                 xoffset! = 0: xStop = Xarrd
  71.             END IF
  72.             FOR x = 1 TO xStop
  73.                 '2 sets of neighbors depending if x offset or not
  74.                 IF xoffset! > .05 THEN
  75.                     nc = b(x, y - 1).L + b(x + 1, y - 1).L + b(x - 1, y).L
  76.                     nc = nc + b(x + 1, y).L + b(x, y + 1).L + b(x + 1, y + 1).L
  77.                 ELSE
  78.                     nc = b(x - 1, y - 1).L + b(x, y - 1).L + b(x - 1, y).L
  79.                     nc = nc + b(x + 1, y).L + b(x - 1, y + 1).L + b(x, y + 1).L
  80.                 END IF
  81.                 IF (nc = 3 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  82.             NEXT
  83.         NEXT
  84.         LINE (0, 0)-(xmax, ymax), &H44000000, BF
  85.         FOR y = 1 TO Yarrd 'transfer data from ng to b().l and show cell
  86.             IF y MOD 2 = 0 THEN
  87.                 xStop = Xarrd - 1
  88.             ELSE
  89.                 xStop = Xarrd
  90.             END IF
  91.             FOR x = 1 TO xStop
  92.                 b(x, y).L = ng(x, y)
  93.                 showCell x, y
  94.             NEXT
  95.             'fix symmetry for top left corner, match x at other end for bi-lat symmetry
  96.             b(1, 1).L = b(Xarrd, 1).L
  97.             showCell 1, 1
  98.         NEXT
  99.         _DISPLAY
  100.         _LIMIT 1
  101.     WEND
  102.     IF kh& = 27 THEN EXIT DO
  103.     kh& = 0
  104.  
  105. SUB showCell (c, r)
  106.     DIM da, x!, y!, lastx!, lasty!, clr AS _UNSIGNED LONG
  107.     IF r MOD 2 = 0 THEN
  108.         IF c < 1 OR c > Xarrd - 1 THEN EXIT SUB
  109.     ELSE
  110.         IF c < 1 OR c > Xarrd THEN EXIT SUB
  111.     END IF
  112.     IF r < 1 OR r > Yarrd THEN EXIT SUB
  113.     IF b(c, r).L = 1 THEN clr = &HFFFFFFFF ELSE clr = &HFF000000
  114.     lastx! = b(c, r).x + cellR * COS(_D2R(-30))
  115.     lasty! = b(c, r).y + cellR * SIN(_D2R(-30))
  116.     FOR da = 30 TO 330 STEP 60
  117.         x! = b(c, r).x + cellR * COS(_D2R(da))
  118.         y! = b(c, r).y + cellR * SIN(_D2R(da))
  119.         LINE (lastx!, lasty!)-(x!, y!), &HFFFF00FF
  120.         lastx! = x!: lasty! = y!
  121.     NEXT
  122.     PAINT (b(c, r).x, b(c, r).y), clr, &HFFFF00FF
  123.     'debug
  124.     'cText b(c, r).x, b(c, r).y, 16, &HFF888888, STR$(c) + "," + STR$(r)
  125.  
  126. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  127.     DIM m, mx, my, mb1, mb2, r, c
  128.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  129.     IF mb1 THEN mbNum = 1
  130.     IF mb2 THEN mbNum = 2
  131.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  132.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  133.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  134.             mx = _MOUSEX: my = _MOUSEY
  135.             'LOCATE 1, 1: PRINT SPACE$(50)
  136.             'LOCATE 1, 1: PRINT mx, my, .5 * xspacing!
  137.             _DISPLAY
  138.         WEND
  139.         FOR r = 1 TO Yarrd
  140.             FOR c = 1 TO Xarrd
  141.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xspacing! THEN
  142.                     returnCol = c: returnRow = r: EXIT SUB
  143.                 END IF
  144.             NEXT
  145.         NEXT
  146.         mbNum = 0 'still here then clicked wrong
  147.     END IF
  148.  
  149. 'debug
  150. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  151.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  152.     fg = _DEFAULTCOLOR
  153.     'screen snapshot
  154.     cur& = _DEST
  155.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  156.     _DEST I&
  157.     COLOR K, _RGBA32(0, 0, 0, 0)
  158.     _PRINTSTRING (0, 0), txt$
  159.     mult = textHeight / 16
  160.     xlen = LEN(txt$) * 8 * mult
  161.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  162.     COLOR fg
  163.     _FREEIMAGE I&
  164.  
  165.  

If you had enjoyed exploring Conway's Life, you'll like exploring this one too I think. In a way I find this Life version more robust.

I am a lover of symmetry so this code has been hacked a little to keep a symmetric seed start symmetric throughout the run, bilateral left/right in particular.
Title: Re: Hexagonal Life
Post by: TempodiBasic on September 25, 2019, 10:01:55 am
Very fine Bplus!
About rules IMHO you must adapt!  A square has 8 neighbour , an exagon seems to have 6 neighbour so tolerance for life is 2 and overpopulation is  3-6 while solitude is 0-1, bring to life is 2.
Title: Re: Hexagonal Life
Post by: Jack002 on September 25, 2019, 10:13:41 am
Very cool! now on to 3d hex life, 4d hex life. Really nice job B+
Title: Re: Hexagonal Life
Post by: bplus on September 25, 2019, 03:40:54 pm
Thanks guys,

TempodiBasic, for me sticking to Conway's rules makes sense, 2 is birth or survival and 3 is survival.
I think I tried 1 for survival as opposed to 3 but that was when I was getting code to run, I will test again.
(A quick check) Oh yeah! looks interesting too, thanks! I will play around with that some more.

Jack002, my backlog of 3D work is #1 Battleship, maybe with Subs... airplanes too?
#2 The thing STxAxTIC suggested, flying through space with orbiting spheres
#3 Hexagon Life... hmm don't hold your breath ;)

PS line 87 is useless as I redraw all cells on each loop, I just noticed it still in there today. It was a carry over from experimenting with code.
Title: Re: Hexagonal Life
Post by: SierraKen on September 25, 2019, 03:59:06 pm
Pretty cool B+, would be a good simulator for a Biology course.
Title: Re: Hexagonal Life
Post by: bplus on September 25, 2019, 06:26:55 pm
Hi Ken,

I've a feeling that math teachers would be far more receptive to this than biology teachers.
Title: Re: Hexagonal Life
Post by: Jack002 on September 26, 2019, 11:12:59 am
This makes me think of the game Othello. There have also been some basic programs that imitate that as well.
Title: Re: Hexagonal Life
Post by: bplus on September 26, 2019, 11:35:32 am
This makes me think of the game Othello. There have also been some basic programs that imitate that as well.

Othello, not same as Reversi of which I have a copy qbguy's which comes from QB samples according to first line in it. But this version starts with 4 in middle as Othello is supposed to...
Well that is played on square board with square cells moving one piece at a time.

Not like Life "Game" which is not a game in the same sense as these human games with winners and losers and with player skill or luck.

Yeah bplus rather play inhuman games with the gods or aliens take your pick ;-))
Title: Re: Hexagonal Life
Post by: Jack002 on September 27, 2019, 08:49:36 pm
I love this game. I keep playing it and playing it. Hex shapes seem more pleasing to the eye than the square ones.
Title: Re: Hexagonal Life
Post by: bplus on September 27, 2019, 10:18:03 pm
Here is the colorized version using neighbor counts to decide the colors, yellow are neighbor counts of 1 = survival using TempodiBasic rules which are better I think than my first post. White are cells with 2 neighbors = birth or survival.

Turns out I confused Conway's Life rules, there it was 3 neighbors for birth or survival and 2 for survival.

Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-09-23 from Hex Minesweeper Custom Field
  2. '2019-09-25 post with original Life Rules
  3. '2019-09-27 OK let's try some more color!
  4.  
  5. DEFINT A-Z
  6. CONST cellR = 10 ' which makes the following constant
  7. CONST xspacing! = 2 * cellR * COS(_D2R(30))
  8. CONST yspacing! = cellR * (1 + SIN(_D2R(30)))
  9.  
  10. TYPE cell
  11.     x AS INTEGER
  12.     y AS INTEGER
  13.     L AS INTEGER
  14. k(0) = &HFF000000: k(1) = &HFFFFFF00: k(2) = &HFFFFFFFF: k(3) = &HFF00BBBB: k(4) = &HFF008800: k(5) = &HFF000066: k(6) = &HFFFF0000
  15. DIM SHARED xmax, ymax, Xarrd, Yarrd 'set all this in customField sub
  16.  
  17.  
  18. '      note: To preserve symmetry when cells hit boundries with a symmetric seed started in middle:
  19. '            y should be odd for 1 cell center x axis, on a shorter inner row
  20. '            If x is odd then one cell is marked in center.
  21. '            If x is even the left one of two center cells will be marked, toggle the one to right also.
  22.  
  23. Xarrd = 41 ' the top left cell has been hacked to duplicate the top right cell, to preserve symmetric seeds through a run
  24.  
  25. Yarrd = 41 'y should always be odd top preserve symmetry of center symmetric seed
  26.  
  27. xmax = (Xarrd + 2) * xspacing!: ymax = (Yarrd + 2) * yspacing!
  28.  
  29. SCREEN _NEWIMAGE(xmax, ymax, 32)
  30. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  31. DIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS cell, ng(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS INTEGER 'oversize the board to make it easy to count
  32.  
  33. DIM x, y, xoffset!, xStop, nc, c, r, mb, kh&
  34.  
  35.     _TITLE "Hexagon Life: Left Click to Toggle Cells On/Off, Right Click to Start Run, Escape to Quit"
  36.     ' set x, y for cells and mark ceter cell(s)
  37.     FOR y = 1 TO Yarrd
  38.         IF y MOD 2 = 0 THEN
  39.             xoffset! = .5 * xspacing!: xStop = Xarrd - 1
  40.         ELSE
  41.             xoffset! = 0: xStop = Xarrd
  42.         END IF
  43.         FOR x = 1 TO xStop
  44.             b(x, y).x = x * xspacing! + xoffset! + .5 * xspacing!
  45.             b(x, y).y = y * yspacing! + .5 * yspacing!
  46.             IF x = INT(Xarrd / 2 + .5) AND y = INT(Yarrd / 2 + .5) THEN b(x, y).L = 1 ELSE b(x, y).L = 0 'mark middle cell
  47.             showCell x, y, 7
  48.         NEXT
  49.     NEXT
  50.     _DISPLAY
  51.  
  52.     'setup seed by toggling cells on and off
  53.     WHILE mb <> 2
  54.         kh& = _KEYHIT
  55.         IF kh& = 27 THEN EXIT DO
  56.         mb = 0: c = 0: r = 0
  57.         getCell c, r, mb
  58.         IF mb = 1 THEN
  59.             b(c, r).L = 1 - b(c, r).L
  60.             showCell c, r, 7
  61.         END IF
  62.         _DISPLAY
  63.         _LIMIT 60
  64.     WEND
  65.     mb = 0
  66.     _TITLE "Hexagon Life: Spacebar to Restart/Reseed, Escape to Quit"
  67.     WHILE kh& <> 32 AND kh& <> 27
  68.         kh& = _KEYHIT
  69.         'count the neighbors
  70.         FOR y = 1 TO Yarrd
  71.             IF y MOD 2 = 0 THEN
  72.                 xoffset! = .5 * xspacing!: xStop = Xarrd - 1
  73.             ELSE
  74.                 xoffset! = 0: xStop = Xarrd
  75.             END IF
  76.             FOR x = 1 TO xStop
  77.                 '2 sets of neighbors depending if x offset or not
  78.                 IF xoffset! > .05 THEN
  79.                     nc = b(x, y - 1).L + b(x + 1, y - 1).L + b(x - 1, y).L
  80.                     nc = nc + b(x + 1, y).L + b(x, y + 1).L + b(x + 1, y + 1).L
  81.                 ELSE
  82.                     nc = b(x - 1, y - 1).L + b(x, y - 1).L + b(x - 1, y).L
  83.                     nc = nc + b(x + 1, y).L + b(x - 1, y + 1).L + b(x, y + 1).L
  84.                 END IF
  85.                 'originally tested and posted( 9/25/2019) here only 2 neighbors for birth in Classic Life it takes 3
  86.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  87.  
  88.                 'TempodiBasic suggested this survival if 1 survival or surviaval and birth for 2 neighbors
  89.                 IF (nc = 1 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  90.  
  91.                 ' my first test for TempodiBasic, I mistakenly ran this which is good too!
  92.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 1 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  93.  
  94.                 showCell x, y, nc
  95.                 IF x = Xarrd AND y = 1 THEN showCell 1, 1, nc
  96.             NEXT
  97.         NEXT
  98.  
  99.         'redraw all cells so no CLS
  100.         FOR y = 1 TO Yarrd 'transfer data from ng to b().l and show cell
  101.             IF y MOD 2 = 0 THEN
  102.                 xStop = Xarrd - 1
  103.             ELSE
  104.                 xStop = Xarrd
  105.             END IF
  106.             FOR x = 1 TO xStop
  107.                 b(x, y).L = ng(x, y)
  108.                 'showCell x, y
  109.             NEXT
  110.             'fix symmetry for top left corner, match x at other end for bi-lat symmetry
  111.             b(1, 1).L = b(Xarrd, 1).L
  112.             'showCell 1, 1
  113.         NEXT
  114.         _DISPLAY
  115.         _LIMIT 2
  116.     WEND
  117.     IF kh& = 27 THEN EXIT DO
  118.     kh& = 0
  119.  
  120. SUB showCell (c, r, kNum)
  121.     DIM da, x!, y!, lastx!, lasty!, clr AS _UNSIGNED LONG
  122.     IF r MOD 2 = 0 THEN
  123.         IF c < 1 OR c > Xarrd - 1 THEN EXIT SUB
  124.     ELSE
  125.         IF c < 1 OR c > Xarrd THEN EXIT SUB
  126.     END IF
  127.     IF r < 1 OR r > Yarrd THEN EXIT SUB
  128.  
  129.     IF kNum = 7 THEN
  130.         IF b(c, r).L = 1 THEN clr = &HFFFFFFFF ELSE clr = &HFF000000
  131.     ELSE
  132.         clr = k(kNum)
  133.     END IF
  134.     lastx! = b(c, r).x + cellR * COS(_D2R(-30))
  135.     lasty! = b(c, r).y + cellR * SIN(_D2R(-30))
  136.     FOR da = 30 TO 330 STEP 60
  137.         x! = b(c, r).x + cellR * COS(_D2R(da))
  138.         y! = b(c, r).y + cellR * SIN(_D2R(da))
  139.         IF kNum < 7 THEN LINE (lastx!, lasty!)-(x!, y!), clr ELSE LINE (lastx!, lasty!)-(x!, y!), &HFF440044
  140.         lastx! = x!: lasty! = y!
  141.     NEXT
  142.     IF kNum < 7 THEN PAINT (b(c, r).x, b(c, r).y), clr, clr ELSE PAINT (b(c, r).x, b(c, r).y), clr, &HFF440044
  143.  
  144.     'debug
  145.     'cText b(c, r).x, b(c, r).y, 16, &HFF888888, STR$(c) + "," + STR$(r)
  146.  
  147. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  148.     DIM m, mx, my, mb1, mb2, r, c
  149.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  150.     IF mb1 THEN mbNum = 1
  151.     IF mb2 THEN mbNum = 2
  152.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  153.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  154.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  155.             mx = _MOUSEX: my = _MOUSEY
  156.             'LOCATE 1, 1: PRINT SPACE$(50)
  157.             'LOCATE 1, 1: PRINT mx, my, .5 * xspacing!
  158.             _DISPLAY
  159.         WEND
  160.         FOR r = 1 TO Yarrd
  161.             FOR c = 1 TO Xarrd
  162.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xspacing! THEN
  163.                     returnCol = c: returnRow = r: EXIT SUB
  164.                 END IF
  165.             NEXT
  166.         NEXT
  167.         mbNum = 0 'still here then clicked wrong
  168.     END IF
  169.  
  170. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  171.     DIM a&
  172.     a& = _NEWIMAGE(1, 1, 32)
  173.     _DEST a&
  174.     PSET (0, 0), K
  175.     _DEST 0
  176.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  177.     _FREEIMAGE a& '<<< this is important!
  178.  
  179. 'debug
  180. SUB cText (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  181.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  182.     fg = _DEFAULTCOLOR
  183.     'screen snapshot
  184.     cur& = _DEST
  185.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  186.     _DEST I&
  187.     COLOR K, _RGBA32(0, 0, 0, 0)
  188.     _PRINTSTRING (0, 0), txt$
  189.     mult = textHeight / 16
  190.     xlen = LEN(txt$) * 8 * mult
  191.     _PUTIMAGE (x - .5 * xlen, y - .5 * textHeight)-STEP(xlen, textHeight), I&, cur&
  192.     COLOR fg
  193.     _FREEIMAGE I&
  194.  
  195.  

I just watched an episode of Ancient Aliens "The Guardian of the Badlands" jeez these people see faces everywhere and I have been abducted and programmed to share with you this code ;-))

 


BTW I have ftri code in to fix the messy lines and paint jobs but haven't gotten to it yet.
Title: Re: Hexagonal Life
Post by: bplus on September 28, 2019, 04:26:32 pm
Cleaned up the Hexagon drawing, changed colors and spent sometime trying to figure out how I seeded the previous screen shot?? stumped on that one!

Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-09-23 from Hex Minesweeper Custom Field
  2. '2019-09-25 post with original Life Rules
  3. '2019-09-27 OK let's try some more color!
  4. '2019-09-28 fix hexagon fills by not using PAINT
  5.  
  6. CONST cellR = 10 ' which makes the following constant
  7. CONST xSpacing = 2 * cellR * COS(_D2R(30))
  8. CONST ySpacing = cellR * (1 + SIN(_D2R(30)))
  9.  
  10. TYPE cell
  11.     x AS INTEGER
  12.     y AS INTEGER
  13.     L AS INTEGER
  14. k(0) = &HFF000000: k(1) = &HFFFFFF88: k(2) = &HFFDDDDFF: k(3) = &HFF550033: k(4) = &HFF005500: k(5) = &HFF000044: k(6) = &HFFFF0000
  15. DIM SHARED xmax AS INTEGER, ymax AS INTEGER, Xarrd AS INTEGER, Yarrd AS INTEGER 'set all this in customField sub
  16.  
  17.  
  18. '      note: To preserve symmetry when cells hit boundries with a symmetric seed started in middle:
  19. '            y should be odd for 1 center row
  20. '            x should be equal to or less than y
  21. '            If int(x/2 + .5) is even then the right one of two center cells is marked else the one center cell is marked
  22. '
  23.  
  24. Xarrd = 41 ' the top left cell has been hacked to duplicate the top right cell, to preserve symmetric seeds through a run
  25.  
  26. Yarrd = 41 'y should always be odd top preserve symmetry of center symmetric seed
  27.  
  28. xmax = (Xarrd + 2) * xSpacing: ymax = (Yarrd + 2) * ySpacing
  29.  
  30. SCREEN _NEWIMAGE(xmax, ymax, 32)
  31. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  32. DIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS cell, ng(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS INTEGER 'oversize the board to make it easy to count
  33.  
  34. DIM x AS INTEGER, y AS INTEGER, xoffset, xStop AS INTEGER, nc AS INTEGER, c AS INTEGER, r AS INTEGER, mb AS INTEGER, kh&
  35.  
  36.     _TITLE "Hexagon Life: Left Click to Toggle Cells On/Off, Right Click to Start Run, Escape to Quit"
  37.     ' set x, y for cells and mark ceter cell(s)
  38.     FOR y = 1 TO Yarrd
  39.         IF y MOD 2 = 0 THEN
  40.             xoffset = .5 * xSpacing: xStop = Xarrd - 1
  41.         ELSE
  42.             xoffset = 0: xStop = Xarrd
  43.         END IF
  44.         FOR x = 1 TO xStop
  45.             b(x, y).x = x * xSpacing + xoffset + .5 * xSpacing
  46.             b(x, y).y = y * ySpacing + .5 * ySpacing
  47.             IF x = INT(Xarrd / 2 + .5) AND y = INT(Yarrd / 2 + .5) THEN b(x, y).L = 1 ELSE b(x, y).L = 0 'mark middle cell
  48.             showCell x, y, 7
  49.         NEXT
  50.     NEXT
  51.     _DISPLAY
  52.  
  53.     'setup seed by toggling cells on and off
  54.     WHILE mb <> 2
  55.         kh& = _KEYHIT
  56.         IF kh& = 27 THEN EXIT DO
  57.         mb = 0: c = 0: r = 0
  58.         getCell c, r, mb
  59.         IF mb = 1 THEN
  60.             b(c, r).L = 1 - b(c, r).L
  61.             showCell c, r, 7
  62.         END IF
  63.         _DISPLAY
  64.         _LIMIT 60
  65.     WEND
  66.     mb = 0
  67.     _TITLE "Hexagon Life: Spacebar to Restart/Reseed, Escape to Quit"
  68.     WHILE kh& <> 32 AND kh& <> 27
  69.         kh& = _KEYHIT
  70.         'count the neighbors
  71.         FOR y = 1 TO Yarrd
  72.             IF y MOD 2 = 0 THEN
  73.                 xoffset = .5 * xSpacing: xStop = Xarrd - 1
  74.             ELSE
  75.                 xoffset = 0: xStop = Xarrd
  76.             END IF
  77.             FOR x = 1 TO xStop
  78.                 '2 sets of neighbors depending if x offset or not
  79.                 IF xoffset > .05 THEN
  80.                     nc = b(x, y - 1).L + b(x + 1, y - 1).L + b(x - 1, y).L
  81.                     nc = nc + b(x + 1, y).L + b(x, y + 1).L + b(x + 1, y + 1).L
  82.                 ELSE
  83.                     nc = b(x - 1, y - 1).L + b(x, y - 1).L + b(x - 1, y).L
  84.                     nc = nc + b(x + 1, y).L + b(x - 1, y + 1).L + b(x, y + 1).L
  85.                 END IF
  86.                 'originally tested and posted( 9/25/2019) here only 2 neighbors for birth in Classic Life it takes 3
  87.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  88.  
  89.                 'TempodiBasic suggested this survival if 1 survival or surviaval and birth for 2 neighbors
  90.                 IF (nc = 1 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  91.  
  92.                 ' my first test for TempodiBasic, I mistakenly ran this which is good too!
  93.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 1 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  94.  
  95.                 showCell x, y, nc
  96.                 IF x = Xarrd AND y = 1 THEN showCell 1, 1, nc
  97.             NEXT
  98.         NEXT
  99.  
  100.         'redraw all cells so no CLS
  101.         FOR y = 1 TO Yarrd 'transfer data from ng to b().l and show cell
  102.             IF y MOD 2 = 0 THEN
  103.                 xStop = Xarrd - 1
  104.             ELSE
  105.                 xStop = Xarrd
  106.             END IF
  107.             FOR x = 1 TO xStop
  108.                 b(x, y).L = ng(x, y)
  109.                 'showCell x, y
  110.             NEXT
  111.             'fix symmetry for top left corner, match x at other end for bi-lat symmetry
  112.             b(1, 1).L = b(Xarrd, 1).L
  113.             'showCell 1, 1
  114.         NEXT
  115.         _DISPLAY
  116.         _LIMIT 1
  117.     WEND
  118.     IF kh& = 27 THEN EXIT DO
  119.     kh& = 0
  120.  
  121. SUB showCell (c AS INTEGER, r AS INTEGER, kNum AS INTEGER)
  122.     DIM clr AS _UNSIGNED LONG
  123.     IF r MOD 2 = 0 THEN
  124.         IF c < 1 OR c > Xarrd - 1 THEN EXIT SUB
  125.     ELSE
  126.         IF c < 1 OR c > Xarrd THEN EXIT SUB
  127.     END IF
  128.     IF r < 1 OR r > Yarrd THEN EXIT SUB
  129.     IF kNum = 7 THEN
  130.         IF b(c, r).L = 1 THEN clr = &HFFFFFFFF ELSE clr = &HFF000000
  131.     ELSE
  132.         clr = k(kNum)
  133.     END IF
  134.     IF kNum < 7 THEN
  135.         fHexH b(c, r).x, b(c, r).y, cellR, clr
  136.         hexH b(c, r).x, b(c, r).y, cellR, &HFF000000
  137.     ELSE
  138.         fHexH b(c, r).x, b(c, r).y, cellR, clr
  139.         hexH b(c, r).x, b(c, r).y, cellR, &HFF440044
  140.     END IF
  141.  
  142. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  143.     DIM m, mx, my, mb1, mb2, r AS INTEGER, c AS INTEGER
  144.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  145.     IF mb1 THEN mbNum = 1
  146.     IF mb2 THEN mbNum = 2
  147.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  148.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  149.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  150.             mx = _MOUSEX: my = _MOUSEY
  151.             'LOCATE 1, 1: PRINT SPACE$(50)
  152.             'LOCATE 1, 1: PRINT mx, my, .5 * xSpacing
  153.             _DISPLAY
  154.         WEND
  155.         FOR r = 1 TO Yarrd
  156.             FOR c = 1 TO Xarrd
  157.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xSpacing THEN
  158.                     'LOCATE 1, 1: PRINT SPACE$(50)
  159.                     'LOCATE 1, 1: PRINT c, r
  160.                     returnCol = c: returnRow = r: EXIT SUB
  161.                 END IF
  162.             NEXT
  163.         NEXT
  164.         mbNum = 0 'still here then clicked wrong
  165.     END IF
  166.  
  167. 'draw Hexagon Outline that can be packed Horizontally, flat edge to flat edge
  168. SUB hexH (xOrigin AS SINGLE, yOrigin AS SINGLE, radius AS SINGLE, c AS _UNSIGNED LONG)
  169.     DIM polyAngle AS SINGLE, aOff AS SINGLE, x1 AS SINGLE, y1 AS SINGLE, i AS INTEGER, x2 AS SINGLE, y2 AS SINGLE
  170.     polyAngle = _PI(2) / 6: aOff = _PI / 2
  171.     x1 = xOrigin + radius * COS(polyAngle + aOff)
  172.     y1 = yOrigin + radius * SIN(polyAngle + aOff)
  173.     FOR i = 2 TO 7
  174.         x2 = xOrigin + radius * COS(i * polyAngle + aOff)
  175.         y2 = yOrigin + radius * SIN(i * polyAngle + aOff)
  176.         LINE (x1, y1)-(x2, y2), c
  177.         x1 = x2: y1 = y2
  178.     NEXT
  179.  
  180. 'draw filled Hexagon that can be packed Horizontally, flat edge to flat edge
  181. 'uses SUB fTri
  182. SUB fHexH (xOrigin AS SINGLE, yOrigin AS SINGLE, radius AS SINGLE, c AS _UNSIGNED LONG)
  183.     DIM polyAngle AS SINGLE, aOff AS SINGLE, x1 AS SINGLE, y1 AS SINGLE, i AS INTEGER, x2 AS SINGLE, y2 AS SINGLE
  184.     polyAngle = _PI(2) / 6: aOff = _PI / 2
  185.     x1 = xOrigin + radius * COS(polyAngle + aOff)
  186.     y1 = yOrigin + radius * SIN(polyAngle + aOff)
  187.     FOR i = 2 TO 7
  188.         x2 = xOrigin + radius * COS(i * polyAngle + aOff)
  189.         y2 = yOrigin + radius * SIN(i * polyAngle + aOff)
  190.         fTri xOrigin, yOrigin, x1, y1, x2, y2, c
  191.         x1 = x2: y1 = y2
  192.     NEXT
  193.  
  194. SUB fTri (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE, x3 AS SINGLE, y3 AS SINGLE, K AS _UNSIGNED LONG)
  195.     DIM a&
  196.     a& = _NEWIMAGE(1, 1, 32)
  197.     _DEST a&
  198.     PSET (0, 0), K
  199.     _DEST 0
  200.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  201.     _FREEIMAGE a& '<<< this is important!
  202.  
  203.  
 [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Hexagonal Life
Post by: TempodiBasic on September 29, 2019, 03:18:50 pm
Hi Bplus I think that both the model with original rules both that you have coded following my suggestion suffer of overpopulation!

However I find 2 seed for the same permanent entity!

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Hexagonal Life
Post by: bplus on September 30, 2019, 11:03:07 am
Yeah, I don't know how well explored Hexagon Life is compared to Classic Conway Life action at the boundary lines is not as neat as with Classic because of 6 way symmetry versus 4 way of Classic so maybe the playing field needs to be hexagonal also? How about Hexagonal arrays to hold the data also!?!

But you might run into some of the same problems if the square or rectangular cells were stagger-stacked like bricks.

I wonder if there exist a set of rules for Hexagonal Life that would yield the equivalent of a glider gun or something equally as amazing. I have noticed that stable blinkers usually cycle in multiples of 3, like the one TempodiBasic is showing.
Title: Re: Hexagonal Life
Post by: bplus on September 30, 2019, 12:00:18 pm
Face maker seeds,

Title: Re: Hexagonal Life
Post by: SierraKen on September 30, 2019, 03:33:30 pm
LOL this one is much better! After around 30 seconds or so it filled the entire screen. :) You also might want to add in the _TITLE "Generations: "+g  where g is how many times they multiply. Really cool. Or you can use a different word than Generations.
Title: Re: Hexagonal Life
Post by: bplus on September 30, 2019, 04:21:46 pm
LOL this one is much better! After around 30 seconds or so it filled the entire screen. :) You also might want to add in the _TITLE "Generations: "+g  where g is how many times they multiply. Really cool. Or you can use a different word than Generations.

Good idea Ken, I usually do have generation on screen.
Code: QB64: [Select]
  1. OPTION _EXPLICIT 'Bplus started 2019-09-23 from Hex Minesweeper Custom Field
  2. '2019-09-25 post with original Life Rules
  3. '2019-09-27 OK let's try some more color!
  4. '2019-09-28 fix hexagon fills by not using PAINT
  5. '2019-09-30 add Generation as suggested by Ken
  6.  
  7. CONST cellR = 10 ' which makes the following constant
  8. CONST xSpacing = 2 * cellR * COS(_D2R(30))
  9. CONST ySpacing = cellR * (1 + SIN(_D2R(30)))
  10.  
  11. TYPE cell
  12.     x AS INTEGER
  13.     y AS INTEGER
  14.     L AS INTEGER
  15. k(0) = &HFF000000: k(1) = &HFFFFFF88: k(2) = &HFFDDDDFF: k(3) = &HFF550033: k(4) = &HFF005500: k(5) = &HFF000044: k(6) = &HFFFF0000
  16. DIM SHARED xmax AS INTEGER, ymax AS INTEGER, Xarrd AS INTEGER, Yarrd AS INTEGER 'set all this in customField sub
  17.  
  18.  
  19. '      note: To preserve symmetry when cells hit boundries with a symmetric seed started in middle:
  20. '            y should be odd for 1 center row
  21. '            x should be equal to or less than y
  22. '            If int(x/2 + .5) is even then the right one of two center cells is marked else the one center cell is marked
  23. '
  24.  
  25. Xarrd = 41 ' the top left cell has been hacked to duplicate the top right cell, to preserve symmetric seeds through a run
  26.  
  27. Yarrd = 41 'y should always be odd top preserve symmetry of center symmetric seed
  28.  
  29. xmax = (Xarrd + 2) * xSpacing: ymax = (Yarrd + 2) * ySpacing
  30.  
  31. SCREEN _NEWIMAGE(xmax, ymax, 32)
  32. _SCREENMOVE (1280 - xmax) / 2 + 60, (760 - ymax) / 2
  33. DIM SHARED b(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS cell, ng(0 TO Xarrd + 1, 0 TO Yarrd + 1) AS INTEGER 'oversize the board to make it easy to count
  34.  
  35. DIM x AS INTEGER, y AS INTEGER, xoffset, xStop AS INTEGER, nc AS INTEGER, c AS INTEGER, r AS INTEGER, mb AS INTEGER, kh&, gen AS INTEGER
  36.  
  37.     _TITLE "Hexagon Life: Left Click to Toggle Cells On/Off, Right Click to Start Run, Escape to Quit"
  38.     ' set x, y for cells and mark ceter cell(s)
  39.     FOR y = 1 TO Yarrd
  40.         IF y MOD 2 = 0 THEN
  41.             xoffset = .5 * xSpacing: xStop = Xarrd - 1
  42.         ELSE
  43.             xoffset = 0: xStop = Xarrd
  44.         END IF
  45.         FOR x = 1 TO xStop
  46.             b(x, y).x = x * xSpacing + xoffset + .5 * xSpacing
  47.             b(x, y).y = y * ySpacing + .5 * ySpacing
  48.             IF x = INT(Xarrd / 2 + .5) AND y = INT(Yarrd / 2 + .5) THEN b(x, y).L = 1 ELSE b(x, y).L = 0 'mark middle cell
  49.             showCell x, y, 7
  50.         NEXT
  51.     NEXT
  52.     _DISPLAY
  53.  
  54.     'setup seed by toggling cells on and off
  55.     WHILE mb <> 2
  56.         kh& = _KEYHIT
  57.         IF kh& = 27 THEN EXIT DO
  58.         mb = 0: c = 0: r = 0
  59.         getCell c, r, mb
  60.         IF mb = 1 THEN
  61.             b(c, r).L = 1 - b(c, r).L
  62.             showCell c, r, 7
  63.         END IF
  64.         _DISPLAY
  65.         _LIMIT 60
  66.     WEND
  67.     mb = 0
  68.     _TITLE "Hexagon Life: Spacebar to Restart/Reseed, Escape to Quit"
  69.     WHILE kh& <> 32 AND kh& <> 27
  70.         kh& = _KEYHIT
  71.         'count the neighbors
  72.         FOR y = 1 TO Yarrd
  73.             IF y MOD 2 = 0 THEN
  74.                 xoffset = .5 * xSpacing: xStop = Xarrd - 1
  75.             ELSE
  76.                 xoffset = 0: xStop = Xarrd
  77.             END IF
  78.             FOR x = 1 TO xStop
  79.                 '2 sets of neighbors depending if x offset or not
  80.                 IF xoffset > .05 THEN
  81.                     nc = b(x, y - 1).L + b(x + 1, y - 1).L + b(x - 1, y).L
  82.                     nc = nc + b(x + 1, y).L + b(x, y + 1).L + b(x + 1, y + 1).L
  83.                 ELSE
  84.                     nc = b(x - 1, y - 1).L + b(x, y - 1).L + b(x - 1, y).L
  85.                     nc = nc + b(x + 1, y).L + b(x - 1, y + 1).L + b(x, y + 1).L
  86.                 END IF
  87.                 'originally tested and posted( 9/25/2019) here only 2 neighbors for birth in Classic Life it takes 3
  88.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  89.  
  90.                 'TempodiBasic suggested this survival if 1 survival or surviaval and birth for 2 neighbors
  91.                 IF (nc = 1 AND b(x, y).L = 1) OR nc = 2 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  92.  
  93.                 ' my first test for TempodiBasic, I mistakenly ran this which is good too!
  94.                 'IF (nc = 3 AND b(x, y).L = 1) OR nc = 1 THEN ng(x, y) = 1 ELSE ng(x, y) = 0
  95.  
  96.                 showCell x, y, nc
  97.                 IF x = Xarrd AND y = 1 THEN showCell 1, 1, nc
  98.             NEXT
  99.         NEXT
  100.  
  101.         'redraw all cells so no CLS
  102.         FOR y = 1 TO Yarrd 'transfer data from ng to b().l and show cell
  103.             IF y MOD 2 = 0 THEN
  104.                 xStop = Xarrd - 1
  105.             ELSE
  106.                 xStop = Xarrd
  107.             END IF
  108.             FOR x = 1 TO xStop
  109.                 b(x, y).L = ng(x, y)
  110.                 'showCell x, y
  111.             NEXT
  112.             'fix symmetry for top left corner, match x at other end for bi-lat symmetry
  113.             b(1, 1).L = b(Xarrd, 1).L
  114.             'showCell 1, 1
  115.         NEXT
  116.         gen = gen + 1
  117.         LOCATE 1, 1: PRINT SPACE$(50)
  118.         LOCATE 1, 1: PRINT "Generation:"; gen
  119.         _DISPLAY
  120.         _LIMIT 1
  121.     WEND
  122.     IF kh& = 27 THEN EXIT DO
  123.     kh& = 0
  124.  
  125. SUB showCell (c AS INTEGER, r AS INTEGER, kNum AS INTEGER)
  126.     DIM clr AS _UNSIGNED LONG
  127.     IF r MOD 2 = 0 THEN
  128.         IF c < 1 OR c > Xarrd - 1 THEN EXIT SUB
  129.     ELSE
  130.         IF c < 1 OR c > Xarrd THEN EXIT SUB
  131.     END IF
  132.     IF r < 1 OR r > Yarrd THEN EXIT SUB
  133.     IF kNum = 7 THEN
  134.         IF b(c, r).L = 1 THEN clr = &HFFFFFFFF ELSE clr = &HFF000000
  135.     ELSE
  136.         clr = k(kNum)
  137.     END IF
  138.     IF kNum < 7 THEN
  139.         fHexH b(c, r).x, b(c, r).y, cellR, clr
  140.         hexH b(c, r).x, b(c, r).y, cellR, &HFF000000
  141.     ELSE
  142.         fHexH b(c, r).x, b(c, r).y, cellR, clr
  143.         hexH b(c, r).x, b(c, r).y, cellR, &HFF440044
  144.     END IF
  145.  
  146. SUB getCell (returnCol AS INTEGER, returnRow AS INTEGER, mbNum AS INTEGER)
  147.     DIM m, mx, my, mb1, mb2, r AS INTEGER, c AS INTEGER
  148.     mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  149.     IF mb1 THEN mbNum = 1
  150.     IF mb2 THEN mbNum = 2
  151.     IF mb1 OR mb2 THEN '                      get last place mouse button was down
  152.         WHILE mb1 OR mb2 '                    wait for mouse button release as a "click"
  153.             m = _MOUSEINPUT: mb1 = _MOUSEBUTTON(1): mb2 = _MOUSEBUTTON(2)
  154.             mx = _MOUSEX: my = _MOUSEY
  155.             'LOCATE 1, 1: PRINT SPACE$(50)
  156.             'LOCATE 1, 1: PRINT mx, my, .5 * xSpacing
  157.             _DISPLAY
  158.         WEND
  159.         FOR r = 1 TO Yarrd
  160.             FOR c = 1 TO Xarrd
  161.                 IF ((mx - b(c, r).x) ^ 2 + (my - b(c, r).y) ^ 2) ^ .5 < .5 * xSpacing THEN
  162.                     'LOCATE 1, 1: PRINT SPACE$(50)
  163.                     'LOCATE 1, 1: PRINT c, r
  164.                     returnCol = c: returnRow = r: EXIT SUB
  165.                 END IF
  166.             NEXT
  167.         NEXT
  168.         mbNum = 0 'still here then clicked wrong
  169.     END IF
  170.  
  171. 'draw Hexagon Outline that can be packed Horizontally, flat edge to flat edge
  172. SUB hexH (xOrigin AS SINGLE, yOrigin AS SINGLE, radius AS SINGLE, c AS _UNSIGNED LONG)
  173.     DIM polyAngle AS SINGLE, aOff AS SINGLE, x1 AS SINGLE, y1 AS SINGLE, i AS INTEGER, x2 AS SINGLE, y2 AS SINGLE
  174.     polyAngle = _PI(2) / 6: aOff = _PI / 2
  175.     x1 = xOrigin + radius * COS(polyAngle + aOff)
  176.     y1 = yOrigin + radius * SIN(polyAngle + aOff)
  177.     FOR i = 2 TO 7
  178.         x2 = xOrigin + radius * COS(i * polyAngle + aOff)
  179.         y2 = yOrigin + radius * SIN(i * polyAngle + aOff)
  180.         LINE (x1, y1)-(x2, y2), c
  181.         x1 = x2: y1 = y2
  182.     NEXT
  183.  
  184. 'draw filled Hexagon that can be packed Horizontally, flat edge to flat edge
  185. 'uses SUB fTri
  186. SUB fHexH (xOrigin AS SINGLE, yOrigin AS SINGLE, radius AS SINGLE, c AS _UNSIGNED LONG)
  187.     DIM polyAngle AS SINGLE, aOff AS SINGLE, x1 AS SINGLE, y1 AS SINGLE, i AS INTEGER, x2 AS SINGLE, y2 AS SINGLE
  188.     polyAngle = _PI(2) / 6: aOff = _PI / 2
  189.     x1 = xOrigin + radius * COS(polyAngle + aOff)
  190.     y1 = yOrigin + radius * SIN(polyAngle + aOff)
  191.     FOR i = 2 TO 7
  192.         x2 = xOrigin + radius * COS(i * polyAngle + aOff)
  193.         y2 = yOrigin + radius * SIN(i * polyAngle + aOff)
  194.         fTri xOrigin, yOrigin, x1, y1, x2, y2, c
  195.         x1 = x2: y1 = y2
  196.     NEXT
  197.  
  198. SUB fTri (x1 AS SINGLE, y1 AS SINGLE, x2 AS SINGLE, y2 AS SINGLE, x3 AS SINGLE, y3 AS SINGLE, K AS _UNSIGNED LONG)
  199.     DIM a&
  200.     a& = _NEWIMAGE(1, 1, 32)
  201.     _DEST a&
  202.     PSET (0, 0), K
  203.     _DEST 0
  204.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  205.     _FREEIMAGE a& '<<< this is important!
  206.  
  207.  

Ha! I am finding faces everywhere today (not exactly human but...) ;-))


Title: Re: Hexagonal Life
Post by: TempodiBasic on September 30, 2019, 05:30:01 pm
Yes you can find so many faces... but too fast to be catched by a screenshot

here more permanent blinker
  [ This attachment cannot be displayed inline in 'Print Page' view ]