reinsert linked list impl, skeleton for game impl

lots of undefined vars!
This commit is contained in:
Kistaro Windrider 2024-02-03 11:12:36 -08:00
parent 368eeb2fb4
commit 150e1385ad
Signed by: kistaro
SSH Key Fingerprint: SHA256:TBE2ynfmJqsAf0CP6gsflA0q5X5wD5fVKWPsZ7eVUg8

View File

@ -65,6 +65,78 @@ function mknew(tt, more)
end
end
-- intrusive singly-linked list.
-- cannot be nested!
linked_list = {is_linked_list=true}
mknew(linked_list, function(x)
x.next=nil
x.tail=x
end)
function linked_list:push_back(x)
self.tail.next = x
self.tail = x
end
function linked_list:push_front(x)
if (not self.next) self.tail = x
x.next = self.next
self.next = x
end
-- vore eats another linked list
-- by appending its contents.
-- the ingested linked is empty.
function linked_list:vore(x)
if (not x.next) return
self.tail.next = x.next
self.tail = x.tail
x.next = nil
x.tail = x
end
-- strip calls f(x) for each
-- node, removing each node for
-- which f(x) returns true. it
-- returns the new tail; nil
-- if the list is now empty.
function linked_list:strip(f)
local p, n = self, self.next
while n do
if f(n) then
p.next = n.next
else
p = n
end
n = n.next
end
self.tail = p
return p
end
-- optimized special case -
-- could be done with strip but
-- this avoids extra function
-- calls and comparisions since
-- draw isn't allowed to kill
-- the item
function linked_list:draw()
local n = self.next
while n do
n:draw()
n = n.next
end
end
function linked_list:pop_front()
local ret = self.next
if (not ret) return
self.next = ret.next
if (not ret.next) ret.tail = nil
return ret
end
-- if t[mname] is a thing,
-- invoke it as a method. else,
-- try each object in t
@ -80,6 +152,51 @@ function outer_or_each_opt(t, mname)
end)
end
-- puke emits a verbose string
-- describing item, indented to
-- the specified depth (0 by
-- default). used for table
-- debugging. table-type keys
-- are not legible here
function puke(item, indent, seen, hidekey)
if (type(item) ~= "table") return tostr(item)
seen = seen or {}
if (seen[item]) return "<<...>>"
seen[item] = true
indent = indent or 0
local pfx = "\n"
for _=1,indent do
pfx ..= " "
end
local xpfx = pfx.." "
if item.is_linked_list then
local ret,n = "linked_list <",0
item:strip(function(x)
n += 1
ret ..= xpfx..tostr(n)..": "..puke(x, indent+2, seen, "next")
end)
return ret..pfx..">"
end
local ret = "{"
for k, v in pairs(item) do
if (k ~= hidekey) ret ..= xpfx..tostr(k)..": "..puke(v, indent+2, seen)
end
return ret..pfx.."}"
end
-- convenience for debugging
function puketh(item, ...)
printh(puke(item), ...)
end
function pukeboard(item)
puketh(item, "@clip")
end
-------------------------------
-- view
-------------------------------
@ -285,7 +402,6 @@ function newtitle()
{
update=function()
box.go = btn(4)
-- if (box:done()) mainview.views[2].c=2
end
},
bg.new{c=1},
@ -300,4 +416,64 @@ end
-- awakener
-->8
-- game mode
-- arcade mode
arcade_level = {
score=0,
maxscore=15,
}
mknew(arcade_level, function(x)
x.p = toyphin.new()
x.waves = waves.new()
x.words = linked_list.new()
x.fx = linked_list.new()
end)
-- dolphin sprite states:
-- spr args
-- draw pal
-- hitbox size
-- todo: figure out a practical
-- way to pick a state, given
-- x and dy. make sure it
-- stabilizes appropriately
-- around splash/surface
-- even though the animation
-- is supposed to bounce here
phinstate_nrm = {}
phinstate_jump_full = {}
phinstate_jump_wane = {}
phinstate_crest = {}
phinstate_fall_wax = {}
phinstate_fall_full = {}
phinstate_splash = {}
phinstate_dive_full = {}
phinstate_dive_wane = {}
phinstate_turn = {}
phinstate_rise_wax = {}
phinstate_rise_full = {}
phinstate_surface = {}
toyphin = {
x=3,
y=56,
state=phinstate_nrm,
}
mknew(toyphin)
-->8
-- game sequencer