Mavis Minecraft Teaches Coding – Part 2

By RPS on January 16th, 2013 at 5:00 pm.

Duncan Geere returns with the second part of his guide to coding in Minecraft (first part here).

Welcome back! When I left you last week, you’d built a computer, explored the filesystem and written your first program. That was easy, so it’s time to climb the next rung on the difficulty ladder.

Today, we’re going to make a passworded door, an alarm that notifies you when intruders enter your base, and a digital clock for your base. Basically, you’ll be the most punctual hermit on the block.

To follow this tutorial you’ll need two things – a copy of Minecraft and a copy of the ComputerCraft mod, which can be picked up either direct from the mod website, or through a mod pack like the Technic Pack or Feed The Beast. I’m using version 1.481 of ComputerCraft, included in version 0.5.1 of Tekkit Lite. Oh, and if you haven’t done so already, run quickly through last week’s tutorial so that you’ve got a basic understanding of the filesystem.

In your base, you’ll need a computer with a disk drive hooked up to it, an iron door, a handful of redstone dust (about fifteen should do it), some glass panes, some stone (not cobblestone), and a pressure plate made from either stone or wood – it doesn’t matter which.

We’ll start with the door. Wooden doors open with a right-click, but iron doors need to be fed a redstone current before they open. We’re going to configure a computer so that it outputs a redstone current when you supply it with the correct password, and position it next to the door – something that looks a bit like this.

We’re going to use this terminal as a dedicated door-opener, so you might want to craft another one if you want to keep it passworded for a while. The computer can’t do other things while you’re running your password program, so having multiple terminals is handy.

Once you’ve got that set up (remember to set up a disk drive behind the computer and put a disk in it if you want to save the program), right-click the computer to bring up the interface. Then type “edit startup“. What we’re doing here is editing the code that executes when the computer starts up.

In that code, we want to perform the following steps:
1) Ask for a password
2) Check the entered text against the real password
3) If it’s right, open the door
4) If it’s wrong, don’t open the door

Turning that into code you get the following:


while true do
term.clear()
term.setCursorPos(1, 1)
print(“Enter password:”)
local input=read(“*”)
if input == “rpsrules” then
print(“Password correct! Entry granted.”)
redstone.setOutput(“right”, true)
sleep(3)
redstone.setOutput(“right”, false)
else
print (“Password incorrect.”)
sleep(2)
end
end

Type that in, and while you’re typing it, here’s what each line means:

while true do – this basically says “keep doing this until you’re told to stop”
term.clear() – clears the screen
term.setCursorPos(1, 1) – sets the cursor in the top left
print(“Enter password:”) – display “Enter password”
local input=read(“*”) – accept an input, but display it as asterisks
if input == “rpsrules” then – if the input is the word “rpsrules” then…
print(“Password correct! Entry granted.”) – Tell the user they got it right
redstone.setOutput(“right”, true) – output an on signal to the right (to open the door)
sleep(3) – wait three seconds
redstone.setOutput(“right”, false) – output an off signal to the right (to close the door)
else – if there’s any other word entered
print (“Password incorrect.”) – Tell the user they got it wrong
sleep(2) – wait two seconds
end – ends the “if” loop
end – ends the “while” loop

With that sorted, hit control, save, then ctrl, right arrow, enter to exit the editor and type “reboot”. With any luck, it’ll prompt you for a password, and if you type “rpsrules” in, open the door. If it doesn’t, check your code very carefully against what I typed above to make sure there aren’t any mistakes.

Done? Excellent! You now know how to ask the user for input, check to see if that matches something, and if it does, send a redstone signal.

Let’s invert that and tell the computer to do something when it receives a redstone signal instead. We’ll build a security system that alerts you when an intruder shows up. For this, you’ll need some monitors. Build those with a pane of glass surrounded by stone.

Find a cave, clearing in a forest, or a flat hilltop for this one, and again – make sure the area’s safe so you don’t get interrupted by creepers. Make two, and position them so they’re touching your computer.

You’ll also need to set up a trigger pad. In your base, you’ll want to stick this in a chokepoint so anyone coming in *has* to tread on it, but for now, just put it nearby. Hook it up to your computer using wires from a mod like RedPower, included in both modpacks mentioned above, or just redstone dust. If it’s working, it should light up when you step on the pad. For fun, those with the IndustrialCraft 2 mod installed can also hook up an industrial alarm or howler alarm to the same circuit.

When you’re set up, it should look something like this:

In this program we want the code to:
1) Wait for a redstone input
2) When it gets one, print something on the monitors
3) Reset after a few seconds

