136 lines
4.7 KiB
Text
136 lines
4.7 KiB
Text
out `Small ``Game\'\'\n'
|
|
use term
|
|
|
|
# Before we begin, a few notes
|
|
# - All objects are strings
|
|
# - There are a few different kinds of objects.
|
|
# - variables which have a static value they always evaluate to
|
|
# - lazies (contained by curlies (`{' and `}')) lazilly evaluate the lines
|
|
# within themselves only when nessicary. They may take arguments the same
|
|
# way commands do
|
|
# - commands, which are essentially lazies behind the mask of a variable name
|
|
# - strings, contained by a backtick to open (``') and a single quote to close
|
|
# (`\'').
|
|
# - Each line begins with any object
|
|
# - builtin commands are always 3 characters long
|
|
# - the starting object is followed by a space, then the arguments, which are
|
|
# space seperated objects
|
|
# - the arguments are passed to the first object
|
|
# - variables and strings ignore these arguments
|
|
# - commands and lazies may access these arguments with the `arg' command
|
|
# - interpolation, either within a variable name, command name, or string, is
|
|
# done with the `<...>' syntax.
|
|
# - The arrows, as they're called, evaluate the line inside them, then insert
|
|
# that value into the variable name/command name/string.
|
|
# - thus a lone `<varname>' on a line evaluates to the value of the variable
|
|
# that is named by varname.
|
|
# - To say that backwards, varname contains the name of a variable, and that
|
|
# variable has a value, and that value is what we're getting.
|
|
# - When a object begins with a bang (`!'), if object being evaluated sets any
|
|
# variables, it sets them within the current scope.
|
|
# - Variable and function names are stripped of bangs and spaces.
|
|
# - Booleans don't exist. Instead, any string that is empty (`') is truthy and
|
|
# all other (non-empty) strings are falsey.
|
|
# - Numbers are strings in the formats:
|
|
# - `[+\-]?real(\.dec)?[+\-]imag(\.dec)?i'
|
|
# - `[+\-]?real(\.dec)?'
|
|
# - `[+\-]?imag(\.dec)?i'
|
|
# - where, imag is the immaginary part, real is the real part, and the .dec is
|
|
# the decimal part of the one it appears to the right of.
|
|
# - These strings are in any base from 3 to 19.
|
|
# - bases 20+ are reserved since they would involve the letter i (which
|
|
# denotes the immaginary part)
|
|
# - the current base is defined by the 'base' variable, which is always in
|
|
# base 2.
|
|
# - base 2 is reserved for no good reason.
|
|
# - all bases lower than two are reserved because they're inconveinent to
|
|
# implement.
|
|
|
|
set `score' `0'
|
|
set `win.maxw' {
|
|
# ^ win.maxw is just the variable name. The dot is just a character.
|
|
# the dot doesn't mean anything special here.
|
|
|
|
# We doin RPN :O
|
|
sub `1' term:rows
|
|
# `term:rows' is the name a command being run.
|
|
# since variable names are quite permissive, this is just the name of a
|
|
# command defined within the file `term' (imported at the top)
|
|
}
|
|
set `win.maxh' {sub `1' term:cols}
|
|
|
|
set `guy.char' `\U0001FBC5'
|
|
set `guy.x' `1'
|
|
set `guy.y' `1'
|
|
|
|
# Unicode is supported inside quotes:
|
|
set `star.char' `⭐'
|
|
|
|
# `def' defines a command
|
|
def randstarpos {
|
|
set `star.x' {
|
|
# Get the real part of the rounded number after adding 1. (
|
|
# rounding removes decimal parts but leaves the immaginary
|
|
# part):
|
|
rea {rnd {add `1' {
|
|
mul win.maxw rnd
|
|
# ^ rnd returns a random number
|
|
# from 0 to 1
|
|
}}}
|
|
}
|
|
set `star.y' {rea {rnd
|
|
add `1' {mul rnd win.maxh}
|
|
}}
|
|
}
|
|
def w {set `guy.y' {rea {rnd {
|
|
max `1' {sub `1' guy.y}
|
|
}}}}
|
|
def a {set `guy.x' {rea {rnd {max `1' {sub `1' guy.x}}}}}
|
|
def s {set `guy.y' {rea {rnd {min win.maxh {add `1' guy.y}}}}}
|
|
def d {set `guy.x' {rea {rnd {min win.maxw {add `1' guy.x}}}}}
|
|
|
|
!randstarpos
|
|
inf !{
|
|
#^the infinite loop command.
|
|
#Note that the bang is nessicary as otherwise, the lazy would always
|
|
#inherit the same state.
|
|
out `\x1b[<rea {rnd guy.y}>;<rea {rnd guy.x}>H<guy.char>'
|
|
# ^writes to stdout
|
|
out `\x1b[<rea {rnd star.y}>;<rea {rnd star.x}>H<star.char>'
|
|
map inp \
|
|
`w' !w \
|
|
`k' !w \
|
|
`a' !a \
|
|
`j' !a \
|
|
`s' !s \
|
|
`h' !s \
|
|
`d' !d \
|
|
`l' !d \
|
|
defa {}
|
|
# ^map -- maps a value to a result
|
|
# The arguments alternate between
|
|
# things to match against and lazies
|
|
# to run as a result of those matches.
|
|
# The result is always a block that
|
|
# will be ccl'd if the match is found.
|
|
# The last thing to match against is
|
|
# always assumed to be the default.
|
|
# It is convention to make the last
|
|
# matching argument `defa'.
|
|
# `inp' gets a single char from stdin.
|
|
|
|
ifs {
|
|
eql `<guy.x>' `<star.x>'
|
|
# ^ eql will return `f' if they're
|
|
# not equal and `' if they're equal.
|
|
eql `<guy.y>' `<star.y>'
|
|
# Note that since output is combined, this block is effectively
|
|
# an and operator. The actual and operator is better tho. It
|
|
# provides short-circuting.
|
|
} then !{
|
|
!randstarpos
|
|
set score {add `1' score}
|
|
out `\x1b[2J\x1b[HScore: <rea {rnd score}>'
|
|
}
|
|
}
|
|
|