During Global Game Jam 2020, I was asked about the easiest way to have a state propagate a cluster of Blinks and I recalled the first algorithm I wrote to do this. Since then @danking222 has created and outlined a much safer way to do this, and it is such a nice solution. It takes a moment to wrap your head around why it is so important to do what he outlines, but it will save us all headaches down the road. That said, I believe there is definitely more than one way to pet a kitten, so try out the sketch below, and use it with caution. Also, I would love to hear your thoughts on why this is less safe
/*
* Spreading a message in the most precarious way possible
*
* Send the message we heard,
* then don't listen for a period of time
*
* This is how I used to propogate messages until Dan King created
* a much more stable solution. This sketch does do what you'd expect
* but it feels a bit more precarious than the validation that occurs with
* the Safe Communication tutorials
*
* by Jonathan Bobrow
* 02.02.2020
*/
#define BROADCAST_DURATION 100
#define DEAF_DURATION 200
uint32_t timeOfSwitch = 0;
Color colors[] = {WHITE,CYAN,MAGENTA,BLUE,ORANGE,GREEN,RED};
byte myState = 1;
byte numStates = 6;
void setup() {
// nothing needed in setup
}
void loop() {
// increment our state each time the button is pressed
if(buttonPressed()) {
setState(myState+1);
}
// determine if we should listen to our neighbors
if(timeOfSwitch < millis() - (BROADCAST_DURATION + DEAF_DURATION) ) {
// we have broadcasted and ignored feedback, so we are good to listen again
FOREACH_FACE(f) {
// is there a Blink on this face?
if(!isValueReceivedOnFaceExpired(f)) {
// get their value
byte neighbor = getLastValueReceivedOnFace(f);
// is our neighbor different (since Blinks broadcast 0 by default, we don't want to respond to 0)
if(neighbor != 0 && neighbor != myState) {
// let's match our neighbor :)
setState(neighbor);
}
}
}
}
// is the time passed our broadcast duration?
if(timeOfSwitch < millis() - BROADCAST_DURATION ) {
// return to sending 0
setValueSentOnAllFaces(0); // stop sending state
}
// display a color that matches our state
setColor(colors[myState]);
}
/*
* setState
* - Set the state of the Blink to this value
* - Broadcast the value of the Blink on all faces
* - Set the time that we started broadcasting
*/
void setState(byte _state) {
if(_state >= numStates) {
myState = 1;
}
else {
myState = _state;
}
timeOfSwitch = millis();
setValueSentOnAllFaces(myState); // start sending state
}