update! (the EXE at the begining is also updated)
gosub ini
place_random_molecules()
place_cell_membrane()
REM for testing
`global circle_x = 0
`global circle_y = 0
global x_move_count
global y_move_count
global net_x_move
global net_y_move
do
if pause_sim = 0 or step_sim = 1
REM for testing
x_move_count = 0
y_move_count = 0
REM set molecule counters
for mol_id = 0 to max_mol
mol(mol_id).count = 0
next mol_id
REM add particles at fountains
place_molecules()
REM do molecules
for x = 2 to 298
for y = 2 to 298
if g(x,y) = id_test_enzyme then do_test_enzyme(x,y)
next y
next x
REM move molecules and count molecules
for x = 2 to 298
for y = 2 to 298
if g(x,y) > 0
mol_id = g(x,y)
inc mol(mol_id).count
if mol(mol_id).move = "float" then move_molecule(x,y,mol_id)
endif
next y
next x
REM update grid
for x = 0 to 300
for y = 0 to 300
g(x,y) = ng(x,y)
next y
next x
step_sim = 0
endif
REM display
cls
show_interface()
inc sync_counter
if sync_counter = sync_frequency
sync_counter = 0
show_grid()
endif
sync
REM for testing
`ink rgb(255,255,255),0
`circle circle_x+256, circle_y+10, 5
`sync
`wait key
loop
function place_molecules()
REM ATP fountain
g(150,150) = id_atp
endfunction
REM DO MOLECULES
function move_molecule(x, y, typ)
REM find a random direction to move where there is no other molecule
move = get_random_direction_no_diag(x, y)
if move = 1
ng(x+x_move, y+y_move) = typ
ng(x, y) = 0
g(x, y) = 0
else
ng(x, y) = typ
endif
endfunction
function do_test_enzyme(x, y)
REM IF there is (left) ATP (above) ATP (right) glucose (below) nothing
REM THEN turn ATP's into ADP and turn glucose into two G3Ps
if g(x+1, y) = id_glucose and g(x, y+1) = 0 and g(x-1, y) = id_atp and g(x, y-1) = id_atp
g(x+1, y) = id_g3p
g(x, y+1) = id_g3p
g(x-1, y) = id_adp
g(x, y-1) = id_adp
endif
endfunction
REM FUNCTIONS FOR DOING MOLECULES
function get_random_direction_no_diag(x, y)
repeat
rnd_dir = rnd(4)
if x > 296 then rnd_dir = 4
if x < 4 then rnd_dir = 2
if y > 296 then rnd_dir = 1
if y < 4 then rnd_dir = 3
if rnd_dir = 1 then x_move = 0: y_move = -1
if rnd_dir = 2 then x_move = 1: y_move = 0
if rnd_dir = 3 then x_move = 0: y_move = 1
if rnd_dir = 4 then x_move = -1: y_move = 0
if ng(x + x_move, y + y_move) = 0 and g(x + x_move, y + y_move) = 0 then found = 1
inc counter
if counter = 10 then found = 2
until found > 0
if found = 2
x_move = 0
y_move = 0
else
REM for testing
x_move_count = x_move_count + x_move
y_move_count = y_move_count + y_move
endif
endfunction found
function get_random_direction_yes_diag(x, y)
repeat
x_move = rnd(2) - 1
y_move = rnd(2) - 1
if x > 296 then x_move = -1
if x < 4 then x_move = 1
if y > 296 then y_move = -1
if y < 4 then y_move = 1
if ng(x + x_move, y + y_move) = 0 then found = 1
inc counter
if counter = 10 then found = 2
until found > 0
if found = 2
x_move = 0
y_move = 0
endif
endfunction found
REM DISPLAY DATA FOR USER
function show_grid()
for x = 0 to 300
for y = 0 to 300
if g(x,y) > 0
mol_id = g(x,y)
red = mol(mol_id).r
green = mol(mol_id).g
blue = mol(mol_id).b
ink rgb(red, green, blue), 0
box x+320, y+120, x+321, y+121
endif
next y
next x
show_molecule_counts()
endfunction
function show_interface()
REM mouseclick variable for buttons
oldmc = mc
mc = mouseclick()
REM text
ink rgb(255,196,255),0
center text 470, 10, "Biological cell simulation"
center text 470, 20, "FPS: " + str$(screen fps())
REM buttons
do_button_pause()
do_button_resume()
REM for testing
net_x_move = net_x_move + x_move_count
net_y_move = net_y_move + y_move_count
center text 470, 40, "Net x move: " + str$(net_x_move)
center text 470, 50, "Net y move: " + str$(net_y_move)
endfunction
function do_button_pause()
REM if click on button, pause sim
if mouseinregion(580, 440, 620, 460)
if mc = 1
pause_sim = 1
if oldmc = 0
step_sim = 1
endif
endif
endif
REM color of button depends on pause_sim variable
if pause_sim = 0
ink rgb(128,128,128),0
else
ink rgb(255,255,128),0
endif
if step_sim = 1 then ink rgb(64,255,64),0
REM display button
emptybox(580, 440, 620, 460)
center text 600, 442, "Step"
endfunction
function do_button_resume()
REM if click on button, unpause
if mouseinregion(530, 440, 570, 460)
if mc = 1
pause_sim = 0
endif
endif
REM color of button depends on pause_sim variable
if pause_sim = 1
ink rgb(128,128,128),0
else
ink rgb(255,255,128),0
endif
REM display button
emptybox(530, 440, 570, 460)
center text 550, 442, "Play"
endfunction
function show_molecule_counts()
for mol_id = 1 to max_mol
r = mol(mol_id).r
g = mol(mol_id).g
b = mol(mol_id).b
ink rgb(r,g,b),0
print mol(mol_id).name + ": " + str$(mol(mol_id).count)
next mol_id
endfunction
REM useful functions
function emptybox(xa,ya,xb,yb)
line xa,ya,xa,yb
line xa,yb,xb,yb
line xb,yb,xb,ya
line xb,ya,xa,ya
endfunction
function mouseinregion(xa,ya,xb,yb)
if mousex()>xa
if mousex()<xb
if mousey()>ya
if mousey()<yb
exitfunction 1
endif
endif
endif
endif
endfunction 0
REM INITIALIZE ENVIRONMENT
function place_random_molecules()
for x = 2 to 298
for y = 2 to 298
if rnd(100) = 0 then g(x,y) = id_glucose
if rnd(100) = 0 then g(x,y) = id_test_enzyme
next y
next x
endfunction
function place_cell_membrane()
for x = 25 to 275
y# = sqrt( 125.0 ^ 2.0 - ((x+0.0) - 150.0) ^ 2.0 ) + 150.0
y=y#
g(x,y) = 1
ng(x,y) = 1
y# = -sqrt( 125.0 ^ 2.0 - ((x+0.0) - 150.0) ^ 2.0 ) + 150.0
y=y#
g(x,y) = 1
ng(x,y) = 1
next x
for y = 25 to 275
x# = sqrt( 125.0 ^ 2.0 - ((y+0.0) - 150.0) ^ 2.0 ) + 150.0
x=x#
g(x,y) = 1
ng(x,y) = 1
x# = -sqrt( 125.0 ^ 2.0 - ((y+0.0) - 150.0) ^ 2.0 ) + 150.0
x=x#
g(x,y) = 1
ng(x,y) = 1
next y
endfunction
ini:
REM screen
set display mode 640,480,16
sync on
fastsync
REM game
randomize 999
REM types
type molecules
name as string
id
count
r
g
b
move as string
endtype
REM globals
global sync_frequency = 1
global x_move
global y_move
global mc = 0
global oldmc = 0
global pause_sim = 0
global step_sim = 0
global max_mol = 6
REM molecules
global id_phospholipid = 1
global id_glucose = 2
global id_test_enzyme = 3
global id_g3p = 4
global id_adp = 5
global id_atp = 6
REM arrays
dim g(301,301)
dim ng(301,301)
dim mol(max_mol) as molecules
REM molecules
inc mol_id `1
mol(mol_id).name = "Phospholipid"
mol(mol_id).id = mol_id
mol(mol_id).move = "none"
mol(mol_id).r = 196 : mol(mol_id).g = 128 : mol(mol_id).b = 0
inc mol_id `2
mol(mol_id).name = "Glucose"
mol(mol_id).id = mol_id
mol(mol_id).move = "float"
mol(mol_id).r = 64 : mol(mol_id).g = 255 : mol(mol_id).b = 64
inc mol_id `3
mol(mol_id).name = "Test enzyme (Glycolysis energonic summary)"
mol(mol_id).id = mol_id
mol(mol_id).move = "float"
mol(mol_id).r = 32 : mol(mol_id).g = 32 : mol(mol_id).b = 255
inc mol_id `4
mol(mol_id).name = "Glyceraldehyde Phosphate"
mol(mol_id).id = mol_id
mol(mol_id).move = "float"
mol(mol_id).r = 255 : mol(mol_id).g = 64 : mol(mol_id).b = 64
inc mol_id `5
mol(mol_id).name = "Adenosine Biphosphate"
mol(mol_id).id = mol_id
mol(mol_id).move = "float"
mol(mol_id).r = 128 : mol(mol_id).g = 128 : mol(mol_id).b = 64
inc mol_id `6
mol(mol_id).name = "Adenosine Triphosphate"
mol(mol_id).id = mol_id
mol(mol_id).move = "float"
mol(mol_id).r = 255 : mol(mol_id).g = 255 : mol(mol_id).b = 32
return
code is restructured, it's much easier to add molecules now
there is unfortunately a net movement upward for the particles. this means they collect at the top of the cell. i need to figure out a way to stop this
for those interesting in the science of it, read this:
i added two more molecules and now we have a complete summary of the endergonic half of glycolysis: the blue enzyme, when there is ATP to its left and above, and there is a glucose to its right, turns the glucose into two Glyceraldehyde phosphates, and turns both ATPs into ADPs
in order to see this, though, you have to wait a little bit for the ATP concentration to rise (no ATP starts out in this test program, there is an ATP fountain in the center where it spawns). once a bunch of ATP is in the cell, youll start seeing ATPs turn to ADPs and glucose turn to G3P. you wont see this outside the cell because the ATP wont cross the cell membrane, thus wont power the reaction outside the cell