I enjoy the idea of lists. I really like how through code we can create pointers to pointers (or in PICO-8's case, reference to reference). I like experimenting with different simple structures in code and seeing how I can produce different kinds of little graphical effects with them.
This is similar to my Procedural Fire cart, as well as its sister cart, the Cool Sonar Effect. These two carts humor the idea of a command queue, where each entry in the queue is a function which should be called.
Anyway, this cart utilizes singly-linked lists to store string data. There are a few commands which were produced to create a tiny linked-list API. The functions are as follows:
-- link node -- d: data -- n: next node (if necessary) function link(d,n) local l={ data=d, next=n } return l end -- loop through all nodes -- in the chain and call f(d) -- on the data inside. function loop(l,f) while l!=nil do f(l) l=l.next end end -- count the size of the list -- starting with link l -- (this will hang forever -- if the list is circular) function count(l) if (l==nil) return 0 local c=0 while l do c+=1 l=l.next end return c end -- get the data for the list. -- if data is provided, also set -- the data before returning function data(l,d) if d then l.data=d end return l.data end -- get the next link for the -- list. if the next link is -- provided set the next link -- before returning function next(l,n) if n then l.next=n end return l.next end |
The example code of the cart is:
------------------------------ -- example -- clear to dark blue cls(0) -- sample text to use sss="hello world !! " -- starting node (nil) xxx=nil -- tile x and y tx,ty=0,0 -- flip flag fp=false -- create a new list with -- each node containing a -- character of the sample -- string. we do this backwards. for i=#sss,1,-1 do xxx=link(sub(sss,i,i),xxx) end loop(xxx,function(l) ?l.data,tx*4,ty*8,rnd()>0.5 and 15 or 2 if next(l)==nil then next(l,xxx) end tx+=1 if (tx>=32) tx=0 ty+=1 if (ty>=16) ty=0 if btn(❎) or btn(🅾️) then fp=not fp end if (fp==true) then flip() end end) |
Notice how in the example code, the characters in the string are added backwards. This is similar to stacking paper, or any kind of stack, really. We have access to only the top item in the stack, and if we want to read it from first to last, we have to add the items in backwards. The link
command asks for a reference to the previous link, and returns itself. When used like xxx=link(sub(sss,i,i),xxx)
we are storing the most recent link in xxx
.
Singly-linked lists (stacks) are not quite as flexible as doubly-linked lists. We cannot read backwards from a stack. Once the topmost item has been removed, we don't have any way to reference it. But, sometimes you don't need that ability. In this example, there isn't even a container object keeping track of things.
One of the more interesting commands of this set is loop()
. It asks for the first link, and also a function which will work on each link, starting with the one provided. This can allow you to iterate through each link and do whatever you'd like with its data!
for i=1,10 do ls=link(10-i,ls) end loop(ls,function(l) -- prints 9 to 0 on each line ?data(ls) end) |
You can even do things like neat mathematical models like the Fibonacci sequence
-- if we go over 23 there -- will be overflow for i=1,23 do -- fill stack with 23 0's lis=link(0,lis) end -- fill the sequence loop(lis,function(l) if data(l)==0 then data(l,1) data(next(l),1) data(next(next(l)),2) else if next(l) and next(next(l)) then data(next(next(l)), data(l)+data(next(l))) end end end) -- read the sequence loop(lis,function(l) ?data(l) end) |
[Please log in to post a comment]