dyslexic
edit
qrcode
+=-

Assignment 00 - Individual - Lua Introduction (part 0)


Comments, Variables, Flow Control — Due: 2019.06.18 1:00PM

In this assignment, you will begin to learn how to code in PICO-8. PICO-8 uses Lua 5.2 as it's programming language, but there are a few differences (not covered in this course).

Useful


After running PICO-8, toggle between the console and the editors by pressing the ESC key.

You can execute commands immediately using the console.

You can run the code that is typed in the editor by typing run in the console or by pressing CTRL+R.

Requirements


  1. Read the following sections of the Learn PICO-8 Guide located in the Resources section below.
    • Section 0, Comments
    • Section 1, Variables and Flow Control
  2. Answer the Questions below.
    • You will not turn in your answers, but there might be a quiz over them.
  3. Solve the Problems addressed below.
    • Write all of you code in the PICO-8 code editor, not in the console.
  4. Save your solution as a PNG cartridge called a00_lua.p8.png.
    • IMPORTANT: Use save a00_lua.p8.png, not export a00_lua.png
    • The former creates a cartridge; the latter exports the sprite sheet.
  5. Submit your PNG cartridge to the course Canvas page.

Resources


The PICO-8 program below computes the factorial of a number. You may copy the source by pressing the COPY button in the top-right corner, and then paste it into your PICO-8 editor with CTRL+V.

-- defines a factorial function
function fact (n)
 if n == 0 then
  return 1
 else
  return n * fact(n - 1)
 end
end

-- print factorial of number 5
print("factorial(5) = "..fact(5))

Below is a modified version of the Learning Lua in 15 Minutes | Tyley Neylon. I have modified it to include the quirks of PICO-8's Lua implementation.

--[[

welcome to the learn pico-8 guide!

pico-8 is a fantasy console for making, sharing, and
playing tiny games and other computer programs.  when you
turn it on, the machine greets you with a shell for
typing in lua programs and provides simple built-in tools
for creating sprites, maps, and sounds

the harsh limitations of pico-8 are carefully chosen to be fun
to work with, encourage small but expressive designs and
hopefully to give pico-8 cartridges their own particular
look and feel.

keys
  alt+enter   toggle fullscreen
  alt+f4      quit
  ctrl+r      reload/run/restart cart
  ctrl+s      quick-save
  ctrl+m      mute / unmute
  arrows+zx   player 1 controls
  sdfe+tab,q  player 2 controls
  enter/p     pause game

specs
  display     128x128 pixels fixed 16 color pal
  input       6 btn controller
  cart size   32k
  sound       4 channel, 64 editable blerps
  code        lua (max 8192 tokens of code)
  sprites     single bank of 128 8x8 sprites (+128 shared)
  map         128x32 8b cels (+128x32 shared)

an important note:
  pico-8 uses portions of lua 5.2 under the hood.  so, if
  you know lua, you can easily learn pico-8.  however, there
  are a few differences that will make standard lua code
  not work in pico-8.  i will try to note these.

a less important note:
  pico-8 is a constrained fantasy console.  one of the
  constraints is that there is no case (no upper or lower
  case of a).  also, the editor can only show 32 characters.
  i have written this document to fit these constraints, so
  that you can copy-paste the document into the pico-8
  editor and run it.

--]]


------------------------------------------------------------
-- Section 0. comments
------------------------------------------------------------

-- two dashes start a one-line comment.

--[[
  adding two ['s and ]'s makes
  it a multi-line comment.
--]]


------------------------------------------------------------
-- Section 1. variables and flow control
------------------------------------------------------------

num = 42
-- all numbers are 32b fixed-point floats.  this
-- means that there are 16bits for storing the integer,
-- and 16bits for storing the decimal portion.  numbers
-- can store any value between -32768.0 and 32767.99999,
-- inclusive.  if you try to store numbers outside that
-- range, the value will wrap around (modulus).

s = 'walternate' -- immutable strings like python.
t = "double-quotes are fine"
u = [[ double brackets
       start and end
       multi-line strings.]]
t = nil  -- undefines t; lua has garbage collection.

-- blocks are denoted with keywords like do/end:
while num < 50 do
  -- the following two lines both increment num by 1
  num = num + 1
  num += 1
end

-- if clauses:
if num > 40 then
  print('over 40')
elseif s ~= 'walternate' then
  -- ~= is not equals. can use != instead.
  print('not over 40')
elseif s == "foo bar" then
  -- equality check is == like python; ok for strs.
else
  -- variables are global by default.
  thisisglobal = 5

  -- line (below) is a local variable.  local vars
  -- exist only within the chunk they are defined.
  local line = 'bar'

  -- string concatenation uses the .. operator:
  print('foo ' .. line)
end
-- line is no longer defined

-- undefined variables return nil. this is not an error:
foo = anunknownvariable
-- now, foo == nil.

aboolval = false

-- only nil and false are falsy; 0 and '' are true!
if not aboolval then
  print('twas false')
end

-- 'or' and 'and' are short-circuited.  this is similar
-- to the a?b:c operator in c/js:
ans = aboolval and 'y' or 'n'
-- now, ans == 'n'

karlsum = 0
for i = 1, 100 do
  -- range includes both ends.
  karlsum = karlsum + i
end

-- use "100, 1, -1" as the range to count down:
fredsum = 0
for j = 100, 1, -1 do
  fredsum = fredsum + j
end

-- in general, the range is begin, end[, step].

-- another loop construct:
repeat
  print('back to the future!')
  num = num - 1
until num == 0


------------------------------------------------------------
-- Section 2. functions
------------------------------------------------------------

function fib(n)
  if n < 2 then return 1 end
  return fib(n - 2) + fib(n - 1)
end

-- closures and anonymous functions are ok:
function adder(x)
  -- the returned function is created when adder is
  -- called, and remembers the value of x:
  return function (y)
    return x + y
  end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16))  --> 25
