commit 50eb33a7f2c4a627468ae6ac86e43f1858caf43a Author: Matt Nish-Lapidus Date: Tue Jun 11 17:37:04 2024 -0400 adding initial scripts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..ab62b59 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Ludus Scripts + +For now this is a place to put our collective Ludus sketches and scripts. Some sort of structure or organization might emerge... diff --git a/annoying_box.ld b/annoying_box.ld new file mode 100644 index 0000000..f3f3994 --- /dev/null +++ b/annoying_box.ld @@ -0,0 +1,15 @@ +& Lesson 2: Repeating things, labouriously + +& Let's draw a box! +& How do we start? + +forward! (100) + +& We move forward. +& Now we turn right: + +right! (100) + +& How many more times should we do that? +& How many total times do we do that? +& Finish the code to finish drawing the box. diff --git a/arguments.ld b/arguments.ld new file mode 100644 index 0000000..a59186d --- /dev/null +++ b/arguments.ld @@ -0,0 +1,39 @@ +& Lesson 5: Passing arguments + +& Recall our last function: +& fn box! () -> repeat 4 { fd! (100); rt! (0.25) } + +& This function can only draw a box with a side of `100` + +& To make our function more flexible, we can add an argument: + +fn box! (size) -> repeat 4 { +& ^^^^ This is our size parameter + fd! (size) +& ^^^^ Which we use here: the parameter is a name. +& This name only lasts as long as our function. + rt! (0.25) +} + +& How do you call out new `box!` function? + + + + + + + + +& A note: +& * a *parameter* is the name for a thing we _don't yet know the value of_ +& * an *argument* is the name for a parameter _when it is given a concrete value_ + +& fn box! (size) ... +& ^^^^ This is a parameter: in the function definition +& box! (50) +& ^^ This is an argument: in the function call + +& It's a subtle difference, and not especially important +& Plenty of programmers use these words interchangeably +& I just wanted to alert you to these words, their difference, their use. +& In all Ludus documentation, we'll be using them correctly. diff --git a/cngon.ld b/cngon.ld new file mode 100644 index 0000000..0cdd158 --- /dev/null +++ b/cngon.ld @@ -0,0 +1,41 @@ +& Lesson 12: c_ngon +& Clayson walks you through this step by step +& It's just high school trigonometry +& But that probably strikes terror into the hearts of PhD students in the humanities +& So I've adapted his solution. +& He walks you carefully through it on pp. 24-31. + +fn ngon! (sides, size) -> repeat sides { + fd! (size) + rt! (inv (sides)) +} + +fn c_ngon! (sides, radius) -> { + & first, some fancy trigonometry + & don't read this if you don't want to + & but: there are two hard problems here + & how far to turn before drawing the ngon + & and how long each side should be to fit inside the radius + let entry_turn = sub ( + 0.5 + mult ( + 0.25 + sub (sides, 2) + inv (sides))) + + let side_length = mult ( + 2 + radius + sin (div (0.5, sides))) + + & now that we have the math: what do we need the turtle to do + pu! () + fd! (radius) + pd! () + rt! (entry_turn) + ngon! (sides, side_length) + lt! (entry_turn) + pu! () + bk! (radius) + pd! () +} diff --git a/demo_1.ld b/demo_1.ld new file mode 100644 index 0000000..18e4d12 --- /dev/null +++ b/demo_1.ld @@ -0,0 +1,19 @@ +& Lesson 6: A first demo + +& Source: _Visual Modeling with Logo_, 14. + +fn box! (size) -> repeat 4 { fd! (size); rt! (0.25) } + +fn demo! () -> repeat 4 { + box! (100) + box! (98) + box! (96) + box! (75) + box! (40) + box! (35) + box! (30) + rt! (0.25) +} + +& How can you make this box more interesting? +& Consider `pc!` and `pw!` diff --git a/drawing.ld b/drawing.ld new file mode 100644 index 0000000..6a30e12 --- /dev/null +++ b/drawing.ld @@ -0,0 +1,37 @@ +& Lesson 1: The World of the Turtle +& Ludus is a Logo: it leads with turtle graphics +& There are two panes on the right: +& * the turtle +& * the console + +& You saw the console in Lesson 0: Hello World! + +& `print!`ing things is very useful; remember you can do that. + +& Now, we're going to give the turtle some functions. + +forward! (100) + +& let's dissect that + +& forward! (100) +& ^^^^^^^^ `forward!` is is the name of the function +& ^^^^ `100` is how far the turtle should walk +& (...) notice that we have to put 100 in parens + +& Uncomment the line below, and re-run the script: +& right! (0.25) + +& right! (0.25) +& ^^^^^^ `right!` is the name of this function +& ^^^^ 0.25 is how far the turtle should turn +& (....) notice again, we put the amount in parens +& What is the unit of 0.25? + +& Try out some other turtle functions. Here are a few: +& `left!`, `back!`, `penup!`, `pendown!`, `pencolor!`, `penwidth!` +& `home!` + +& Note they all end with `!`. What happens if you forget the bang? +& There are abbreviations: `fd!`, `rt!`, `lt!`, `bk!`, etc. +& The turtle graphics functions (and abbreviations!) are listed at https://alea.ludus.dev/twc/ludus/src/branch/main/prelude.md#turtle-graphics diff --git a/eliza.ld b/eliza.ld new file mode 100644 index 0000000..de5ea6b --- /dev/null +++ b/eliza.ld @@ -0,0 +1,279 @@ +let input = *input* + +print! (">>> ", input) + +let sanitized = do input > trim > downcase + +& ensuring we have spaces at the beginning and end +& this lets us match patterns as written below +let padded = " {sanitized} " + +fn switch_persons { + ("i") -> "you" + ("you") -> "i" + ("am") -> "are" + ("me") -> "you" + ("my") -> "your" + (x) -> x +} + +fn repersonalize (x) -> do x > + trim > + split (_, " ") > + map (switch_persons, _) > + join (_, " ") + +fn one_of { + (str as :string) -> str + (strs as :list) -> random (strs) +} + +let output = match padded with { + "{x} hello {y}" -> "How do you do. Please state your problem" + "{x} hi {y}" -> "How do you do. Please state your problem" + "{x} computer {y}" -> [ + "Do computers worry you" + "What do you think about machines" + "Why do you mention computers" + "What do you think machines have to do with your problem" + ] + "{x} name {y}" -> "I am not interested in names" + "{x} sorry {y}" -> [ + "Please don't apologize" + "Apologies are not necessary" + "What feelings do you have when you apologize" + ] + "{x} i remember {y}" -> { + let switched = repersonalize (y) + [ + "Do you often think of {switched}" + "Does thinking of {switched} bring anything else to mind" + "What else do you remember" + "Why do you recall {switched} right now" + "What in the present situation reminds you of {switched}" + "What is the connection between me and {switched}" + ] + } + "{x} do you remember {y}" -> { + let switched = repersonalize (y) + [ + "Did you think I would forget {switched}" + "Why do you think I should recall {switched} now" + "What about {switched}" + "You mentioned {switched}" + ] + } + "{x} if {y}" -> { + let switched = repersonalize (y) + [ + "Do you reall think that its likely that {switched}" + "Do you wish that {switched}" + "What do you think about {switched}" + "Really--if {switched}" + ] + } + "{x} i dreamt {y}" -> { + let switched = repersonalize (y) + [ + "Really--{switched}" + "Have you ever fantasized {switched} while you were awake" + "Have you dreamt {switched} before" + ] + } + "{x} dream about {y}" -> { + let switched = repersonalize (y) + "How do you feel about {switched} in reality" + } + "{x} dream {y}" -> [ + "What does this dream suggest to you" + "Do you dream often" + "What persons appear in your dreams" + "Don't you believe that dream has to do with your problem" + ] + "{x} my mother {y}" -> { + let switched = repersonalize (y) + [ + "Who else in your family {switched}" + "Tell me more about your family" + ] + } + "{x} my father {y}" -> [ + "Your father" + "Does he influence you strongly" + "What else comes to mind when you think of your father" + ] + "{x} i want {y}" -> { + let switched = repersonalize (y) + [ + "What would it mean if you got {switched}" + "Why do you want {switched}" + "Suppose you got {switched} soon" + ] + } + "{x} i am glad {y}" -> { + let switched = repersonalize (y) + [ + "How have I helped you to be {switched}" + "What makes you happy just now" + "Can you explain why you are suddenly {switched}" + ] + } + "{x} i am sad {y}" -> [ + "I am sorry to hear you are depressed" + "I'm sure it's not pleasant to be sad" + ] + "{x} are like {y}" -> { + let switched_x = repersonalize (x) + let switched_y = repersonalize (y) + "What resemblance to you see between {switched_x} and {switched_y}" + } + "{x} is like {y}" -> { + let switched_x = repersonalize (x) + let switched_y = repersonalize (y) + [ + "In what way is it that {switched_x} is like {switched_y}" + "What resemblance do you see" + "Could there really be some connection" + "How" + ] + } + "{x} alike {y}" -> [ + "In what way" + "What similarities are there" + ] + "{x} same {y}" -> "What other connections do you see" + "{x} i was {y}" -> { + let switched = repersonalize (y) + [ + "Were you really" + "Perhaps I already knew you were {switched}" + "Why do you tell me you were {switched} now" + ] + } + "{x} was i {y}" -> { + let switched = repersonalize (y) + [ + "What if you were {switched}" + "Do you think you were {switched}" + "What wouuld it mean if you were {switched}" + ] + } + "{x} i am {y}" -> { + let switched = repersonalize (y) + [ + "In what way are you {switched}" + "Do you want to be {switched}" + ] + } + "{x} am i {y}" -> { + let switched = repersonalize (y) + [ + "Do you believe you are {switched}" + "Would you want to be {switched}" + "You wish I would tell you you are {switched}" + "What would it mean if you were {switched}" + ] + } + "{x} am {y}" -> [ + "Why do you say *AM*" + "I don't understand that" + ] + "{x} are you {y}" -> { + let switched = repersonalize (y) + [ + "Why are you interested in whether I am {switched} or not" + "Would you prefer if I weren't {switched}" + "Perhaps I am {switched} in your fantasies" + ] + } + "{x} you are {y}" -> { + let switched = repersonalize (y) + "What makes you think I am {y}" + } + "{x} because {y}" -> [ + "Is that the real reason" + "What other reasons might there be" + "Does that reason seem to explain anything else" + ] + "{x} were you {y}" -> { + let switched = repersonalize (y) + [ + "Perhaps I was {switched}" + "What od you think" + "What if I had been {switched}" + ] + } + "{x} i can't {y}" -> { + let switched = repersonalize (y) + [ + "Maybe you could {switched} now" + "What if you could {switched}" + ] + } + "{x} i feel {y}" -> { + let switched = repersonalize (y) + "Do you often feel {switched}" + } + "{x} i felt {y}" -> "What other feelings do you have" + "{x} i {y} you {z}" -> { + let switched = repersonalize (y) + "Perhaps in your fantasy we {switched} each other" + } + "{x} why don't you {y}" -> { + let switched = repersonalize (y) + [ + "Should you {switched} yourself" + "Do you believe I don't {switched}" + "Perhaps I will {switched} in good time" + ] + } + "{x} yes {y}" -> [ + "You seem quite positive" + "You are sure" + "I understand" + ] + "{x} no {y}" -> [ + "Why not" + "You are being a bit negative" + "Are you saying *NO* just to be negative" + ] + "{x} someone {y}" -> "Can you be more specific" + "{x} everyone {y}" -> [ + "Surely not everyone" + "Can you think of anyone in particular" + "Who for example" + "You are thinking of a special person" + ] + "{x} always {y}" -> [ + "Can you think of a specific example" + "When" + "What incident are you thinking of" + "Really--always" + ] + "{x} what {y}" -> [ + "Why do you ask" + "Does that question interest you" + "What is it you really want to know" + "What do you think" + "What comes to your mind when you ask that" + ] + "{x} perhaps {y}" -> "You do not seem quite certain" + "{x} are {y}" -> { + let switched = repersonalize (y) + [ + "Did you think they might not be {switched}" + "Possibly they are {switched}" + ] + } + _ -> [ + "Very interesting" + "I am not sure I understand you fully" + "What does that suggest to you" + "Please continue" + "Go on" + "Do you feel strongly about discussing such things" + ] +} + +print! ("~> ", do output > one_of > upcase) + diff --git a/functions.ld b/functions.ld new file mode 100644 index 0000000..89c1350 --- /dev/null +++ b/functions.ld @@ -0,0 +1,24 @@ +& Lesson 4: Making functions and naming them + +& It's tedious to type out the whole `repeat 4 {...}` scene. +& Let's give this set of commands a name: + +fn box! () -> repeat 4 { + forward! (100) + right! (0.25) +} + +& fn box! () -> repeat 4 { +& fn `fn` is a special form +& It creates a function. +& box! `box!` is the name of our new function +& Note that it ends with `!`: by convention, +& all commands end with a "bang" like this. +& () `box!` doesn't take arguments. +& This represents an empty list of args. +& -> This arrow is basically punctuation. +& repeat 4 { We already know what this is. + +& Run this code. What happens? + +& If you want to actually draw a box, what does that look like? diff --git a/ifs.ld b/ifs.ld new file mode 100644 index 0000000..e0d5d20 --- /dev/null +++ b/ifs.ld @@ -0,0 +1,38 @@ +& Lesson 9: Flipping coins + +& Let's try a different version of this random walk. Instead of going an arbitrary amount forward, and an arbitrary amount left or right, let's turn left OR right, let's go forward OR backwards by a fixed amount. +& We need coin flips! + +let coin = [true, false] & these are booleans: equivalent to heads and tails +& ^^^^^^^^^^^^^ this is a list with two members +& Lists are like parameters or arguments, but with square brackets + +fn flip_coin () -> random (coin) +& ^^^^^^ `random` will pick a random element of a collection +& ^^^^ `coin` is a collection of two elements + +let times = random (10, 30) & we'll do this a random number of times + +repeat times { + pc! (random (colors)) +& `if` is our first conditional form + if flip_coin () +& ^^ the expression starts with `if` +& ^^^^^^^^^^^^ this is our *condition* +& if the condition is true, run the `then` branch +& if it is false, run the `else` branch +& in this case, our condition is the coin flip + then rt! (0.25) +& ^^^^ `then` gives us the branch to evaluate if true +& ^^^^^^^^^^ in this case, turn right 0.25 turns + else lt! (0.25) +& ^^^^ `else` gives us the branch to evaluate if false +& NB: Ludus requires you have a false branch +& ^^^^^^^^^^ in this case, turn left 0.25 turns +& This whole expression is: +& turn right 50% of the time, turn left 50% of the time + +& we don't need newlines before `then` and `else` +& but you can include them! + if flip_coin () then fd! (5) else bk! (5) +} diff --git a/koch.ld b/koch.ld new file mode 100644 index 0000000..5c1b3f8 --- /dev/null +++ b/koch.ld @@ -0,0 +1,20 @@ +& koch curve + +let length = 10 + +fn koch! { + (0) -> fd! (length) + (n) -> { + koch! (dec (n)) + lt! (0.25) + koch! (dec (n)) + rt! (0.25) + koch! (dec (n)) + rt! (0.25) + koch! (dec (n)) + lt! (0.25) + koch! (dec (n)) + } +} + +& koch! (3) diff --git a/lezertest.ld b/lezertest.ld new file mode 100644 index 0000000..cb99111 --- /dev/null +++ b/lezertest.ld @@ -0,0 +1,13 @@ +print! ("Hello, world!") + +fn box! (size) -> repeat 4 { + forward! (size) + right! (0.25) +} + +:symbol + +& This is a comment +& More comment + +Not comment or anything else diff --git a/ngon.ld b/ngon.ld new file mode 100644 index 0000000..d648aeb --- /dev/null +++ b/ngon.ld @@ -0,0 +1,33 @@ +& Lesson 10: ngons + +& Recall our first function: +fn simple_box! () -> { fd! (100); rt! (0.25) } + +& Recall our second function: +fn box! (size) -> { fd! (size); rt! (0.25) } + +& What haven't we "parameterized" yet? + + + + + + + + + + + + + +fn ngon! (n, size) -> repeat n { fd! (size); rt! (div (1, n)) } +& ^ ^^^^^^^^^^ +& Note n: what does this represent? +& What does `div (1, n)` mean here? +& Why is it here? +& Note: we could also have used `inv (n)`--inverse is 1/x +& What other math can we do? +& cf. https://alea.ludus.dev/twc/ludus/src/branch/main/prelude.md#math +& What happens when you pass in strange values? 0? 1? 2? +& Note `div` does not end in a bang. +& This differentiates between functions with side effects vs. return values. diff --git a/random.ld b/random.ld new file mode 100644 index 0000000..8b3ca6d --- /dev/null +++ b/random.ld @@ -0,0 +1,44 @@ +& Lesson 8: A random lesson. + +& So far, everything we've done is deterministic. +& Let's let the computer make some decisions. + +& We're going to introduce a few things here: +& * colors +& * random +& * dicts + +& our friend box! +fn box! (size) -> repeat 4 { fd! (size); rt! (0.25) } + +doc! (pencolor!) +print! ("These are Ludus's built-in colors: ", colors) + +pencolor! (colors :maroon) +& ^^^^^^ This is a dict. +& ^^^^^^^ This is a keyword. +& We use to get values out of dicts. +& Dict is short for "dictionary." +& pencolor! is also pc! + +& Drawing some colourful boxes: +box! (100) +rt! (0.25) +pc! (colors :purple) +box! (100) +rt! (0.25) +pc! (colors :olive) +box! (100) +rt! (0.25) +pc! (colors :teal) +box! (100) + +& We can also get a random colour using a handy-dandy function: random +repeat 4 { + pc! (random (color)) + box! (75) + rt! (0.25) +} + +& And we can also set the background to a random colour: +background! (random (color)) diff --git a/recursion.ld b/recursion.ld new file mode 100644 index 0000000..ad8cc89 --- /dev/null +++ b/recursion.ld @@ -0,0 +1,38 @@ +& Lesson 11: `spingons` and recursion + +& Here's our friend, the ngon +fn ngon! (n, size) -> repeat n { fd! (size); rt! (div (1, n)) } + +& Here we're introducing one of the more important, and """difficult""" concepts in computer science, recursion + +& Let's read this line-by-line +fn spin_gon! (n, size, angle, growth, times) -> if lte? (times, 0) + then :ok & this is the base case: what to do when we're done + & in this case, `:ok`--just a little signal all went well + else { + ngon! (n, size) & make an ngon + rt! (angle) & turn right + spin_gon! (n, mult (size, growth), angle, growth, sub (times, 1)) +& ^^^^^^^^^ This is the recursive call +& `spin_gon!` calls itself!--make another spin_gon +& What does this change between invocations? +& * `mult (size, growth)` +& * `sub (times, 1)` (or we could use `dec (times)`) +& What would happen if we *didn't* make these changes? + } +} + +& Play with `spin_gon!`: see what you can come up with. +& Also: see if you can't read what each call does. +& It's okay if you can't: 5 parameters is a lot. +& Clayson's examples: + +& Example 1, p. 21 +& spin_gon! (30, 2, 0.03, 1.02, 95) + +& Example 2, p. 21 +& repeat 3 { +& spin_gon! (4, 120, 0, 0.95, 50) +& rt! (0.25) +& } +& spin_gon! (4, 120, 0, 0.95, 19) diff --git a/repeat.ld b/repeat.ld new file mode 100644 index 0000000..e48650a --- /dev/null +++ b/repeat.ld @@ -0,0 +1,32 @@ +& Lesson 3: Repeating things, simply + +& Computers are good at repeating things: + +repeat 4 { + forward! (100) + right! (0.25) +} + +& let's take this line by line +& 5: repeat 4 { +& ^^^^^^ `repeat` is NOT a function, but a "special form" +& ^ this tells Ludus how many times to repeat a thing +& ^ this "curly brace" lets you group lines of code together +& we call this group a "block" + +& 6: forward! (100) +& ^^ as a matter of style, we indent lines in a block +& ^^^^^^^^ we recognize this + +& 7: right! (0.25) +& we recognize this, too +& but it has to be on its own line! +& (we could use a `;` instead of a newline) + +& 8: } +& ^ We need to close the block we opened on line 5 +& What happens if we forget it? + +& What happens if you change the number of times it repeats? +& -- the distance the turtle goes forward? +& -- the amount we turn right? diff --git a/sierp.ld b/sierp.ld new file mode 100644 index 0000000..a6053fe --- /dev/null +++ b/sierp.ld @@ -0,0 +1,54 @@ +& Example Ludus implementation of the Sierpinski triangle. +& https://en.m.wikipedia.org/wiki/L-system#Example_5:_Sierpinski_triangle + +& The Sierpinski triangle drawn using an L-system +& variables : F G +& constants : + − +& start : F−G−G +& rules : (F → F−G+F+G−F), (G → GG) +& angle : 120° + +& set a length for each segment +let length = 10 + +& set an angle for all turns, default to 1/3 for triangles +let angle = inv(1) + +& define 'G' function from the grammaer +fn g! { + (0) -> fd!(length) + (n) -> { + g!(dec(n)) + g!(dec(n)) + } +} + +& define 'F' function from the grammaer +fn f! { + (0) -> fd!(length) + (n) -> { + f!(dec(n)) + rt!(angle) + g!(dec(n)) + lt!(angle) + f!(dec(n)) + lt!(angle) + g!(dec(n)) + rt!(angle) + f!(dec(n)) + } +} + +& this function defines the starting pattern. +& each of the f! and g! calls expand based on the grammar at the top of this example +fn sierp! (times) -> { + f!(times) + rt!(angle) + g!(times) + rt!(angle) + g!(times) +} + +& call the base function with a number of iterations +& remember, this is exponential! high numbers can freeze your browser. +sierp!(7) diff --git a/spiralgon.ld b/spiralgon.ld new file mode 100644 index 0000000..02d44d5 --- /dev/null +++ b/spiralgon.ld @@ -0,0 +1,46 @@ +let gons = 10 +let sides = 4 +let size = 50 + +fn randcolor () -> (random(0,255), random(0,255), random(0,255)) + +fn ngon! (sides, size) -> { + repeat sides { + fd! (size) + rt! (inv(sides)) + } + :gon! +} + +fn spiralgon_recursive! (num, sides, size) -> { + pencolor!(randcolor()) + ngon! (sides, size) + + if gt? (num, 0) then { + rt!(inv(gons)) + spiralgonr!(dec (num), sides, add(10,size)) + } else { + :tired! + } +} + +& Non recursive version using loop for reference/example +& fn spiralgon! (num, sides) -> { +& loop (15, 0) with (size, times) -> { +& if lt? (times, num) then { +& pencolor!(randcolor()) +& ngon! (sides, size) +& rt! (0.2) +& if gt? (times, div (num, 2)) then { +& fd! (20) +& } else { +& back! (200) +& } +& recur (add (size, 1), inc (times)) +& } else :dizzy +& } +& } + + + +spiralgon_recursive!(gons, sides, size) diff --git a/start.ld b/start.ld new file mode 100644 index 0000000..adafaa3 --- /dev/null +++ b/start.ld @@ -0,0 +1,29 @@ +& Welcome to Ludus! +& To run the code in this window, hit the RUN button. +& Ludus will evaluate this script and return its value. +& It will also perform "side effects": printing text to the screen, +& or making the "turtle" move (that's the little triangular guy). +& Lines that begin with an ampersand--&--are comments. +& Comments don't have any effect: they're for other people, not the machine. + +& here's your usual first program: +print! ("Hello, world!") + +& this is your first function call! +& notice a few things here: +& print! ("Hello, world!") +& ^^^^^^ This is the function name. +& Not `print` but `print!` +& ^^^^^^^^^^^^^^ This is what it prints. +& Note the quotation marks. +& Without them, Ludus would think this is code. +& ^ ^ Between parentheses! +& This is a "function argument." +& We need parens to send an arg to a function. + +& Try printing other things-- +& just delete the `&` at the start of these lines: +& print! ("Well, hello there!") +& print! ("Can", "we", "print", "multiple", "strings?") + +& What do you notice? diff --git a/tenprintmod.ld b/tenprintmod.ld new file mode 100644 index 0000000..7b309e5 --- /dev/null +++ b/tenprintmod.ld @@ -0,0 +1,28 @@ +& 10 print not quite working yet. need to wait for scott to fix mod +let gridsize = 20 +let root2 = 1.414213562 +let cellsize = 20 +let linelength = mult (root2, cellsize) + +fn tenprint! (times, width) -> { + + pendown!() + rt!(0.125) + fd!(linelength) + penup!() + back!(linelength) + lt!(0.125) + penup!() + rt!(0.25) + fd!(cellsize) + lt!(0.25) + + if eq? (0, mod(times, width)) then { + home!() + back!(gridsize) + } else nil + + if gt? (times, 0) then tenprint!(dec (times), width) else :donezo +} + +tenprint!(20, 200) diff --git a/walk.ld b/walk.ld new file mode 100644 index 0000000..10b98e9 --- /dev/null +++ b/walk.ld @@ -0,0 +1,34 @@ +& Lesson 8: A random walk + +& Besides colors, what can we get? +doc! (random) & Check the console to see the documentation + +pc! (random (colors)) + +& * random distances + +fd! (random (10, 50)) & walks forward a random amount between 10 and 50 + +& * random angles + +rt! (random (-0.25, 0.25)) & turns a random amount between -0.25 and 0.25 +& you can give turtle commands negative values! +& try giving `fd!` and `bk!` negative values. + +& do it a random number of times: +let times = random (10, 30) +& `let` allows us to give names to values; so far we have only named functions +& let times = random (10, 30) +& ^^^ `let` is a special form; after +& ^^^^^ This is the name we're binding +& ^ `=` goes between the lhs and the rhs +& ^^^^^^^^^^^^^^^ The value of this expression is what's bound to the name +& (in this case, it's a random value between 10 and 30) + +& here's our random walk: +repeat times { & repeat our random number of times + pc! (random (colors)) & a new random color + fd! (random (10, 50)) & a new random distance + rt! (random (-0.3, 0.3)) & a new random turn +} +