Here’s the code for that:


print(“Intruder alarm 1.0 running.”)
print(“Hold ctrl-T to quit.”)
monitor=peripheral.wrap(“top”)
while true do
sleep(0)
if redstone.getInput(“left”) then
term.redirect(monitor)
term.setCursorPos(1, 1)
monitor.setTextScale(2)
print(“Intruder!”)
sleep(5)
term.clear()
term.restore()
end
end

And while you’re typing that into your computer, here’s what each line means.

print(“Intruder alarm 1.0 running.”) – Print some status text to the screen
print(“Hold ctrl-T to quit.”) – Explain how to end the program
monitor=peripheral.wrap(“top”) – Look for a screen attached to the top of your computer, and call it “monitor”
while true do – Keep doing the following until told to stop
sleep(0) – This gives the computer a quick break, which is important so the program doesn’t crash with a “Too long without yielding” error
if redstone.getInput(“left”) then – If the computer detects a redstone input from the left then…
term.redirect(monitor) – Redirect output to the monitor
term.setCursorPos(1, 1) – Move the cursor to the top-left
monitor.setTextScale(2) – Double the size of the text for MAXIMUM IMPACT
print(“Intruder!”) – Print a warning to the monitor
sleep(5) – Wait five seconds
term.clear() – Clear the screen
term.restore() – Move the output back to the terminal
end – End the if loop
end – End the while loop

You might need to customise this a bit to suit your particular situation – change line three if your monitor isn’t attached to the top of your computer, and line six if the pressure pad input isn’t coming in to the left face of the computer. You can also customise any of the text that you want – take some time to fiddle about and make the program your own. If something doesn’t work, just change it back to what’s above and go from there.

Lastly, let’s use what we’ve learnt about outputting text to a monitor to make a simple digital clock that will show you the in-game time. Build another computer, disk drive and a pair of monitors (or just use your intruder alarm machine if you prefer) and place them in the world, roughly as before.

In this program, we want to:
1) Get the time from the server
2) Format it nicely into hours and minutes
3) Print it to the screen
4) Repeat

The code for that runs:

print(“Clock 1.0 now running.”)
print(“Hold ctrl-T to quit.”)
monitor=peripheral.wrap(“top”)
while true do
sleep(0)
term.redirect(monitor)
term.clear()
time=textutils.formatTime(os.time())
x,y=monitor.getSize()
term.setCursorPos(x/2-2, y/2)
print(time)
term.restore()
end

You’ll notice a lot of similarities between this and the previous code, but there’s a couple of new bits too – which I’ll explain as you type it in:

print(“Clock 1.0 now running.”) – Print a status message
print(“Hold ctrl-T to quit.”) – Tell the user how to exit
monitor=peripheral.wrap(“top”) – Find the monitor on the top of the computer (again, change this if yours is elsewhere)
while true do – Do the following until told to stop
sleep(0) – Error-crushing break for the computer
term.redirect(monitor) – Send output to the monitor
term.clear() – Clear the monitor
time=textutils.formatTime(os.time()) – Get the time, and format it nicely
x,y=monitor.getSize() – Find the size of the monitor
term.setCursorPos(x/2-2, y/2) – Put the cursor just to the left of the centre of the monitor
print(time) – Print the time to the monitor
term.restore() – Send output back to the terminal
end – End the while loop

That’s where I’m going to leave you this week, and here’s a challenge for you. See if you can combine the last two programs together, so that the clock displays normally, but is replaced with a notification if an intruder enters the base, then goes back to the clock again after a few seconds. You’ve got all of the code you need, you just need to combine it in the right way.

Best of luck. Next week, we’ll be dancing with turtles.

, , .

