Creating blink "pairs"

Hi all,

I’ve been rather enjoying tooling around with these little guys. I’ve created a little “memory” game as a jumping-off point (find matching pairs in the grid).

At the moment each Blink randomly selects its own colour during setup. This was just a temporary stopgap so I could move on and get the rest of it running, but I’d like to go back and fix it so that the setup generates coloured pairs of blinks (e.g. 2 red, 2 green, 2 blue etc). Ideally, these pairs wouldn’t necessarily always be adjacent.

I’m not sure how to tackle it – I can broadcast a message like “I am green, who’s with me?” easily enough, but what’s got me stuck is how to boil any responses back to a single “winner” without just randomly selecting a directly connected peer.

  • it should be possible for a match to be adjacent
  • it should also be equally possible for a match to be on the other side of the grid

Any advice/pointers? The networking stuff is the most interesting part of working with these but it’s also the part that completely bakes my noodle!

cheers
-O

1 Like

This is actually a non-trivial problem to solve giving the limitations of the platform. But in a general way there are lots of different solutions for this.

The easiest is simply to ask the user to set the Blinks in color pairs and them setup the "board whatever way they want).

Another a bit more ellaborate is to simply require a specific organization for the setup state (say, 2 rows of blinks all connected in a single cluster). Picking up a suitable arrangement and assuming the user will do the right thing turns this in a trivial problem (in the end the user would still be responsible to build the board).

Now to have a board assembled and them automatically filling the colors with your requirements most likely means that at least one Blink needs to know the full arrangement of the board (see recent question about this).

Thanks for the reply – it’s actually encouraging to know it’s not simple! I had considered manual setup but it felt like a cheat given the way most of the other games manage themselves.

My latest approach has been to walk a tree to allocate pairs based on direct proximity and then “shuffle” the tree once allocated. It works in my head, but applying it to the hardware is a different story :slight_smile:

1 Like

I actually want to do something similar. Or at least it seems similar to me. Anyway, I have an idea for a game that would involve a mechanic to make “pairs,” but it’s only on single faces rather than it being the entire Blink. (Because the aim in my game would be to connect same-colored sides together, so there has to be an even number of faces in each color.) I also want the game to allow for some Blinks to have more than one face light up, so I’d have to put some code in there to make sure that each time, it comes up with an arrangement that is “solvable.”
…As I was typing this I realized that this mechanic is probably also used in Puzzle101. Do you think I could maybe steal some code from Puzzle101- I mean, take some concepts from Puzzle101 and use them in my game?

Sure. Puzzle 101 is open-source: GitHub - Move38/Puzzle101: A 6-Blink puzzle game that auto-generates puzzles for the player

I’ve been thinking about how to solve a similar problem, and here’s the best I’ve come up with:
In the initial setup state:

  1. Have Blinks distribute their serial numbers to the network, and collect a list of all the serial numbers. This is easiest if the number of blinks used is fixed in advance, since you know when you’ve got all of them. Call this number n.
  2. Sort the serial numbers and assign yourself a number which is the index of your serial number in the sorted list.
  3. XOR all the serial numbers together to generate a number and set it as the random seed.

In the resetting-the-game state:

  1. Randomly and uniformly sample the space 0…n-1 without replacement n times. Remember the round number x in which your index from step 2 above came up.
  2. Set your color to x%(n/2).

As long as nothing else in the game generates random numbers besides this process, they’ll always agree and pair off perfectly. Make sure you DO NOT call randomize() after setting the random seed or the whole scheme is ruined.

The main issue here is that passing a big amount of data (serial numbers have 9 bytes which is a lot of data for the IR link) is non trivial. As there is no guaranteed delivery, you would need to set up an ack process that would be relatively complex and, due to that, take a lot of code space.

I spent a lot of time working on issues like this and the result was a custom blinklib that includes guaranteed delivery for datagrams while at the same time using less space than the official one.

With that solved, you still need a way to propagate your data. The way I did it is that one Blink start propagation and start and associated timer. Then each blink that gets a message resets their own timers and propagates the message to all neighbors. Blinks will record new entries and ignore entries they already saw (so they will not propagate the same entry twice). This process guarantees that at some point messages will stop being propagated and the timer will run out (I use a 2 seconds timer). When it runs out the Blink assumes that all Blinks are accounted for.

Would it really be necessary to send all nine bytes? There’s no way there will ever be 2^72 Blinks in existence. Is there some fragment of the number that is enough to ensure uniqueness?

I have no idea but I would suspect no. The numbers are either random (factory set) or they follow a pattern. If they do, then one might send just the most commonly changing part (i.e. MSB as in bytes). You still need the ack though. Even a single bite is not guaranteed to get to the other Blink (but it will most of the times).

simpler plan:
in the set up phase, you tap all the blinks one at a time, and when you do, they change color and remember and send out the smallest number they have not yet heard from the network. when you are done, tap any of them again and it sends out a random number to be used as the random seed by all blinks. all blinks synchronize on that shared random seed. then the plan for constructing pairs proceeds as above. this can work quickly and even without the custom blinklib if you’re okay with there being less than 64* different possible pairing sequences (and of course, the synchronization only has to happen once, so all possible pairings have a chance to happen in future rounds).

*(64 minus the number of codes you need to reserve to signal other states)

I would go with a non predetermined approach.

For a “Memory” game this non predetermined approach would look like:

All “tiles” start hidden with colors not yet determined.

Reveal a tile. Blink randomly chooses from available colors. Choose green. Blink locks self as green. Broadcast first selection is green.

All unreaveled blinks decrement their internal count of available green tiles.

Reveal second tile. Blink randomly chooses from available colors. Choose red. Blink locks self as red. Broadcast second selection is red.

All unreaveled blinks decrement their count of available red tiles.

First choice blink responds with broadcast of match success or failure.

On success both blinks stay revealed.
On failure both blinks hide but stay locked to their color.

Rinse repeat.

Long press a blink to send reset broadcast.

Call this the “Schrodinger” approach to Blinks programming.:crazy_face:

FYI: Thalassaphobia uses this “Schrodinger” approach.

3 Likes

Very clever, but there are situations where you may need to create pairs or unique ids all at once at the beginning. Not every game will be amenable to this strategy.

1 Like

FWIIW, this is indeed a very clever approach.

1 Like

Love this. You do need to enumerate the tiles before starting so you know how many colors to include.

1 Like