bp

Make a Micro Dreidle

Let's use makecode to turn a micro:bit into a dreidle!

Micro:bit is a tiny opensource device designed and sold by the BBC. It's made to teach computing and electical engineering concepts to students of all ages and it's a treat to hack around with.

A dreidle is a four-sided top marked with the Hebrew letters נ, ג, ה, and פ. You use it to trick Seleucid Greek Gestapo into thinking you're gambling when you're really clandestinely learning Torah.

Clearly, these two things were made to be one.

Sevivon, Sov Sov Sov

Let's start a new project and flip to the JavaScript editor (which is actually a typescript editor but who's counting?), since posting code blocks is easier than taking screen shots 😄.

The plan is to use the RNG to simulate a drey (spin) of the dreidle, picking a number from 0-3, then depending on which number we get, we'll display a different letter on the screen.

Let's start by generating a random number whenever we shake the micro:bit, and storing it in a variable called pan, which means "face" in Hebrew, as in the face the dreidle landed facing up.

function drey() {
  const pan = Math.randomRange(0, 3);
}

input.onGesture(Gesture.Shake, drey);

That having been accomplished, let's then display a given glyph. Since we're using the JavaScript editor we're less encumbered, so we can use a number of JavaScript constructs to pick and show our glyph LOL nope, we still have to pass string literals to showLeds, so our JS code will still be very congruent with blocks code. If we were using the blocks editor, we'd need to use the if / then / else block and drag in and duplicate "Show LEDs" blocks, which we'll also more-or-less be doing here, but at least we'll get to use switch

function drey() {
  const pan = Math.randomRange(0, 3);
  switch (pan) {
    case 0:
      return basic.showLeds(` ..#..
                              ...#.
                              ...#.
                              ...#.
                              .###.`);

    case 1:
      return basic.showLeds(` ..#..
                              ...#.
                              ...#.
                              ...#.
                              .##.#`);

    case 2:
      return basic.showLeds(` #####
                              ....#
                              ....#
                              #...#
                              ##..#`);

    case 3:
      return basic.showLeds(` #####
                              .#..#
                              .##.#
                              ....#
                              #####`);
  }
}

Honestly, if someone sent you a PR like that... I'm telling you those Greeks won't know what hit 'em. 🤔 I wonder if we could hack around makecode's requirement to use a template literal by passing a tagged template literal?

Only image literals (string literals) supported here; TaggedTemplateExpression

Hmm, guess not. 🤷.

Adding Sounds

Fine, the dreidle spins, but where's the pathos? Let's play a crushing dirge when we lose a throw, and the twinkling melody of gold coins when we take the pot:

case 0:
  music.playSoundEffect('sad', SoundExpressionPlayMode.InBackground);
case 1:
  music.playSoundEffect('twinkle', SoundExpressionPlayMode.InBackground);

Now comes the fun part. When we tap the micro:bit's logo, let's play a little ditty to remind ourselves (and any adults who happen to be in earshot) precisely which holiday is approaching, in case it wasn't already clear to them.

I haven't figured out how to define your own melodies using the keyboard inputs, so let's just play the notes one by one:

function sevivon() {
  music.playTone(Note.D, 200);
  music.rest(40);
  music.playTone(Note.D, 200);
  music.rest(40);
  music.playTone(Note.E, 480);

  music.playTone(Note.F, 200);
  music.rest(40);
  music.playTone(Note.F, 200);
  music.rest(40);
  music.playTone(Note.E, 480);

  music.playTone(Note.A, 200);
  music.rest(40);
  music.playTone(Note.A, 200);
  music.rest(40);
  music.playTone(Note.G, 480);

  music.playTone(Note.F, 200);
  music.rest(40);
  music.playTone(Note.F, 200);
  music.rest(40);
  music.playTone(Note.E, 480);
}

input.onLogoEvent(TouchButtonEvent.Pressed, sevivon);

This way, if any of Antiochus' Nazi thugs try to interrupt our holy game of craps, we'll just tap the logo again and again until they're driven away by sheer bloopety bleepety annoyance. Brilliance!

Grab the final code here 👇
function sevivon() {
    music.playTone(Note.D, 200)
    music.rest(40)
    music.playTone(Note.D, 200)
    music.rest(40)
    music.playTone(Note.E, 480)

    music.playTone(Note.F, 200)
    music.rest(40)
    music.playTone(Note.F, 200)
    music.rest(40)
    music.playTone(Note.E, 480)

    music.playTone(Note.A, 200)
    music.rest(40)
    music.playTone(Note.A, 200)
    music.rest(40)
    music.playTone(Note.G, 480)

    music.playTone(Note.F, 200)
    music.rest(40)
    music.playTone(Note.F, 200)
    music.rest(40)
    music.playTone(Note.E, 480)
}

function drey() {
    switch (Math.randomRange(0, 3)) {
        case 0:
            music.playSoundEffect('sad', SoundExpressionPlayMode.InBackground);
            return basic.showLeds(` ..#..
                                    ...#.
                                    ...#.
                                    ...#.
                                    .###.`);

        case 1:
            music.playSoundEffect('twinkle', SoundExpressionPlayMode.InBackground);
            return basic.showLeds(` ..#..
                                    ...#.
                                    ...#.
                                    ...#.
                                    .##.#`);

        case 2:
            return basic.showLeds(` #####
                                    ....#
                                    ....#
                                    #...#
                                    ##..#`);

        case 3:
            return basic.showLeds(` #####
                                    .#..#
                                    .##.#
                                    ....#
                                    #####`);
    }
}

input.onGesture(Gesture.Shake, drey);
input.onLogoEvent(TouchButtonEvent.Pressed, sevivon);

Take it for a spin (🥁) in the simulator:

Or take a look at a blocks version for younger kids.

Happy Hannukah!