01-23-2025, 08:50 AM
Game of life (MOD)
Just another modified version
Features :
- Two modes:
R reset mode, where you can create your own pattern or use preset patterns
S life animation mode, where life is in action
- Allow intervention (add 1 or more cells) to break a stable & oscillator pattern in the "S" mode
- Ready to use some preset patterns (1,2,3) either in the "R" or "S" mode
Then launch preset patterns several times in the "S" mode
- Sound effect
Control Key :
- Left/Right mouse = add/remove 1 cell
- 1,2,3 = preset patterns
- S = start life animation
- R = reset
- ESC = exit
References :
- Game of Life by Marcus in N7 folder /examples/other
- CreateSineSfx by Marcus
Need help / future improvement :
- Turn on / off wrapping pattern on the world boundaries
- Stable pattern in the R mode should stay stable in the S mode
- Zoom in / out
- Save and load customized pattern to/from JSON file format
- Ability to resize the world
- Add more preset patterns
- Find and fix any bugs
Just another modified version
Features :
- Two modes:
R reset mode, where you can create your own pattern or use preset patterns
S life animation mode, where life is in action
- Allow intervention (add 1 or more cells) to break a stable & oscillator pattern in the "S" mode
- Ready to use some preset patterns (1,2,3) either in the "R" or "S" mode
Then launch preset patterns several times in the "S" mode
- Sound effect
Control Key :
- Left/Right mouse = add/remove 1 cell
- 1,2,3 = preset patterns
- S = start life animation
- R = reset
- ESC = exit
References :
- Game of Life by Marcus in N7 folder /examples/other
- CreateSineSfx by Marcus
Need help / future improvement :
- Turn on / off wrapping pattern on the world boundaries
- Stable pattern in the R mode should stay stable in the S mode
- Zoom in / out
- Save and load customized pattern to/from JSON file format
- Ability to resize the world
- Add more preset patterns
- Find and fix any bugs
Code:
'============================================================================
' Game of life (MOD)
' ------------------
' Just another modified version
'
' Features :
' - Two modes:
' R reset mode, where you can create your own pattern or use preset patterns
' S life animation mode, where life is in action
' - Allow intervention (add 1 or more cells) to break a stable & oscillator pattern in the "S" mode
' - Ready to use some preset patterns (1,2,3) either in the "R" or "S" mode
' Then launch preset patterns several times in the "S" mode.
' - Sound effect
'
' Control Key :
' - Left/Right mouse = add/remove 1 cell
' - 1,2,3 = preset patterns
' - S = start life animation
' - R = reset
' - ESC = exit
'
' References :
' - Game of Life by Marcus in N7 folder /examples/other
' - CreateSineSfx by Marcus
'
' Need help / future improvement :
' - Turn on / off wrapping pattern on the world boundaries
' - Stable pattern in the R mode should stay stable in the S mode
' - Zoom in / out
' - Save and load customized pattern to/from JSON file format
' - Ability to resize the world
' - Add more preset patterns
' - Find and fix any bugs
'============================================================================
constant W = 48, H = 48
'set window size
set window "Game of life (MOD)", W, H, 10
set redraw off
'sound definition (duration, startFreq, endFreq, fadeOut, sampleRate)
visible tiktok = CreateSineSfx(0.02,1500,500,0.05,5000)
' Create a world.
world = CreateWorld(W, H)
'Initial value
visible start = true
'draw grid
Grid(H,W)
'------------
' MAIN LOOP
'------------
' Loop until ESC is pressed.
do
'--------PRESET PATTERNS-----------------'
set color 255,255,255
'Johnno's pattern
if keydown (KEY_1,true) then
for i = 23 to 25
SetCell(world,i,30,1); set pixel i,30
next
SetCell(world,24,31,1); set pixel 24,31
SetCell(world,25,32,1); set pixel 25,32
endif
'Glider spaceships pattern
if keydown(KEY_2,true) then
SetCell(world,5,5,1); set pixel 5,5
SetCell(world,6,6,1); set pixel 6,6
for i = 4 to 6
SetCell(world,7,i,1);set pixel 7,i
next
endif
'Pentadecathlon pattern
if keydown(KEY_3,true) then
for i = 23 to 25
SetCell(world,i,10,1);set pixel i,10
SetCell(world,i,19,1);set pixel i,19
next
for i = 14 to 15
SetCell(world,20,i,1); set pixel 20,i
SetCell(world,28,i,1); set pixel 28,i
next
SetCell(world,21,12,1);set pixel 21,12
SetCell(world,21,17,1);set pixel 21,17
SetCell(world,22,11,1);set pixel 22,11
SetCell(world,22,18,1);set pixel 22,18
SetCell(world,26,11,1);set pixel 26,11
SetCell(world,26,18,1);set pixel 26,18
SetCell(world,27,12,1);set pixel 27,12
SetCell(world,27,17,1);set pixel 27,17
endif
'-----------------------------------------'
'mouse interactivity
if mousex()<W-1 then 'boundary limit
if mousebutton(0) ModifyLife(world, mousex(), mousey(), 1)
if mousebutton(1) ModifyLife(world, mousex(), mousey(), 0)
endif
'start
if start then
set color 0,0,0
set caret 52,35
wln "S"
set color 255,0,0
set caret 52,35
wln "R"
endif
'S mode
if keydown(KEY_S) or start= false then
UpdateWorld(world,W,H)
DrawWorld(world, 0, 0, false)
start = false
set color 0,0,0
set caret 52,35
wln "R"
set color 0,255,0
set caret 52,35
wln "S"
endif
'restart in R mode
if keydown(KEY_R) then
set color 0,0,0
cls
set color 255,255,255
Grid(H,W)
world = CreateWorld(W, H) 'reset world
start = true
set color 0,0,0
set caret 52,35
wln "S"
set color 255,0,0
set caret 52,35
wln "R"
endif
redraw
fwait 10
until keydown(KEY_ESCAPE)
'-------------
' FUNCTIONS
'-------------
' CreateWorld
' -----------
function CreateWorld(w, h)
world = []
' These arrays represents the word's current and previous state. We need the
' previous when generating the current. They're simply swapped in
' UpdateWorld.
world.c = fill(0, w, h)
world.p = fill(0, w, h)
world.w = w
world.h = h
' UpdateWorld only updates cells that are present in this table. Whenever a
' change is made to a cell, it and its neighbors are added to the table.
' The table is reset (or rather replaced) every time UpdateWorld executes.
world.ch = []
world.img = createimage(w, h)
return world
endfunc
' ModifyLife
' ----------
function ModifyLife(w, cx, cy, value)
SetCell(w,cx,cy,value)
if value then
set color 255,255,255
set pixel cx,cy
else
set color 30,30,30
set pixel cx,cy
endif
endfunc
' SetCell
' -------
function SetCell(world, x, y, value)
x = x%world.w
y = y%world.h
world.c[x][y] = value
' Only cells that MAY change are handled in UpdateWorld. So add the current
' cell and its neighbors to the ch table.
' Rather than storing the cell x and y coordinates as values, we
' transform them into a key using the forumula k = y*w + x. We can then
' extract the coordinates from the key as y = int(k/w) and x = k%w.
world.ch[((y - 1)%world.h)*world.w + (x - 1)%world.w] = unset
world.ch[((y - 1)%world.h)*world.w + (x)] = unset
world.ch[((y - 1)%world.h)*world.w + (x + 1)%world.w] = unset
world.ch[(y)*world.w + (x - 1)%world.w] = unset
world.ch[(y)*world.w + (x)] = unset
world.ch[(y)*world.w + (x + 1)%world.w] = unset
world.ch[((y + 1)%world.h)*world.w + (x - 1)%world.w] = unset
world.ch[((y + 1)%world.h)*world.w + (x)] = unset
world.ch[((y + 1)%world.h)*world.w + (x + 1)%world.w] = unset
endfunc
' UpdateWorld
' -----------
function UpdateWorld(world,W,H)
tmp = world.p
world.p = world.c
world.c = tmp
' Grab the ch table, containing cells that may change.
ch = world.ch
' Create a new ch list for the world.
world.ch = []
' Iterate cells that may have changed.
set image world.img
Grid(W,H)
foreach k, v in ch
' Convert the key k into coordinates.
y = int(k/world.w)
x = k%world.w
' Count neighbors.
t = (y - 1)%world.h
b = (y + 1)%world.h
l = (x - 1)%world.w
r = (x + 1)%world.w
n = world.p[l][t] + world.p[x][t] + world.p[r][t]
n = n + world.p[l][y] + world.p[r][y]
n = n + world.p[l][b] + world.p[x][b] + world.p[r][b]
' Alive?
if world.p[x][y]
' Die.
if n < 2 or n > 3
SetCell(world, x, y, 0)
set color 0, 0, 0
set pixel x, y
else
world.c[x][y] = 1
endif
' Dead.
else
' Live.
if n = 3
SetCell(world, x, y, 1)
set color 55+rnd(200),200+rnd(55),128+rnd(55)
set pixel x, y
play sound tiktok,0.5
else
world.c[x][y] = 0
endif
endif
next
set color 155,155,155
draw rect 0,0,W,H
set image primary
' The previous ch list of the world, that we kept in ch, will eventually be
' garbage collected. But to avoid high memory usage we can clear it before
' it is lost in garbage space.
clear ch
endfunc
' DrawWorld
' ---------
function DrawWorld(world, x, y, plotAll)
if plotAll
set color 0, 0, 0
draw rect x+1, y+1, world.w-2, world.h-2, true
set color 255, 255, 255
for cy = 0 to world.h - 2 for cx = 0 to world.w - 2
if world.p[cx][cy] then
set pixel x + cx, y + cy
endif
next
else
set color 255, 255, 255
draw image world.img, x, y
endif
endfunc
'grid function
function Grid(H,W)
for i = 1 to H-1 step 2
for j = 1 to W-1 step 2
set color 50,50,50
set pixel j,i
next
next
for i = 2 to H-2 step 2
for j = 2 to W-2 step 2
set color 50,50,50
set pixel j,i
next
next
set color 155,155,155
draw rect 0,0,W,H
endfunc
'sound effect function
function CreateSineSfx(duration, startFreq, endFreq, fadeOut, sampleRate)
data = []
a = 0
da = 2*PI*startFreq/sampleRate
dda = (2*PI*endFreq/sampleRate - 2*PI*startFreq/sampleRate)/(duration*sampleRate)
vol = 1
fadeOut = fadeOut*duration*sampleRate
fadeOutDelta = 1/(duration*sampleRate - fadeOut)
for i = 0 to duration*sampleRate - 1
data[i] = sin(a)*vol
a = a + da
da = da + dda
if i > fadeOut vol = vol - fadeOutDelta
next
return createsound(data, data, sampleRate)
endfunc