Archives May 2022

Creating 3D-printable landscapes and craters in Logo

Terrain can be saved as STL files (under the File menu in the web IDE) and then 3D printed!

setterrain

[x1 y1 x2 y2] (list) | [height floor ceiling] (list) | seed (number) | algorithm (word) OR [algorithm magnification] | style (word)

Creates terrain on the z-plane between the specified x and y co-ordinates.

These co-ordinates represent 10 turtle-units, and the output can be scaled using setterrainresolution.

height specifies the maximum height in terms of single turtle-units, similarly scaled using setterrainresolution. The floor value specifies the lowest level rendered, and any values lower than that value are rendered at the floor level. Similarly, the ceiling value represents the highest value rendered, and anything higher is lowered to that value.

The seed is provided to the algorithm that generates the terrain, the algorithm is the method used (currently only fbm and flat (no algorithm) are supported) and the style (voxel, line, triangle or combo (line and triangle) — note that combo uses the terraininterior color to render its lines).

Providing a list containing the algorithm type and a multiplier allow you to ‘zoom in’ or out on the terrain, making it more dense and complex, or spacious and simple. Multiple blocks of terrain can be defined so long as they do not overlap.

See terrain, setterrainresolution, setterraincolors, setterraininterior, setelevation, elevation, lockelevation, elevationsnap, unlockelevation

setterrain [-10 -10 10 10] [25] 25 “fbm “voxel

 

setterrainresolution

number

Sets the ‘resolution’ of the terrain, or the size of each ‘sector’ in turtle-units within the terrain ‘grid’ which expands out from [0 0]. For example, the higher the terrainresolution is the larger each voxel is in the terrain in the voxel mode, and the more area the terrain covers. See setterrain, terrainresolution

setterrainreolution 5

 

setelevation

[x y elevation] list OR [[x y elevation][x2 y2 elevation2]…]]

Sets the elevation height of the terrain at the specified x and y co-ordinates. If a floor value is set in the terrain impacted by setelevation, the elevation will be set to the floor value if it is greater than the elevation specified, unless the new elevation is provided as a list of a single value.

setelevation can also take list of lists. See elevation, setterrain

setelevation [10 20 10]

 

Voxel-based terrain generation:

TO voxelterrain
  reset hideturtle
  setterrainresolution 5
  setterrain [-2 -2 2 2] [20 1 10] random 500 [fbm 2] "voxel
END

 

Triangle-based terrain generation:

TO triangleterrain
  reset hideturtle
  setterrainresolution 5
  setterrain [-2 -2 2 2] [20 1 10] random 500 [fbm 2] "triangle
  ;the only real difference is changing the last parameter above to 'triangle'
END

Voxel-based crater generation:

TO voxelcrater
  reset hideturtle
  setterrainresolution 5
  setterrain [-2 -2 2 2] [20 1 10] random 500 [fbm 2] "voxel
  stop
  dropanchor penup pullout 50
  repeat 10 [
    repeat 180 [
      orbitright 2
      setelevation {xpos ypos 40 + 5 * repabove 1}
    ]
    pullout 2
  ]
  
  pullout 2
  
  repeat 9 [
    repeat 180 [
      orbitright 2
      setelevation {xpos ypos 95 - 5 * repabove 1}
    ]
    pullout 2
  ]
END

Triangle-based crater generation:

TO trianglecrater
reset hideturtle
setterrainresolution 5
setterrain [-2 -2 2 2] [20 1 10] random 500 [fbm 2] "triangle
stop
dropanchor penup pullout 50
repeat 10 [
repeat 180 [
orbitright 2
setelevation {xpos ypos 40 + 5 * repabove 1}
]
pullout 2
]

pullout 2

repeat 9 [
repeat 180 [
orbitright 2
setelevation {xpos ypos 95 - 5 * repabove 1}
]
pullout 2
]
END

Project Idea: How to Code a Hangman-style game in Logo

You can open this project in the web-based IDE environment by following this link: https://turtlespaces.org/weblogo/?pub=122

Due to Logo’s enhanced string-handling capabilities and built-in dictionary, making Hangman-style games in turtleSpaces is easy-peasy!

The mechanics of a Hangman game are simple: the computer chooses a word, and then the player chooses letters. If the letters they choose are in the chosen word, then those letters are revealed. If they aren’t in the chosen word, the ‘hanged man’ is built — although these days we probably shouldn’t do that due to nasty historical context, and choose something else.

In our example, we’ve decided to reconstitute the Egyptian god Konshu (aka Khonsu) as a shameless reference to the Marvel TV show Moon Knight. Once Konshu is fully-reconstituted then he will block out the sun forever — we don’t want that! Another potential conceit could be a space portal being built by aliens which once complete will deliver an invading armada.

