pxt-calliope/docs/projects/hot-or-cold.md
Carlos d9ed0652e6 Fix misspells in documentation macros ()
* Fix doc macro in "hot or cold" project

* Fix doc macro in "wallet" project
2017-06-25 08:28:21 -07:00

4.7 KiB

Hot Or Cold

@description A Hot-or-Cold treasure hunt game

~avatar avatar

Find the hidden @boardname@ before the other players!

~

https://youtu.be/nbRfNug-RkY

Beacons

In this game, players are looking for hidden @boardname@ that emit radio signals. The hidden @boardname@ are called beacons.

Setting up the radio

We set the radio group to 1 to make sure all the players are using the same group. We also tell the @boardname@ to transmit its serial number (that's a unique number that identifies it) so that the player can tell apart each beacon. We also reduce the power of the antenna to reduce the range of transmission.

radio.setGroup(1)
radio.setTransmitSerialNumber(true)
radio.setTransmitPower(6)

Beacon gotta beam

The beacon simply needs to send a radio message every now and then. To pace it out, we add some |show icon| blocks to animate the screen.

basic.forever(() => {
    radio.sendNumber(0)
    basic.showIcon(IconNames.Heart)
    basic.showIcon(IconNames.SmallHeart)
})
radio.setGroup(1)
radio.setTransmitSerialNumber(true)
radio.setTransmitPower(6)

Hide the beacons

Download the code to your beacon @boardname@ and hide them!

Hunters

The hunter @boardname@ look for beacons.

Is the beacon close?

To determine how far or close, we use the signal strength of each radio packet sent by the beacons. The signal strength ranges from -128db (weak) to -42db (very strong).

radio.onDataPacketReceived( ({ receivedNumber, signal }) =>  {
    basic.showNumber(signal)
});
radio.setGroup(1)

Take notes of the values as you move around the beacon.

  • hot signal value: _________________
  • mild signal value: _________________
  • cold signal value: _________________

Hot or cold?

The hunter screen displays SmallDiamond on the screen if the beacon is far, Diamond mildly close and Square if it is close. Use the signal values collected in the previous step to determine when to show those letters.

Here is an example that uses -95 and less for cold, between -95 and -80 for mild and above -80 for hot. Use your own values based on the room setup or the hidding place.

To make the program more responsive, we add a |led stop animation| to cancel any icon animation when a new beacon packet comes.

radio.onDataPacketReceived( ({ receivedNumber, signal }) =>  {
    led.stopAnimation();
    if (signal < -90) {
        basic.showIcon(IconNames.SmallDiamond)
    } else if (signal < -80) {
        basic.showIcon(IconNames.Diamond)
    } else {
        basic.showIcon(IconNames.Square)
    }
})
radio.setGroup(1)

Download the code and play the game!

Extra: Multiple beacons

We're making the game more interresting by counting how many beacons a player has seen so far.

Remember the beacons

Remember that the beacon was configured to transmit its serial number? We can use this information to determine if we've visited a beacon for the first time.

To do so, we are going to add an array variable that will hold all the beacon serial numbers seen so far.

let beacons: number[] = [0]

Whenever we receive a new packet, we are going to check if the beacons already contains the serial number. If not, we add the serial number at the end of beacons and increment the |game score|.

To check if an array contains an element, we use the |find index of| block which returns -1 if the value is not found.

let beacons: number[] = [0]
radio.onDataPacketReceived( ({ receivedNumber, signal, serial }) =>  {
    if (signal > -50 && beacons.indexOf(serial) < 0) {
        beacons.push(serial)
        game.addScore(1)
        basic.showNumber(game.score())
    }
})

Show my score

To see the current score, we add a |on button pressed| that displays the score on screen when A is pressed.

input.onButtonPressed(Button.A, () => {
    basic.showNumber(game.score())
})

All together

The hunter code with all th pieces together looks like this now. Download it and try it out with multiple beacons!

let beacons: number[] = [0];
radio.onDataPacketReceived( ({ receivedNumber, signal, serial }) =>  {
    led.stopAnimation();
    if (signal < -95) {
        basic.showIcon(IconNames.SmallDiamond)
    } else if (signal < -80) {
        basic.showIcon(IconNames.Diamond)
    } else {
        basic.showIcon(IconNames.Square)
        if (signal > -50 && beacons.indexOf(serial) < 0) {
            beacons.push(serial)
            game.addScore(1)
            basic.showNumber(game.score())
        }
    }
})
input.onButtonPressed(Button.A, () => {
    basic.showNumber(game.score())
})
radio.setGroup(1)