Input not disabling

I’m trying to make Simon Says game for the micro:bit, but I have a problem with inputs getting recorded if pressed while the game is running some other code (like displaying the sequence or the game over message).

I tried to disable inputs by using a variable to flag when other code is running. The code for each input first check if that flag is false (0. I didn’t find a way to make a Boolean variable with the blocks), and if so, change it to true and run the main function. This variable is then reset at the end of the main function.

It works for most inputs, but for some reason, the input that was used last to call the main function and set the variable can still be triggered again, which the game react to later as if the variable didn’t existed.

I even tried to make a debug function that records the inputs and call it at the end of the main function before the variable is reset, and it turns out that after each time the input register and the main function is called, it is only “aware” of that input and the next trigger is not taken into account yet, and the variable is indeed set to true.

I also tried to pause the main function before resetting the variable to let the scheduler run the even handlers for the inputs (and hopefully realize that the variable is still true so the if statement should prevent them from calling the main function) but it still didn’t worked.

How can I fix this? Here is the code in JavaScript (I used the blocks to code but the generated JavaScript is easier to share.

“working” is the variable that keeps track if other code is running (or is currently “working”)

Play() is a function to play a sound and display an arrow pointing at an input (because I can’t make the buttons glow like in the real Simon Says).

The main (Check) function:

function Check (num: number) {
    if (sequence[index] == num) {
        Play(num)
        index += 1
        if (index >= length) {
            sequence.push(randint(0, 3))
            length += 1
            basic.pause(500)
            for (let index = 0; index <= length - 1; index++) {
                Play(sequence[index])
                basic.pause(100)
            }
            index = 0
        }
    } else {
        music.play(music.stringPlayable("C5 A B G A F G E ", 120), music.PlaybackMode.LoopingInBackground)
        basic.showString("Game Over")
        music.stopAllSounds()
        basic.showString("Score:")
        basic.showString("" + (length - 1))
        sequence = [randint(0, 3)]
        index = 0
        length = 1
        Play(sequence[0])
    }
    basic.pause(100)
    Working = 0

Example input:

input.onButtonPressed(Button.B, function () {
    if (Working == 0) {
        Working = 1
        Inputs.push("B")
        Check(1)
    }
1 Like

Hmm, @richard, would your new state extension also work with micro:bit?

1 Like

no, i’m afraid it is arcade specific at the moment

@Yuvalyly can you share a link to your project?

Here is the project link: https://makecode.microbit.org/S62918-32140-58102-60932

BTW ignore the “Inputs” array. It is used only for testing.

@Yuvalyly ah, I see what’s going on here. When you pause inside of a button handler, we queue up any other button presses that happen while the handler is still executing.

This is sort of annoying to work around in micro:bit because there isn’t a nestable “run in background” block. Here’s an extension you can add to your project to get one:

The fix here is to take the portion of your button handler that pauses and wrap it in a “run in background” block like so:

image

This will prevent the button handlers from queueing up

1 Like

Thanks for the help. I’ll need it to not be midnight to be able to focus on it enough to understand it though. I’ll check it tomorrow.

Nice game, interesting case and welcome, @Yuvalyly!

@richard:
Thanks for answering!

I’ve been playing around with background/parallel tasks in both MakeCode for micro:bit and Mindstorms, and have found the former to be more difficult to grasp.

It just occurred to me that the nestability of these blocks might be exactly why, because the background task in micro:bit is not nestable;

while in Mindstorms it is;

Aren’t there really equally numerous use cases and needs for support for both nestable and un-nestable versions of this block, by default and without the need for an extension, as this example case shows?

And for the micro:bit maybe, in fact, a nestable block could be more important to have instead of the un-nestable, since you apparently can achieve the same result as the un-nestable background block by using a (un-nestable) forever loop, like the documentation link above shows?

Here’s a grey block version similar to your solution, which I probably would never have thought was possible, just due to the background block not being nestable…:

@Vegz78 yeah, the reason it’s not nestable in micro:bit is purely historical. We realized our mistake after shipping it for micro:bit and so it’s nestable in all of our other editors.

The fix never propagated backwards because we try very hard not to update blocks once they have been shipped; a lot of teachers take screenshots of the editor when making teaching materials and we don’t like to break them.

That being said, in a perfect world I would do away with the un-nestable version entirely since the nestable version can be used to replicate it perfectly.

1 Like

Any way we(also as teachers with said screenshots in teaching material) can help?

The utility argument for a nestable background block seems pretty obvious.

If not possible to aim for perfection, maybe an addendum, which wouldn’t be that a breaking* change, in a command submenu that is not the most frequently used(or screenshot), anyways?

*Even though a vocal and fragile group, I am sure we teachers would survive such a change without having to lie down in the fetus position, so you do not have make us the main consideration against doing the right thing… :wink:

I can’t figure out how to import the run-in-background extension. When I click the link you pasted here, it just lead to an empty project.

@Yuvalyly share links can be imported the same way as extensions! Just paste the link into the search box you get when you open the extensions dialog

It’s working! Thanks!