: length ( list -- u ) 0 swap begin dup while 1 under+ @ repeat drop ; : head ( list -- x ) cell+ @ ; : .list ( list -- ) begin dup while dup dup . head . 10 emit @ repeat dup . 10 emit drop ; : empty? ( list -- flag ) 0= ; : iterate ( xt list -- ) begin dup while dup 2 pick execute @ repeat 2drop ; \ (ptr, xt, x, y, damage) : ufo-x ( ufo-addr -- x ) 2 cells + @ ; : ufo-y ( ufo-addr -- y ) 3 cells + @ ; : ufo-damage ( ufo-addr -- dmg ) 4 cells + @ ; : set-ufo-x ( x ufo-addr -- ) 2 cells + ! ; : set-ufo-y ( y ufo-addr -- ) 3 cells + ! ; : set-ufo-damage ( dmg ufo-addr -- ) 4 cells + ! ; 0 value ufo_list : add-ufo ( y x xt -- ) 5 cells allocate throw dup ufo_list swap ! dup cell+ ( xt addr addr+ ) rot swap ! dup ( x addr addr ) rot swap set-ufo-x dup ( y addr addr ) rot swap set-ufo-y 0 over set-ufo-damage to ufo_list ; : remove-ufo ( index -- ) dup 0 = if drop ufo_list dup @ to ufo_list free throw else ufo_list swap 1 - 0 u+do @ loop ( prev_el ) dup @ ( el_1 el_2 ) dup @ ( el_1 el_2 el_3 ) swap free throw swap ! then ; : iterate-ufo ( xt -- ) ufo_list iterate ; : ufo-position ( block -- x y ) dup ufo-x swap ufo-y ; : clear-ufos ( -- ) recursive ufo_list 0= invert if 0 remove-ufo clear-ufos then ; \ -------------------------------------------------- : shot-x 1 cells + @ ; : shot-y 2 cells + @ ; : set-shot-x 1 cells + ! ; : set-shot-y 2 cells + ! ; 0 value shot_list : add-shot ( y x -- ) 3 cells allocate throw dup shot_list swap ! dup ( x addr addr ) rot swap set-shot-x dup ( y addr addr ) rot swap set-shot-y to shot_list ; : remove-shot ( index -- ) dup 0 = if drop shot_list dup @ to shot_list free throw else shot_list swap 1 - 0 u+do @ loop ( prev_el ) dup @ ( el_1 el_2 ) dup @ ( el_1 el_2 el_3 ) swap free throw swap ! then ; : iterate-shot ( xt -- ) shot_list iterate ; : clear-shots ( -- ) recursive shot_list 0= invert if 0 remove-shot clear-shots then ; \ ------------------------------------- : block-x 1 cells + @ ; : block-y 2 cells + @ ; : block-health 3 cells + @ ; : set-block-x 1 cells + ! ; : set-block-y 2 cells + ! ; : set-block-health 3 cells + ! ; 0 value block_list : add-block ( y x health -- ) 4 cells allocate throw dup block_list swap ! dup ( health addr addr ) rot swap set-block-health dup ( x addr addr ) rot swap set-block-x dup ( y addr addr ) rot swap set-block-y to block_list ; : remove-block ( index -- ) dup 0 = if drop block_list dup @ to block_list free throw else block_list swap 1 - 0 u+do @ loop ( prev_el ) dup @ ( el_1 el_2 ) dup @ ( el_1 el_2 el_3 ) swap free throw swap ! then ; : iterate-blocks ( xt -- ) block_list iterate ; : block-position ( block -- x y ) dup block-x swap block-y ; : clear-blocks ( -- ) recursive block_list 0= invert if 0 remove-block clear-blocks then ;