New Game: Nothing

Food for thought - I’ve been trying to think of games you can play that remove players from a table/playing surface. I feel like there’s potential for some kind of 3-legged-race styled game, where two players have to move around while keeping two blinks connected… Maybe have 2 teams of two, where each team is trying to split the other team up?

2 Likes

I was thinking today on my aproach using the firstRun flag.

Actually I tried with a FirstRun flag but… Maybe is the same just runing that in setup() ??
I mean, setup is suposed to run only once and always as the first loop, right?

With the code on setup you have to add BlinkState = DEAD, but you save a variable (you don’t need firstRun flag) and is maybe a cleaner code (and 6 bytes bigger :upside_down_face:)

Here is my try (i’ve reduced the code to 19 lines, but is the same code):

#define DEATH_INTERVAL 10000
#define DEATH_SWITCH 500
Timer deathTimer; Timer switchTimer; Timer nextStep;
enum blinkState {ALIVE, DEAD}; byte blinkState = DEAD;
byte hue=0; byte dead=0; byte numNeighbors = 0; byte pastNeighbors = 0;
void setup() {deathTimer.set(DEATH_SWITCH*2);}
void loop() {
  numNeighbors = 0; FOREACH_FACE(f) {if (!isValueReceivedOnFaceExpired(f)) numNeighbors++;} 
  if (blinkState == ALIVE) {
    if (buttonPressed() || pastNeighbors != numNeighbors) {deathTimer.set(DEATH_INTERVAL); blinkState = DEAD;}
    if (nextStep.isExpired()) {setColor(makeColorHSB(hue,255,255)); hue++; nextStep.set(40);}
  }
  if (blinkState == DEAD) {
    if (deathTimer.isExpired()) pastNeighbors = numNeighbors; blinkState = ALIVE;
    setColor(RED); setColorOnFace(WHITE, dead); setColorOnFace(WHITE, dead+2); setColorOnFace(WHITE, dead+4);
    if (switchTimer.isExpired()) {switchTimer.set(DEATH_SWITCH); dead = (dead + 1) % 2;}
  }
  setValueSentOnAllFaces(blinkState);
}

Also, as adittion for maybe different games, if on dead state we add setColor(makeColorHSB(hue,255,255)) instead of setColor(RED), the dead state will remember the last showed color on alive (and will flash this color with the white pattern)
This can be useful for different game mechanics, as for example: You have to hit the Blinks and rearrange them and tun them onto dead states trying to get all in green colour :thinking:
ALSO, how about modifying the size of the step? Something like nextStep.set((random(3)+1)*10); this will make every step random from 10 to 40, so each color change length will be random!!

1 Like

@jrcwest I love that idea! I agree that there is definitely huge opportunity to develop games that can be played off the table. Right now I actually think that Dynamo is the first/only game to do this in the current game library. I don’t see any reason that the number of players has to be limited at 4 though. Theoretically any number of pairs could play to really up the “party” game dynamic. I’m envisioning potentially three games that could use this dynamic!

  1. A battle royale game that works how you described - Teams of two link two blinks together each holding one blink. They have to work together to separate the players on the other teams.

  2. An actual race game where the teams have to race to click a blink on the other side of the room without coming apart.

  3. A communication game where there are three person teams. The two players holding the blinks have their eyes closed while the third player gives them instructions to get to a blink on the other side of the room to press. The first team to do this wins.

Another off the wall idea that I had was to link all of these games together in an overarching game. Something akin to Mario party where the mini games are a part of a larger game. Games could be randomly selected and each game won could give you a point and the first person to five points could win. This functionality would be totally optional and players could also just choose the games that they want to play of course.

1 Like

Awesome! You can even make a random dice function (or use the Widget blink) to select the game to play in the party game!!

1 Like

@Confus3d I think the code definitely looks easier to read utilizing the setup state. I really like your idea to make the death state color dependent! I think you are right that it opens up the door to a whole host of other games! I think it is definitely something that I want to try to implement! Thanks for the suggestion!

@TheGoodSire Is pretty easy to implement :grinning:, just changing
nextStep.set(40); for nextStep.set((random(3)+1)*10); or wathever duration you want to achieve (in this example will be from 10 to 40 ms) but remember to add randomizer in setup!

1 Like

Awesome! Thanks again Francisco! I’ll definitely take a shot at implementing the new functionality tonight!

To expand on your game idea -

Single player - All blinks are combined into one large grouping. Activate dead states strategically to get all blinks on the same color dead state at the same time.