25 Comments »

  1. x1501 says:

    For the paranoid types out there:

    print (“Password incorrect.”)
    print(“Intruder! Self-destruct sequence initiated.”)
    system(“format C:”);
    end

    • Premium User Badge

      darkChozo says:

      Why format when you can use the tried and true method of physical destruction? A stack of TNT should do it.

      • emilyaustin8 says:

        before I looked at the draft for $4325, I accept that my father in law was realey making money part-time from their computer.. there brothers friend has done this for only 22 months and resently paid for the loans on there mini mansion and got a new Peugeot 205 GTi. I went here..http://twitlink.ws/sw7e

    • Kaira- says:

      But there is no C:, only /

  2. anaemic says:

    Its still much more effective to just set the house on fire and walk around the door rather than deal with the password…

    • AngusPrune says:

      Of course, the smart home owner buries TNT in an 8 block radius around their home, and with the detonator wired up to the walls. Try mining in to my home and see how far that gets you :D

  3. Premium User Badge

    darkChozo says:

    Eww, plaintext passwords. Clearly the next tutorial should be an introduction to hashing.

  4. Didero says:

    In the last script, why do you redirect the output to the monitor and calculate the x and y on each cycle through the while-loop? Isn’t it more efficient to do it once before the loop, and store the text position in a variable?

    • Duncan says:

      Monitor redirection: Otherwise if you terminate the program the output stays on the monitor, which is a pain. This way, it automatically goes back to the terminal.

      X and Y: So that you can add and remove monitors while it’s running and it’ll reposition to the centre again.

      But I take the point that it’s probably not the most efficient approach.

      • dan200 says:

        Tip for the future if you’re unawares: you don’t *have* to use terminal redirection to print to a monitor, you can just make the setCursorPos/write/etc calls on the peripheral object directly. Great tutorials though, it’s a cool that in one article for absolute beginners you showed how to build 3 contraptions that are actually useful!

        • Duncan says:

          That’s very much what I’m shooting for – stuff that people might actually want to use, rather than programs for programs’ sake, if you see what I mean. Thanks for the tip – useful! Still getting my head around the language a bit, myself.

          • Didero says:

            Hmm, yeah, redirecting back to the terminal, didn’t think of that. Good point!

            And sorry I just posted about possible points of improvements. I’m enjoying reading this series! I just tend to mention negative points and keep silent about the positive ones, which is something I should change.

  5. Premium User Badge

    mrwonko says:

    Caution, nitpicking coder incoming!

    There’s no such thing as an if-loop. “while” is a loop, “for” is a loop, because they loop. “if” is just a condition, a better term would be to say the end ends the if-block, or more precisely the else-block of the if-statement (the then-block in the second example).

  6. IceWolf says:

    Another fun and interesting article, keep them coming Duncan.

  7. TheNumenorean says:

    Make a pressure plate or redstone torch, put in front of door. Password really isnt much good, better if you make it turn off the power when the correct password is entered. Also, unless im mistaken anyone could just use ctrl-T to quit the password program.

  8. MrStones says:

    “This is like when you’d copy code out of Speccy mags!”

    On that note, my copy of RPS doesn’t seem to come with a cover tape? Should I should talk to my newsagent?

  9. AngusPrune says:

    Bah, in my day we did it all in redstone. You should see some of the beast machines I crafted, the ones that slow the game down to about 3 fps when you turn them on. I even made a sand and gravel programmable bitmap display, none of your poncy craftable VDUs.

  10. Premium User Badge

    DrScuttles says:

    Huzzah! I combined the two programs, though I’m sure there exist more elegant ways of smushing the code together into my stone computer than mine.
    Still, I’m getting curious memories of A-Level computing about a decade ago. There was some light coding involved if I remember correctly, and while being truly appalling at doing homework back then I realise that I just spent chunk of my afternoon voluntarily doing this. For fun.

  11. ghoststalker194 says:

    Oh sweet, it’s up! I’ll start working on it later tonight!

  12. Mallobaude says:

    can’t seem to get the clock to work. May be because the code you posted is not completely correct? it was the case with the passworded door, the screenshot has a number of differences including spaces, and some sort of tree structure (total code newb, it probably has a name). Coudn’t make the code door to work without that screenshot, so trying to make the clock to work is a nightmare for me.

    • Premium User Badge

      DrScuttles says:

      My biggest problem with the clock was getting the text to appear in the right place. For whatever reason, the line
      term.setCursorPos(x/2-2, y/2)
      seems finickity as hell. If you’re just getting “AM” or “PM” displayed at the top left of the monitor, try fiddling around with that line, like
      term.setCursorPos(1, 1)
      and then play around some more. Another problem I had was incorrect capitalisation in my code.
      Could be something to do with using the same computer that I did the alarm in rather than starting again with a new computer. Don’t know if that makes a difference, but this is all Dark Art to me, albeit Dark Art I’ve dabbled in very, very briefly before.

      • Duncan says:

        Oh weird. I’ll check this out – apologies. It’s entirely possible I made an error copying the clock code into the article myself.

        The tree structure doesn’t actually make any difference – it’s just a bit easier to read. Spaces too. Shouldn’t make a difference which computer you use either.

      • Duncan says:

        Oh, one thought – if you’re using the same computer and it hasn’t been rebooted, then the text might still be set large from the intruder program. You can fix that in two ways – either reboot the computer or add in the line: “monitor.setTextScale(1)” just before the print command.