print(a2(64))  --> 100

-- returns, func calls, and assignments all work with
-- lists that may be mismatched in length. unmatched
-- receivers are nil; unmatched senders are discarded.

x, y, z = 1, 2, 3, 4
-- now x == 1, y == 2, z == 3, and 4 is thrown away.

function bar(a, b, c)
  print(a.."  "..b.."  "..c)
  return 4, 8, 15, 16, 23, 42
end

x, y = bar('zaphod')
-- prints "zaphod  nil nil" now x == 4, y == 8,
-- values 15..42 are discarded.

-- functions are first-class, may be local/global. these
-- are the same:
function f(x) return x * x end
f = function (x)
  return x * x
end

-- and so are these:
local function g(x)
  return sin(x)
end
local g; g = function (x)
  return sin(x)
end
-- the 'local g' decl makes g-self-references ok.

-- in pico-8, trig functions such as sin, cos, and atan2
-- work in [0,1] range, *not* in radians or degrees! also,
-- sin is inverted!  both of these points deviate from
-- lua and other standard languages.

-- calls with one string param don't need parens:
print 'hello'  -- works fine.


------------------------------------------------------------
-- Section 3. tables
------------------------------------------------------------

-- tables are lua's only compound data structure;
-- they are associative arrays. similar to php arrays or js
-- objects, they are hash-lookup dicts that can also
-- be used as lists.

-- using tables as dictionaries / maps:

-- dict literals have string keys by default:
t = {
  key1 = 'val1',
  key2 = false
}

-- string keys can use js-like dot notation:
print(t.key1)  -- prints 'val1'
t.newkey = {}  -- adds a new key/val pair
t.key2 = nil   -- removes key2 from the t

-- literal notation for any (non-nil) value as key:
u = {
  ['@!#'] = 'qbert',
  [{}] = 1729, -- new dict, object as key
  [6.28] = 'tau'
}
print(u[6.28])  -- prints "tau"

-- key matching is basically by value for numbers and
-- strings, but by identity for tables.
a = u['@!#']  -- now a = 'qbert'
b = u[{}]     -- we might expect
-- 1729, but it's nil: b = nil since the lookup fails. it
-- fails because the key we used is not the same object
-- as the one used to store the original value. so strings
-- and numbers are more portable keys.

-- a one-table-param function call needs no parens:
function h(x) print(x.key1) end
h{key1 = 'sonmi~451'}   -- prints 'sonmi~451'.

-- table iteration.
for key, val in pairs(u) do
  print(key.." "..val)
end

-- using tables as lists / arrays:

-- list literals implicitly set up int keys:
v = {
  'value1',
  'value2',
  1.21,
  'gigawatts'
}
for i = 1, #v do
  -- #v is the size of v for lists.
  print(v[i])
end
-- important: indices start at 1!! so crazy!
-- a 'list' is not a real type. v is just a table with
-- consecutive integer keys, treated as a list.


------------------------------------------------------------
-- Section 4. pico-8 functions
------------------------------------------------------------

--[[

pico-8 has many built-in fns defined for drawing, playing
sounds or music, or for manipulating memory.

also, there are a few special functions that you will define
to make your game work.

--]]

print('hello world')
rectfill(80,80,120,120,12)
circfill(70,90,20,14)
for i=1,4 do print(i) end

-- rectfill function draws a filled rectangle.  the
-- parameters are:
--   rectfill x0 y0 x1 y1 [col]
-- the col param is optional.