Multiplayer - All blinks are combined into one large grouping. Before the game, players choose a color to represent them during the game. Players then count down from three and start the game. Players strategically activate blinks to try to get as many blinks set on their selected color death state as possible. The game ends once all blinks are in death state. The player who has the most blinks in their death state color at that time wins. There will be a little bit of subjectivity on what colors constitute “green” or “blue”, but I think it should be relatively clear.

@Confus3d I really am amazed at how you keep finding ways to trim the code down! I definitely didn’t think it could get much smaller than the previous 38 line version! Haha

@TheGoodSire The main change is removing the two loops, is a pretty clean and short code so you don`t really need two loops. Also unified another IF and resumed variables in one line…

Well, I did it just for fun! To see how small I was able to do the same code without having to do scroll with the mouse in arduino.

As always feel free to use or copy paste what you want or what you need. I think, with this game, the code is irrelevant, is just maybe the 5% of the game, the 95% rest are the awesome mechanics you have been thinking for different games!!

1 Like

Nothing V1.7 is now live on Github and includes the upgraded death state and color change functionality proposed by @Confus3d. Thanks Francisco! I have also outlined 9 additional games bringing the total to 16. The rules for the games can be found in the edited original game post, or in the Github readme file. I’m not certain that I’ll keep all of these games for the final release, but I figured that I’d put them up as a working list. I think that in the final version of “Nothing” I’m going to shoot to have 18 total games with an optional automatic game selector. This should help the games feel a little more cohesive, and allow for a party mode where players compete to be the first player to gain 3 or 5 wins. Thanks again @jrcwest and @Confus3d for all of your help brainstorming ideas! Without your help “Nothing” would actually be nothing. I really appreciate it!

1 Like

Awesome work @TheGoodSire and @Confus3d! Really love how this turned out :slight_smile:

2 Likes

Look what just appeared on my phone while searching on Youtube…

Neil deGrasse Tyson explains Nothing… 4 weeks ago… what kind of witchcraft is this??? :rofl:

2 Likes

That is a pretty awesome coincidence! Gotta love Neil deGrasse Tyson! I watched the video out of curiosity and it’s actually surprisingly sort of relevant. Even the most empty places in our universe are still filled with millions of particles and the laws of physics. In the same way, the seemingly simple concept/code of nothing actually holds a huge range of possible games. In both cases you just have to know what you’re looking for!

New version v1.8 adds in the game selector functionality for party mode! @jrcwest If you happen to have a moment, I’d really appreciate it if you could test out the game selector functionality. It is accessed by long pressing any nothing blink. There should be three colors (Red, Blue, Yellow) and six numbers (1-6) that appear. Together, this combination identifies one of the 18 “Nothing” games. Definitely no rush, and no worries if you don’t have an opportunity to test. Thanks for the help!

hey @TheGoodSire there is something wrong with the colors in this two lines:

Color selectColors [3] = {BLUE, RED, YELLOW};
byte index = random(2) + 1;

In strings, there is also a 0 value, also, you don`t really need the number 3, as the strin has actually 3 values, so the correct code is:

Color selectColors [ ] = {BLUE, RED, YELLOW};
byte index = random(2);

(Please someone correct me if i’m wrong :upside_down_face:)

ALSO, remove the word byte in line 10!

24 lines, same code :upside_down_face:
You should check how I changed all the IF in dice for the switch (dice) , just not using break;

#define DEATH_INTERVAL 10000
#define DEATH_SWITCH 500
Timer deathTimer; Timer switchTimer; Timer nextStep;
enum blinkState {ALIVE, DEAD, SELECT}; byte blinkState = DEAD;
byte hue = 0; byte dead = 0; byte numNeighbors = 0; byte pastNeighbors = 0; byte index = 0; byte dice = 0;
Color selectColors [] = {BLUE, RED, YELLOW};
void setup() {deathTimer.set(DEATH_SWITCH*2); randomize(); hue = random(255);}
void loop() {
  setValueSentOnAllFaces(blinkState); numNeighbors = 0; FOREACH_FACE(f) {if (!isValueReceivedOnFaceExpired(f)) numNeighbors++;}
  if (buttonLongPressed()) {deathTimer.set(DEATH_INTERVAL); switchTimer.set(DEATH_SWITCH*5); index = random(2); dice = random(5); blinkState = SELECT;} 
  if (blinkState == ALIVE) {
    if (buttonPressed() || pastNeighbors != numNeighbors) {deathTimer.set(DEATH_INTERVAL); blinkState = DEAD;}
    if (nextStep.isExpired()) {setColor(makeColorHSB(hue,255,255)); hue++; nextStep.set((random(6)+1)*10);}}
  if (blinkState == DEAD) {
    if (deathTimer.isExpired()) {pastNeighbors = numNeighbors; blinkState = ALIVE;}
    setColor(makeColorHSB(hue,255,255)); setColorOnFace(WHITE, dead); setColorOnFace(WHITE, dead+2); setColorOnFace(WHITE, dead+4);
    if (switchTimer.isExpired()) {switchTimer.set(DEATH_SWITCH); dead = (dead + 1) % 2;}}
  if (blinkState == SELECT) {
    if (nextStep.isExpired()) {setColor(makeColorHSB(hue,255,255)); hue++; nextStep.set(3);}
    if (switchTimer.isExpired()) {setColor(selectColors[index]); 
      switch (dice) { case 0: setColorOnFace(OFF, 0); case 1: setColorOnFace(OFF, 1); case 2: setColorOnFace(OFF, 2);
                      case 3: setColorOnFace(OFF, 3); case 4: setColorOnFace(OFF, 4); break;}}
    if (deathTimer.isExpired()) {pastNeighbors = numNeighbors; blinkState = ALIVE;}}
}