Whichever way you choose to present it, the mechanic is the same — once you run out of ‘misses’ the game is over.

  • Computer chooses a word
  • The number of ‘misses’ is specified
  • We prompt the user for a selection
  • We check to see if the letter is valid (hasn’t been picked before)
  • We search through the target word looking for the letter
  • If we find it, we reveal it by placing it into the ‘solution’
  • We show the player if they’ve uncovered any letters or not
  • If not, we add more on to Konshu (or the space portal, or what-have-you)
  • We repeat until the target word is entirely revealed, or Konshu is built

Here are the ways in which Logo makes building this program simple:

  • We can use the pick and english primitives to choose a word from the built-in dictionary
  • We can use forever to repeat our game loop… forever!
  • We can use question and answer to prompt for and receive input from the user
  • We can queue the user’s selection into the list that logs the user’s choices
  • We can use the boolean containsp to determine if the user’s choice has already been chosen, by passing it the user’s current choice and the list containing the users previous choices
  • We can use count to ensure the user only provides a single letter as input
  • We can use dountil to repeat the question until we get a valid answer
  • We can use foreach to cycle through each letter of the selected word and check for matches.
  • We can use a combination of setitem and loopcount to set the appropriate space in the ‘solution’ container to the guess, should it match. If we initially set the solution container to be a series of dashes, we can then check for dashes using containsp later, to see if we’ve completed the solution
  • We can call another procedure to build our ‘hangman’, passing it the number of tries remaining, so we know which part of the hangman to build. We can use switch and case to build the relevant part of our hangman
  • We can use decrement to decrease a counter by one, and use if to check to see if we are out of tries.

Because we have all of these tools at our disposal in Logo, the game logic does not occupy very many lines of code, and is nearly english-readable:

TO game
 reset hideturtle
  
  (print |You must determine the magic word required to 
   banish Konshu back to the netherrealm.|)
  (print |If Konshu is able to reconstitute himself in 
   this realm and awaken, he will banish the sun!|)
  ;instructions (in brackets for display purposes)
  
  make "attempts 10
  ;this could be made more, or less
  
  make "target pick english 6
  ;similarly, we could pick a different target word length
  
  make "solve "------
  ;this container reflects correct player choices
  ;if we change the word length, we will need to change 
  ;the number of dashes
  
  make "picks []
  ;this holds the players choices so we can discount 
  ;duplicate picks
  
  forever [
    dountil (and
      not containsp answer :picks
      1 = count answer
    ) [question |Pick letter:|]
    ;repeatedly ask which letter until the player enters only
    ;one letter, and it has not already been picked
    
    queue answer "picks
    ;add the selection to the :picks list
    
    make "hit false
    ;set the :hit boolean to false
    
    foreach "i :target [
      ;for each letter in the :target word:
      
      if :i = answer [
        ;if the letter matches the users choice
        
        setitem loopcount "solve answer
        ;update the appropriate character in the :solve
        ;container to reveal the matching letter
        
        make "hit true
        ;set the :hit boolean to true, so we don't
        ;advance the building of Konshu
      ]
    ]
    
    show :solve
    ;show the current state of the :solve container
    
    if not :hit [
      ;if our selection wasn't in the answer:
      
      dec "attempts
      ;decrease the :attempts container by one
      
      konshu :attempts
      ;execute the konshu procedure, passing the
      ;number of remaining attempts to it
      
      (print |Attempts remaining:| :attempts)
      ;placing round brackets around a statement allows more
      ;parameters to be passed to it than its default
      
    ]
    
    if not containsp "- :solve [
      ;if there are no dashes left in the :solve container:
      
      print |You have banished Konshu!|
      finish
    ]
    
    if :attempts = 0 [
      ;if we've no attempts left:
      
      (print |The word was:| :target)
      print |Darkness descends.... forever!|

      finish
    ]
  ]
END

See? That was pretty easy — it only took an hour to write that code! Then comes the building of our ‘hangman’ model:

TO konshu :attempts
  
  ;this procedure builds the relevant part of the Konshu
  ;model.
  
  switch "attempts
  ;switch takes a literal container name
  ;and then subsequent case statements execute
  ;based on the contents of that container:
  
  case 9 [
  ;this is what we build if there are 9 tries remaining
  ]
  case 8 [
  ;...
  ]
  ;etc...
END

You simply put the code to create each stage of construction inside each case block. This could make a great project to tie language / string manipulation to game coding, with a bit of 3D artistry (putting the A in STEAM) in the mix.

Logo is such a powerful, easy-to-use language it can be hard to decide what makes the best introduction for your students. But you know them best, and we hope that one of our examples will work for them, and you!

Thanks for checking out this project!