-- circfill draws a filled circle.  the parameters are:
--   circfill x y r [col]

-- technically, print has parameters that allow you to
-- print text anywhere on the screen.
--   print str [x y [col]]

-- color indices:
--    0 black         1 dark blue
--    2 dark purple   3 dark green
--    4 brown         5 dark gray
--    6 light gray    7 white
--    8 red           9 orange
--   10 yellow       11 green
--   12 blue         13 indigo
--   14 pink         15 peach

btn_0 = btn(0, 0)
print(btn_0)
-- btn function returns boolean indicating if a given button
-- for a given player is being pressed.
--   btn [i [p]]
-- i: [0,5]: left, right, up, down, button_o, button_x
-- p: [0,7]: player index
-- if no params are supplied, btn returns a bitfield of
-- all 12 button states for plr 0 & 1.

greatr = max(1, 3)
lesser = min(1, 3)
middle = mid(1, 5, 3)

floor   = flr(4.1)
ceiling = ceil(4.1)

-- other useful math functions
--   cos, sin, atan2 (remember, these work in [0,1] range!)
--   sqrt, abs, rnd, srand

-- convert str->num or val->str
anumber = tonum('2.7')
astring = tostr(2.7)
bstring = tostr(true)
cstring = tostr(nil)

-- finally, pico-8 calls fns with special names when the
-- cart is ran.

function _init()
  -- this function is called
  -- once at program startup.
  -- place all initialization
  -- code in here.
end

function _update()
  -- this function is called
  -- at 30fps while the
  -- program is running.
  -- place code to update the
  -- game's state in here.
end

function _draw()
  -- this function is called
  -- once per visible frame.
  -- place code to draw the
  -- game in here.
end



------------------------------------------------------------
-- Section 5. references
------------------------------------------------------------

--[[

this is a modification of the:

  learning lua in 15 minutes, by tyler neylon.
  http://tylerneylon.com/a/learn-lua/

i have modified it to include the quirks of pico-8's lua
implementation.

other great resources:

  https://www.lexaloffle.com/pico-8.php?page=manual
  http://pico-8.wikia.com/wiki/lua
  https://github.com/felipebueno/awesome-pico-8
  https://www.lexaloffle.com/bbs/?tid=28207
  https://neko250.github.io/pico8-api/

--]]

Questions


  1. What do each of the following mean in PICO-8?
    • --
    • --[[
    • --]]
  2. Which of the following strings are valid PICO-8 identifiers?
    • ___
    • _END
    • END
    • UNTIL?
    • NIL
    • NULL
    • ONE-STEP
  3. What does x += 1 do? What does y = y + 1 do?
  4. What are the different ways you can write a loop? How are they different?
  5. What is the difference between =, ==, ~=, and !=?
  6. How do you write a conditional (if)? What does elseif mean?
  7. When it comes to strings, what is the difference between a single quote (') and a double quote (")? For example, 'foo' and "foo".
  8. What does foo = nil do?

Problems


  1. Write working PICO-8 code that performs the following assigning, summing, concatenating, and printing

    • Assign your current age to variable called AGE
    • Assign 10 to a variable called PLUS
    • Print out MY AGE IS followed by the value store in AGE
      • Note: all of this text should be printed on a single line!
      • For example: MY AGE IS 59
    • Print out BUT IN xx YEARS, I WILL BE xx but use PLUS and the sum of PLUS and AGE where appropriate
      • Note: all of this text should be printed on a single line!
      • For example: BUT IN 10 YEARS, I WILL BE 69
    • Store your first (given) name to the variable FNAME
    • Store your last (family) name to the variable LNAME
    • Print out MY NAME IS followed by the values stored in FNAME and LNAME
  2. Write working PICO-8 code that performs the following iteration

    • Using a FOR loop, print out HELLO, WORLD exactly 10 times
    • Using a FOR loop, print out the sum of the values of numbers between 5 and 15, inclusively.
  3. Write working PICO-8 code that performs the following

    • Copy and paste the factorial function (Resources section above) into your PICO-8 source.
    • What happens if you call fact with a negative number? (ex: fact(-42))
    • Modify the example to avoid this problem by having the function return nil when the parameter is negative.
      • Note: fact(0) should still return 1, not nil!
    • Demonstrate you have done this correctly by printing out the result of fact(-42) and fact(5)

The output after completing each step above should look like the following screenshot (assuming you are Roberto Ierusalimschy, the creator of the Lua programming language).

Example output
Example output

Deliverable


Create a PNG cartridge for your solution called a00_lua.p8.png, and submit it to the course Canvas page.

Grading Rubric


3pts Variables are used correctly for age and name
3pts For-loops are correct
3pts Factorial function is correctly modified
3pts Submitted PNG cartridge