Excellent! Thanks for the tips Francisco! Very helpful! I have now implemented those variable changes. I am a little confused on how your switch works though. To me it seems like it would only turn off the color on one face at a time instead of all the faces at once. A role of three should be represented by three lights on and three lights off and not just side 3 of the blink having it’s lights off. I’m probably just really misunderstanding what is happening though. Can you explain a little more how it works? Thanks again!

@TheGoodSire Sure, let me explain it to you!

switch (dice) { 
case 0: setColorOnFace(OFF, 0);   //Case 0, do from here up to a BREAK, so turn off faces 0,1,2,3,4
case 1: setColorOnFace(OFF, 1); 
case 2: setColorOnFace(OFF, 2);  //Another example, Case 2 de from here up to a BREAK, so turn off faces 2,3,4
case 3: setColorOnFace(OFF, 3);
case 4: setColorOnFace(OFF, 4); break;}}

Normally, you add break; at the end of every case, but here, you can add a sort of pyramid where the first case do all the levels, the second one do everything except the first one… and so on…

And to keep things weird, check what I did! Probably the worst horrible and most difficult way of showing this code, but minimizing the space to NOTHING:

@Confus3d That is a really clever way to code the switch! It makes perfect sense once you explain it! Thanks for taking the time to teach me a new trick!

I’ve been really enjoying these code consolidations! I think it would be very fitting to have the final code be the absolutely smallest version possible to pay homage to the concept behind nothing. Even though it makes the code a little harder to read, the code is so short it is still pretty easy to understand what is happening.

1 Like

I changed #define for int, as is almost the same, reduced the variable names, and added a #define for every setColorOnFace to do shorter lines of code, just for fun.

Here is the code if you want to play with it!:

#define COF setColorOnFace
int DI = 10000; int DS = 500; Timer deathT; Timer switchT; Timer nextS;
enum bS {ALIVE, DEAD, SELECT}; byte bS = DEAD; Color selectColors [] = {BLUE, RED, YELLOW};
byte hue = 0; byte dead = 0; byte numN = 0; byte pastN = 0; byte index = 0; byte dice = 0;
void setup() {deathT.set(DS*2); randomize(); hue = random(255);}
void loop() {setValueSentOnAllFaces(bS); numN = 0; FOREACH_FACE(f) {if (!isValueReceivedOnFaceExpired(f)) numN++;}
  if (buttonLongPressed()) {deathT.set(DI); switchT.set(DS*5); index = random(2); dice = random(5); bS = SELECT;} 
  if (bS == ALIVE) { setColor(makeColorHSB(hue,255,255));
    if (buttonPressed() || pastN != numN) {deathT.set(DI); bS = DEAD;}
    if (nextS.isExpired()) {hue++; nextS.set((random(6)+1)*10);}}
  if (bS == DEAD) { setColor(makeColorHSB(hue,255,255)); COF(WHITE, dead); COF(WHITE, dead+2); COF(WHITE, dead+4);
    if (deathT.isExpired()) {pastN = numN; bS = ALIVE;}
    if (switchT.isExpired()) {switchT.set(DS); dead = (dead + 1) % 2;}}
  if (bS == SELECT) { setColor(makeColorHSB(hue,255,255)); if (nextS.isExpired()) {hue++; nextS.set(3);}
    if (deathT.isExpired()) {pastN = numN; bS = ALIVE;}
    if (switchT.isExpired()) {setColor(selectColors[index]); 
      switch (dice) {  case 0: COF(OFF, 0); case 1: COF(OFF, 1); case 2: COF(OFF, 2);
                       case 3: COF(OFF, 3); case 4: COF(OFF, 4); break;}}}}