Tag Archives: games

(Blind) Maze puzzle now with generation and play modes.

Info:

  • PlatformIO tested ( install StackArray.h in lib/StackArray/StackArray.h )
    • Reset button and dipswitches for below options
      • Visited pathmode ( dip switch 1)
        • Preview maze generation ( dip switch 3)
        • Hard mode – starts at first position when hitting a wall ( dip 2 )
        • Longest path mode (longest stackarray before stack.pop (dip 4 )
        • Prints serial info, like a drawn maze
        • Pixel remapping for other displays ( Below mapping i had to use, see source sketch )

How is the maze generated?

It is generated using recursive backtracking:

Start at 0,0 mark visited, select a random direction from unvisited neighbours, push current on the stack, goto new location, and mark this visited.
Repeat until no possible directions.
pop from the stack a previous location, another direction possible? Take that path and repeat.
Repeat popping from stack, until stack empty .. now all cells are visited

longest pop : 41
maze
------------------------
|    ||    ||       || |
---            ---      
| ||    ||    ||    || |
   ------------   ---   
|       || ||    ||    |
   ---         ---   ---
|    ||    || ||       |
      ---         ---
| || || || || || ||    |

| || || || || || || || |
---
|    ||    || || || || |
   ---------   ---
|                   || |
------------------------
x y : 00
maze 4
|4|3|6|3|6|5|3|2|
|2|12|9|12|9|6|9|10|
|14|5|3|2|6|9|6|9|
|14|3|12|11|10|6|13|3|
|10|10|2|10|10|10|6|11|
|8|10|10|10|10|10|10|10|
|6|9|12|9|10|8|10|10|
|12|5|5|5|13|5|9|8|

Easiest play mode: Preview Maze, Show visited path, NO reset to square 0,0 and NOT the longest path so :

Show visited DIP1Reset to 0,0 DIP2Preview DIP3Longest path DIP4
1010

Hard mode:

Show visited DIP1Reset to 0,0 DIP2Preview DIP3Longest path DIP4
0101

Todo: Battery / batterymanager / 3D case / better buttons

Some video shorts put together to show modes

CODE

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "StackArray.h"

// Pin Assign
int up=25;
int down=33;
int left=32;
int right=26;
int trailsw=17;
int restartsw=5;
int showmazesw=18;
int popendsw=19;

int xend=7;
int yend=7;

int countpop=0;
int currentpop=0;

int directions[4]{};
int notalldone = 1;
int tmpx=0;
int tmpy=0;
int xgen = 1;
int ygen = 1;
int x = 0;
int y = 0;
int showmaze = 0;

// 0 easy = trail // 1 only red walls // 2 = reset to 0.0
int mode=0;

//int trail=32;
int trail=32;

// Which pin on the Arduino is connected to the NeoPixels?
#define LED_PIN    2

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 64

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

int maze[8][8] = {

  };

int displaymatrix[8][8] = { 
{ 0,1,2,3,4,5,6,7 },
{ 15,14,13,12,11,10,9,8 }, 
{16,17,18,19,20,21,22,23},
{31,30,29,28,27,26,25,24},
{32,33,34,35,36,37,38,39},
{47,46,45,44,43,42,41,40},
{48,49,50,51,52,53,54,55},
{63,62,61,60,59,58,57,56}
};

int visitmatrix[10][10] = { 
  1,1,1,1,1,1,1,1,1,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,1,1,1,1,1,1,1,1,1
  };


void(* resetFunc) (void) = 0;

void drawmaze2(){
  Serial.print("x y : ");
 Serial.print(x);
 Serial.println(y);
 Serial.print("maze ");
 Serial.println(maze[x][y]);
  for(int ledy=0;ledy<8;ledy++)
  { Serial.print("|");
    for(int ledx=0;ledx<8;ledx++){
    Serial.print(maze[ledx][ledy]);  
    Serial.print("|");  
    if ( maze[ledx][ledy] != 0 ) {
       // mled.dot(ledx,ledy); // draw dot
      //  mled.display();
       // delay(50);
    }
      }  
    Serial.println("");
  }
  Serial.println("");
  delay(100);
}

void drawmaze(){
  Serial.println("maze ");
 
  for(int ledy=0;ledy<8;ledy++)
  { 
    // 1st line
    for(int ledx=0;ledx<8;ledx++){
    if(bitRead(maze[ledx][ledy], 3) == 0){ Serial.print("---"); } else { Serial.print("   "); }
    }
    Serial.println("");
    // 2nd line

    for(int ledx=0;ledx<8;ledx++){
    if(bitRead(maze[ledx][ledy], 0) == 1){
        if(bitRead(maze[ledx][ledy], 2) == 1){
          Serial.print("   "); } 
          else 
          { Serial.print("  |"); }
     }
     if(bitRead(maze[ledx][ledy], 0) == 0){
        if(bitRead(maze[ledx][ledy], 2) == 1){
          Serial.print("|  "); } 
          else 
          { Serial.print("| |"); }
     }
    

    
    }
        Serial.println("");
} 
   
    // last line
    int ledy=7;
    for(int ledx=0;ledx<8;ledx++){
    if(bitRead(maze[ledx][ledy], 1) == 0){ Serial.print("---"); } else { Serial.print("   "); }
    }
    Serial.println("");

    
    
  
  //Serial.println("");
  delay(100);
}

void mazegen(){
  visitmatrix[xgen][ygen]=1;       
  StackArray <int> rowStack; 
  StackArray <int> colStack;
        rowStack.push(xgen);
        colStack.push(ygen);
  while(notalldone == 1){    
     visitmatrix[xgen][ygen]=1;
        while(!rowStack.isEmpty()) {
        int count=0;
        //up
        if ( visitmatrix[xgen-1][ygen] == 0 ){
          directions[count]=1;
          count++;    
        }
        //right
        if ( visitmatrix[xgen][ygen+1] == 0 ){
          directions[count]=2;
          count++;    
        }
        //down
        if ( visitmatrix[xgen+1][ygen] == 0 ){
          directions[count]=4;
          count++;    
        }
        //left
        if ( visitmatrix[xgen][ygen-1] == 0 ){
          directions[count]=8;
          count++;    
        }  
        if (showmaze == 1 ){ 
          strip.setPixelColor(displaymatrix[xgen-1][ygen-1], 32, 32, 32);

          strip.show();
          delay(50);
        }
        // no dir found
        if (count == 0 ) {

if (digitalRead(popendsw) == 0 ){
  currentpop = rowStack.count();
  if (currentpop > countpop ) {
    countpop = currentpop;
  xend = xgen-1;
  yend = ygen-1;
  Serial.print("longest pop : ");
  Serial.println(currentpop);
  }
}

         // mled.dot(x-1,y-1);
         // mled.display();
          xgen = rowStack.pop();
          ygen = colStack.pop();

         // Serial.println("popping ");
          } else {
          // count random direction
          int dir = directions[random(count)];
          //Serial.println("push ");
          rowStack.push(xgen); 
          colStack.push(ygen);
         // Serial.print("nr dir : "); 
         // Serial.println(count);
          //delay(100);
         // Serial.println(dir);
          // move 1,1 to 0,0
          //mled.dot(x-1,y-1);
          //mled.display();
          // set direction in maze, dit moet bit set worden
          int mybits = maze[xgen-1][ygen-1];
          int storedir = mybits | dir;
          maze[xgen-1][ygen-1] = storedir;
          if ( dir == 1){
          int getup = maze[xgen-2][ygen-1];
          int storedir = getup | 4;
          maze[xgen-2][ygen-1] = storedir;
          }
          if ( dir == 2){
          int getup = maze[xgen-1][ygen];
          int storedir = getup | 8;
          maze[xgen-1][ygen] = storedir;
          }
          if ( dir == 4){
          int getup = maze[xgen][ygen-1];
          int storedir = getup | 1;
          maze[xgen][ygen-1] = storedir;
          }
          if ( dir == 8){
          int getup = maze[xgen-1][ygen-2];
          int storedir = getup | 2;
          maze[xgen-1][ygen-2] = storedir;
          }


          
        //  maze[x-1][y-1] = dir;
          //set new square
          if (dir == 1){ xgen--; }
          if (dir == 2){ ygen++; }
          if (dir == 4){ xgen++; }
          if (dir == 8){ ygen--; }
          visitmatrix[xgen][ygen]=1;
          //drawmaze();
          }
        }
        notalldone = 0;                                                  //#2
        // if found 0 in 10x10 matrix visited, do
        for(int checkx=0;checkx<10;checkx++){
          for(int checky=0;checky<10;checky++){
            if ( visitmatrix[checkx][checky] == 0 ){
              tmpx=xgen;
              tmpy=ygen;
              notalldone = 1;  
            }
          }
        }
   }
rowStack.push(tmpx); 
colStack.push(tmpy);

}




void setup() {
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(25, INPUT_PULLUP);
  pinMode(26, INPUT_PULLUP);
  pinMode(popendsw, INPUT_PULLUP);
  pinMode(trailsw, INPUT_PULLUP);
  pinMode(restartsw, INPUT_PULLUP);
  pinMode(showmazesw, INPUT_PULLUP);
  
  Serial.begin(115200);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);

 unsigned long seed = 0;
for (int i=0; i<32; i++)
{
  seed = seed | ((analogRead(A0) & 0x01) << i);
}
randomSeed(seed);

if (digitalRead(showmazesw) == 0){
  showmaze = 1;
}


mazegen();
drawmaze();
drawmaze2();
 
 strip.fill(0, 0, 64);
  strip.show(); // Initialize all pixels to 'off'
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[xend][yend], 0, 255, 0);

  strip.show();

  x=0;
  y=0;
  
}

uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}


void reset2start() {
      strip.setPixelColor(displaymatrix[x][y], 0, 0, 0);
    strip.show();
  x = 0;
  y = 0;
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[xend][yend], 0, 255, 0);
  strip.show();

}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);

  }
}

void loop() {


if (digitalRead(trailsw) == 0 ){
  trail = 32;
} else { trail = 0; }

if (digitalRead(restartsw) == 0 ){
  mode = 2;
} else {
  mode = 0;
}
    int isUp = (bitRead(maze[x][y], 1));
    int isRight = (bitRead(maze[x][y], 2));
    int isDown = (bitRead(maze[x][y], 3));
    int isLeft = (bitRead(maze[x][y], 0));
  
//isUp = 1;
//isDown = 1;
//isLeft = 1;
//isRight = 1;

if (digitalRead(up) == 0) {
   
  if (isUp == 1){

  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y++;
     drawmaze();
  if ( y > 7) { y=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
    delay(100);
    strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(down) == 0) {
  if (isDown == 1){
   
  
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y--;
       drawmaze();

  if ( y < 0) { y=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
    delay(100);
    strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(left) == 0) {
      drawmaze();
  if (isLeft == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x--;
       drawmaze();

  if ( x < 0) { x=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
        delay(100);
    strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(right) == 0) {
      drawmaze();
  if (isRight == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x++;
       drawmaze();

  if ( x > 7) { x=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
    delay(100);
    strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (x ==xend && y == yend){
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  rainbow(20);
}

delay(200);

}

Backtracking maze generation with Arduino

As POC for the maze game.

Maze generation!

Make an initial cell the current cell
   mark it as visited
While there are unvisited cells
   If the current cell has any neighbours
   which have not been visited
         Choose randomly one of the unvisited neighbours
                Push the current cell to the stack
                Mark wall hole
                Make the chosen cell the current cell
                mark it as visited
        Else if stack is not empty
                Pop a cell from the stack
                Make it the current cell

This is my implementation of backtracking

The displaymatrix function is a implementation of different led mappings

Still have to decide where to place endpoint …
At 8,8 or at first stack pop?
Maybe both?

Code

#include <WEMOS_Matrix_LED.h>
#include <StackArray.h>

int directions[4]{};
int notalldone = 1;
int tmpx=0;
int tmpy=0;
int x = 1;
int y = 1;
MLED mled(5); //set intensity=5

int maze[8][8] = { 
  };

int displaymatrix[8][8] = { 
{ 0,1,2,3,4,5,6,7 },
{ 8,9,10,11,12,13,14,15 }, 
{16,17,18,19,20,21,22,23},
{24,25,26,27,28,29,30,31},
{32,33,34,35,36,37,38,39},
{40,41,42,43,44,45,46,47},
{48,49,50,51,52,53,54,55},
{56,57,58,59,60,61,62,63}
};

int visitmatrix[10][10] = { 
  1,1,1,1,1,1,1,1,1,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,1,
  1,1,1,1,1,1,1,1,1,1
  };

void setup() {
    Serial.begin(115200);
    randomSeed(analogRead(0));
    mazegen();
    drawmaze();
}

void mazegen(){
  visitmatrix[x][y]=1;       
  StackArray <int> rowStack; 
  StackArray <int> colStack;
        rowStack.push(x);
        colStack.push(y);
  while(notalldone == 1){    
     visitmatrix[x][y]=1;
        while(!rowStack.isEmpty()) {
        int count=0;
        //up
        if ( visitmatrix[x-1][y] == 0 ){
          directions[count]=1;
          count++;    
        }
        //right
        if ( visitmatrix[x][y+1] == 0 ){
          directions[count]=2;
          count++;    
        }
        //down
        if ( visitmatrix[x+1][y] == 0 ){
          directions[count]=4;
          count++;    
        }
        //left
        if ( visitmatrix[x][y-1] == 0 ){
          directions[count]=8;
          count++;    
        }  
        // no dir found
        if (count == 0 ) {

          mled.dot(x-1,y-1);
          mled.display();
          x = rowStack.pop();
          y = colStack.pop();

          Serial.println("popping ");
          } else {
          // count random direction
          int dir = directions[random(count)];
          Serial.println("push ");
          rowStack.push(x); 
          colStack.push(y);
          Serial.print("nr dir : "); 
          Serial.println(count);
          //delay(100);
          Serial.println(dir);
          // move 1,1 to 0,0
          mled.dot(x-1,y-1);
          mled.display();
          // set direction in maze, dit moet bit set worden
          int mybits = maze[x-1][y-1];
          int storedir = mybits | dir;
          maze[x-1][y-1] = storedir;
          if ( dir == 1){
          int getup = maze[x-2][y-1];
          int storedir = getup | 4;
          maze[x-2][y-1] = storedir;
          }
          if ( dir == 2){
          int getup = maze[x-1][y];
          int storedir = getup | 8;
          maze[x-1][y] = storedir;
          }
          if ( dir == 4){
          int getup = maze[x][y-1];
          int storedir = getup | 1;
          maze[x][y-1] = storedir;
          }
          if ( dir == 8){
          int getup = maze[x-1][y-2];
          int storedir = getup | 2;
          maze[x-1][y-2] = storedir;
          }


          
        //  maze[x-1][y-1] = dir;
          //set new square
          if (dir == 1){ x--; }
          if (dir == 2){ y++; }
          if (dir == 4){ x++; }
          if (dir == 8){ y--; }
          visitmatrix[x][y]=1;
          drawmaze();
          }
        }
        notalldone = 0;                                                  //#2
        // if found 0 in 10x10 matrix visited, do
        for(int checkx=0;checkx<10;checkx++){
          for(int checky=0;checky<10;checky++){
            if ( visitmatrix[checkx][checky] == 0 ){
              tmpx=x;
              tmpy=y;
              notalldone = 1;  
            }
          }
        }
   }
rowStack.push(tmpx); 
colStack.push(tmpy);
}



void drawmaze(){
  Serial.println("Generating done - Drawing");
  for(int ledx=0;ledx<8;ledx++)
  {
    for(int ledy=0;ledy<8;ledy++){
    Serial.print(maze[ledx][ledy]);  
    if ( maze[ledx][ledy] != 0 ) {
        mled.dot(ledx,ledy); // draw dot
        mled.display();
       // delay(50);
    }
      }  
    Serial.println("");
  }
  Serial.println("");
  delay(100);
}


void loop() {
}

Little Led Matrix Maze game

While doing stuff like, making our home a little greener. Smoking meat. Working on diorama’s and my Escape game. I found time to make this little maze game.

Using an ESP32, mini joystick and a 8×8 led matrix. The objective is to get to the other side of the invisible maze.

It is a blind maze, so you have to figure out the path by trail and error. I found it quite fun and entertaining. (Coline had a hard time finishing the mode 3 maze)

I’ve got 3 settings on the maze:
0 – There is a trail where you have been.
1 – No trail, but only red leds showing walls.
2 – No trail, red reds and a reset to square 0,0 .. so you have to remember the path you previously took.

I’ll add code and schematics tomorrow …

Light blue shows you where you have been

Mode 2 game, reset when hitting a wall

Hitting the end block!

Maze is static at the moment, i’m planning to implement a “Recursive division method” to generate the maze.

Code

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

// joystick pins
int up=33;
int down=25;
int left=32;
int right=26;
int cursor=32;

// 0 easy = trail // 1 only red walls // 2 = reset to 0.0
int mode=2;

//int trail=32;
int trail=0;

// Which pin on the Arduino is connected to the NeoPixels?
#define LED_PIN    2

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 64

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// bits set opening in square
//    2
//   -----
// 1 |   | 4
//   -----
//     0
// so 5 is a passage from left to right (1+4) 

int maze[8][8] = {
  4,5,3,6,5,5,5,3,
  6,5,11,12,5,3,6,9,
  14,1,12,5,3,10,12,1,
  12,5,5,3,10,12,5,3,
  2,6,5,9,14,5,1,10,
  10,10,6,5,9,6,5,9,
  12,11,10,6,1,10,6,1,
  4,9,12,13,5,13,13,1,
  };

int displaymatrix[8][8] = { 
{ 0,1,2,3,4,5,6,7 },
{ 15,14,13,12,11,10,9,8 }, 
{16,17,18,19,20,21,22,23},
{31,30,29,28,27,26,25,24},
{32,33,34,35,36,37,38,39},
{47,46,45,44,43,42,41,40},
{48,49,50,51,52,53,54,55},
{63,62,61,60,59,58,57,56}
};

int x = 0;
int y = 0;

void setup() {
// joy
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(25, INPUT_PULLUP);
  pinMode(26, INPUT_PULLUP);

// mode set with jumpers
  pinMode(34, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);

  Serial.begin(115200);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
// set begin and end pixel
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[7][7], 0, 255, 0);

  strip.show();
//mode select  
 if (digitalRead(34) == 0) {
 mode=0;
 if (digitalRead(35) == 0) {
 mode=2;
 } else { 
 mode=1; 
 }
// finish effect
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

// reset to start (mode 2)
void reset2start() {
      strip.setPixelColor(displaymatrix[x][y], 0, 0, 0);
    strip.show();
  x = 0;
  y = 0;
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(10);
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.setPixelColor(displaymatrix[7][7], 0, 255, 0);
  strip.show();

}
// finish effect
void rainbow(uint8_t wait) {
  uint16_t i, j;
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

void loop() {
    int isUp = (bitRead(maze[x][y], 1));
    int isRight = (bitRead(maze[x][y], 2));
    int isDown = (bitRead(maze[x][y], 3));
    int isLeft = (bitRead(maze[x][y], 0));
if (digitalRead(up) == 0) {
  if (isUp == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x++;
  if ( x > 7) { x=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(down) == 0) {
  if (isDown == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  x--;
  if ( x < 0) { x=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(left) == 0) {
  if (isLeft == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y--;
  if ( y < 0) { y=0;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();
    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (digitalRead(right) == 0) {
  if (isRight == 1){
  strip.setPixelColor(displaymatrix[x][y], 0, 0, trail);
  y++;
  if ( y > 7) { y=7;}
  strip.setPixelColor(displaymatrix[x][y], 0, 0, 255);
  strip.show();
  } else {
    strip.setPixelColor(displaymatrix[x][y], 255, 0, 0);
    strip.show();

    if (mode == 2){ 
      delay(1000);
      reset2start();
    }
  }
}
if (x ==7 && y == 7){
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  rainbow(20);
}
delay(200);

}

Old and new computer games

Only the ones i’ve played recently or having good memories playing it.
Only noteworthy games

Pyramid Mummy pharaoh thingy ??? One of the first games i remember.
(Besides Pong on a “pong-only” system)

I’ve played a Mummy game in Black/White on a XZ81 or ZX Spectrum, one of the first Computers i had access to. (Richard)
But i can´t find/remember the name.

The Sentinel (1986)

https://classicreload.com/the-sentinel.html

https://en.wikipedia.org/wiki/The_Sentinel_(video_game)

In The Sentinel, the player takes the role of a Synthoid, a telepathic robot who has to take control of a number of surreal, checkered landscapes of hills and valleys, by climbing from the lowest spot, where the hunt begins, to the highest platform, over which the Sentinel looms.

The Synthoid itself cannot move across the level; instead it can look around, accumulate energy by absorbing the objects that are scattered across the landscape, create stacks of boulders, generate inert Synthoid shells and transfer its consciousness from one of these clones to another.

Kings Quest II? (1985)

Played this with my friend Richard on his Atari ST

Few years later, same kind of Game Engine:

Leisure suit larry in the land of the lounge lizards

The Myst series (1993-)

Carmageddon

The player races a vehicle against several other computers controlled competitors in various settings, including city, mine, and industrial areas. The player has a certain amount of time to complete each race, but more time may be gained by collecting bonuses, damaging the competitors’ cars, or by running over pedestrians. Unusually for a racing game, checkpoints do not extend the time limit.

7th Guest

The 7th Guest is an interactive movie puzzle adventure game, produced by Trilobyte and originally released by Virgin Interactive Entertainment in April 1993. It is one of the first computer video games to be released only on CD-ROM. The 7th Guest is a horror story told from the unfolding perspective of the player, as an amnesiac. The game received a great amount of press attention for making live action video clips a core part of its gameplay, for its unprecedented amount of pre-rendered 3D graphics, and for its adult content. In addition, the game was very successful, with over two million copies sold. It, alongside Myst, is widely regarded as a killer app that accelerated the sales of CD-ROM drives.

DOOM and Quake

Many many hours i’ve spend playing doom with Mandy on my first network (1995?)
Quake was my Graphics Card Checker, i never made it to level two!

Amiga

Shadow of the Beast, Super Frog ,The Sentinel, Game of Thrones and Dr Mario
https://www.youtube.com/watch?v=OuGilF0TwYA

And dual player Stunt Car Racer. We played this before there were networks, using a serial cable!

Simulators and more

I used to have Microsoft Flightsim (the old version) , but my main operating system is Linux so i switched to XPlane (Windows, linux and Mac) See other posts about Flightsims

VR games

We bought VR glasses.
Besides viewing movies in 3D, playing with Blender in 3D, Xplane flightsimulator there are some games i sometimes play.

I expect you to die, WWI Warplanes, Green Hell and Mass Exodus Redux. The last one is great fun together with a PC player.

Android games

Tried several games, non stuck.
I enjoyed “SpaceTeam” the most.
Current (dorment on my phone) : Mekorama, BinaryGrid2 (Yes Nerd), Dice me and 2 Player Reactor (those last two, for playing with friends while traveling)

Arcade games

I only knew Galaga, on a table version in Germany (We played there with the Concord Pipe Band)
The other one was
Hyper Olympics by Konami ( Snackbar “Lunch” when attending school LTS Deventer )

PC Games (Recent)

Uboot, Xplane Flightsimulator,Keep talking and nobody explodes
https://store.steampowered.com/app/494840/UBOAT/

Switch Games (Recent)

Limbo, Unravel Two, Death Squared,Machinarium,Degrees of Separation, Guacamelee 2
Mostly Co-op

Sidetrack … pinball

I really like the Terminator pinball game.
There is one in Zwolle at https://computermuseum.nl/
(This one i played when i was a soldier in 1992)
I have some test setups for Virtual Pinballs, but its not the same.

“Recent” old Skool games

https://www.henriaanstoot.nl/2021/11/21/retropi-handheld/

1942 – https://en.wikipedia.org/wiki/1942_(video_game)

Metal Slug series – https://en.wikipedia.org/wiki/Metal_Slug_2

Boardgames

Don’t know what game to buy?
Head over to boardgamegeek.com

Ratings, wiki, manuals, reviews, forum and more
Get you own collection list online

Our list is here
Link https://boardgamegeek.com/collection/user/fashice

My top 5 games (at the moment) are:

  • Uboot
  • Memoir ’44
  • Monster Slaughter
  • Lord of the Rings
  • Codenames Duet

U-BOOT: The Board Game is a fully cooperative, real-time tabletop game of WW2 submarine warfare. It allows 1 to 4 players to assume the roles of the Captain, the First Officer, the Navigator, and the Chief Engineer on board of a type VIIC U-boat. The game is driven by a companion app, allowing for an unprecedented level of realism, as well as a challenging enemy A.I. which will push your skills to the limit. The action unfolds both on the strategic and the tactical scale, always demanding teamwork, efficient crew management, and quick situation assessment.

Uboot game with own 3D printed submarine with leds

Memoir ’44 is a historical boardgame where players face-off in stylized battles of some of the most famous historic battles of World War II including Omaha Beach, Pegasus Bridge, Operation Cobra and the Ardennes. The game includes over 15 different battle scenarios and features a double-sided hex game board for both beach landings and countryside combat. Each scenario mimics the historical terrain, troop placements and objectives of each army. Commanders deploy troops through Command and Tactic cards, applying the unique skills of his units — infantry, paratrooper, tank, artillery, and even resistance fighters — to their greatest strength.

Monster Slaughter is a tactical game inspired by horror movie classics, where each players takes control of a family of three monsters: father, mother and child, each with their own stats and family power. Their objective is to scour the cabin looking for five guests, find their hiding spot and “take care” of them! Each victim hides in a pile of cards that monsters must search through to find them, gathering items and traps as they do. Once revealed, a guest’s miniature is put on the board and can be attacked!

However, each player has secretly set a killing order for these guests, and killing them in order is worth more points. They can use their item cards to defend the guests against other monsters or scare the victims away to other rooms, so the guests die in a more favorable order!

Monster Slaughter

Some DIY own build games are:
Shogi (Japanese Chess)
https://www.henriaanstoot.nl/2012/05/31/shogi-game-lasercut/
Crokinole (Canadian game)
https://www.henriaanstoot.nl/2018/06/14/made-a-crokinole-game/

Started on a mobile over the internet Escape room experiment

I’ve been working on some modular gadgets which can be combined to make a complete puzzle.

I like games like Keep-talking-and-nobody-dies. (Which is a computer game, but you have to play it with multiple persons and a physical “manual” Great fun!)
https://keeptalkinggame.com/

And i like real escape rooms.
There are some puzzle “rooms” you can buy in the game store, it is okay but many are for single use only.

I’ve been following some people on youtube, i saw some great ideas but not a remote over the internet using physical knobs and switches.

This is a RFID reader with an old Amico Esp8266 Arduino. It sends RFID information to the MQTT broker

Some other tools ‘n knobs .. and stuff

I want to use Adhoc Wifi and a Mqtt/Nodered setup which uses a mqtt over the internet to get people (and their knobs) connected

I already got a lot of test schematics

Left part of the “connect the wires puzzle” right a solenoid electrical lock)

Schematic for the MQTT enabled RFID module

ESP8266 <-> RC522
D8            SDA
D5            SCK
D7           MOSI
D6           MISO
GND           GND
D1            RST
3V3           3V3
 

Code

Below will write the RFID id to “rfid/id” and resets this when you remove the tag to “rfid/id = 0”

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <MFRC522.h>

#define SS_PIN D8
#define RST_PIN D1

MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long cardId = 0;

WiFiClient net;
PubSubClient client(net);

const char* mqtt_server = "MQTTBROKER";
const char* ssid = "MYSSID";
const char* password = "MYWIFIPASSWD";

void setup() {
  SPI.begin();
  mfrc522.PCD_Init();

  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

  client.setServer(mqtt_server, 1883);
}

void reconnect() {
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
  }

  while (!client.connected()) {
    String clientId = "NodeMCUClient-";
    clientId += String(random(0xffff), HEX);

    if (!client.connect(clientId.c_str(), "rfidclient", "...")) {
      delay(5000);
    }
  }
}

void loop() {
  reconnect();

  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  cardId = getCardId();

  char buffer[10];
  sprintf(buffer, "%lu", cardId);
  client.publish("rfid/id", buffer);

  uint8_t control = 0x00;

  do {
    control = 0;
    for (int i = 0; i < 3; i++) {
      if (!mfrc522.PICC_IsNewCardPresent()) {
        if (mfrc522.PICC_ReadCardSerial()) {
          control |= 0x16;
        }

        if (mfrc522.PICC_ReadCardSerial()) {
          control |= 0x16;
        }
        control += 0x1;
      }
      control += 0x4;
    }

    delay(0);
  } while (control == 13 || control == 14);

  reconnect();
  client.publish("rfid/id", "0");
  delay(500);

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

unsigned long getCardId() {
  byte readCard[4];
  for (int i = 0; i < 4; i++) {
    readCard[i] = mfrc522.uid.uidByte[i];
  }

  return (unsigned long)readCard[0] << 24
    | (unsigned long)readCard[1] << 16
    | (unsigned long)readCard[2] << 8
    | (unsigned long)readCard[3];
}

Schematics used for the Solenoid lock

Software is a mqtt example from the internet which toggles a PIN on the arduino.