Log In  

Cart #gb_chain-0 | 2023-08-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
3

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)
P#132889 2023-08-09 01:55 ( Edited 2023-08-09 02:12)

Nice! It seems a little like you might be on your way to writing a Forth.

P#132892 2023-08-09 04:12

[Please log in to post a comment]