Vier gewinnt auf dem U 64 LED Matrix Panel

Meanwhile, a lively exchange of information via email with our customer Mr. Küster has developed, whom we owe the electronic hourglass. He has currently a lot of time to program his Micro Controller and this time he has programmed the game "connect four" for two players on the U 64 LED Matrix Panel CJMCU-8 * 8 module with rgbleds. For the experimental setup I had all parts at home. So I tried out right away.

4 wins

Hardware used

1

Nano V3.0 with FT232RL chip and atmega328

Or: Nano V3.0 with Atmega328 CH340

Alternatively: Micro Controller with Atmega 328P

1

U 64 LED Matrix Panel CJMCU-8 * 8 module 

Breadboard (Breadboard), 3 Button and Cable (Jumper Wire)


hardware

For the manufactured finished set you still need:

1

casing

1

Battery pack

1

LM2596S DC-DC Power Adapter Step Down Module


Here is the circuit diagram:

circuit diagram
As so often, the programmers of the New York company Adafruit  worked out  the most difficult part of hardware-close programming and provided a Library for the LED display Available on GitHub or via the library manager. Therefore, we will insert this library at the beginning of the sketch with  #include .
If not yet happened, please enter Neopixel in the search window of the library administrator (already installed with me).

Library administrator

Neopixels are as often a library for a variety of RGBLED displays that have something in common in spite of a wide variety of designs: In addition to the power supply, there is a single data line that controls the one behind the other RGBLEDs. With the lines

 int number = 64;
 Adafruit_neaopixel strip(number, 6, Neo_grb + Neo_khz800);

we therefore instantiate our 8x8 module.

For the playing field are eight columns and seven rows available, because the top line is required for the positioning of the next "token". Red begins. The top, left LED lights red and can be moved with the two buttons for links (to GPIO9) and right (to GPIO10) accordingly. The train is completed with the middle button (to GPIO8). The luminous point migrates so far down, as free fields are available.

After the test routine, whether a player has already reached four equally colored fields horizontally, vertical or diagonally, a green LED appears on top left and the second player makes his move in the same way. Then we see again a red LED back on the top left, etc.

When the test routine comes to a positive result, the four RGBLEDs are first flashing, then the entire display in the colors of the winner. Then the Micro Controller is ready for the next round. To end the game prematurely, press both directional sheets at the same time.

Here the sketch throughout and as Download:

 #include 
 int number = 64;
 Adafruit_neaopixel strip(number, 6, Neo_grb + Neo_khz800);
 
 long Red = strip.Color(5, 0, 0); long green = strip.Color(0, 5, 0); long colour = 0;
 byte zw1 = 0; int Zw2 = 0; // are used in "Output Spielfeld"
 byte zw3 = 0; // is used in lowering the game stones
 byte zw4 = 0; // Startup field when testing
 byte ZW5 = 0; // Zaelwert Inner Loop, tests 4 fields
 byte zw6 = 0; // zaelwert middle loop, tests a column
 byte zw7 = 0; // zael value of the outer loop, tests all columns
 byte zw8 = 0; // fallen stones
 byte zwart = 0; // edition winner color
 byte ZW10 = 0; // Loeschen Display and playing field
 byte SW11 = 0; // blinking winning stones
 long color_1 = 0; long color_2 = 0; // winning color
 byte position 1 = 0; byte Position_2 = 0; byte Position_3 = 0; byte Position_4 = 0; // position winners
 
 // 0 -> Not used; 1 -> red; 2 -> green
 byte matchfield [64] = {
   1, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0
 };
 
 byte right = 10; byte Left = 9; byte down = 8; // number of the necessary amount Ports
 
 byte direction = 0 ; // 1 -> right; 2 -> left; 3 -> down
 byte status_start = 1; // 1 -> red; 2 -> green
 byte status_spiel = 1 ; // 1 -> red; 2 -> green
 byte position_0 = 0; // pointer for the field
 byte test_rot = 0; byte test_gruen = 0; byte winner = 0; // Requires to determine the winner
 
 void set up() {
 
   Serial.begin(9600);
 
   strip.begin();
   strip.show(); // Initialize all pixels to 'off'
 
   pinMode(right, INPUT); digitalWrite (right, HIGH);
   pinMode(Left, INPUT); digitalWrite (Left, HIGH);
   pinMode(down, INPUT); digitalWrite (down, HIGH);
 
   ausgabe_spielfeld ();
 }
 
 void loop() {
 
   // query keyboard and jump into corresponding program
   do {
     
     if (digital read(right) == LOW && digital read(Left) == LOW) {
       zw8 = 56;
       test_spielende ();
    };
     if ( digital read(right) == LOW) {
       direction = 1; rechts_0 ();
    }
     if ( digital read(Left) == LOW) {
       direction = 2; links_0 ();
    }
     if ( digital read(down) == LOW) {
       if (matchfield [position_0 + 8] == 0) {
         direction = 3;
         runter_0 (); zw8 ++; // Number Durchlaeufe + 1
         test_spielende ();
      };
    }
  }
   while ( direction == 0);
   direction = 0; // Loesch Ender direction
 
 
   ausgabe_spielfeld ();
   delay(300);
 }
 
 // ------------- test whether there is a winner ------------------
 // ---------- program is called after lowering a stone
 void test_spielende () {
 
   // ----------- ------------ Test diagonally above
   // ---------- ---------- 3 verschaltelte cycles
 
   zw4 = 32; // Startup field when testing
   winner = 0; zw7 = 0;
 
   do {
     zw6 = 0;
 
     do {
       ZW5 = 0; // Zaelschleife
       test_rot = 0; test_gruen = 0;
 
       // Test 4 cells diegonal above
       do {
         if ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         if ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Note the position of the victory
         if (winner == 0) {
           if (ZW5 == 0) {
             position 1 = zw4;
          };
           if (ZW5 == 1) {
             Position_2 = zw4;
          };
           if (ZW5 == 2) {
             Position_3 = zw4;
          };
           if (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 - 7; ZW5++;
      }
       while (ZW5 != 4);
 
       if (test_rot == 4) {
         winner = 1;
      } Else {
         test_rot = 0;
      };
       if (test_gruen == 4) {
         winner = 2;
      } Else {
         test_gruen = 0;
      };
       zw4 = zw4 + 36; zw6++;
       if (winner != 0) {
         zw6 = 4;
      };
    }
     while ( zw6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     if (winner != 0) {
       zw7 = 5;
    };
  }
   while (zw7 != 5);
 
   // ----------- ----------- Test diagonally down
   // ---------- ---------- 3 nested cycles
 
   zw4 = 8; // Startup field when testing
   zw7 = 0;
 
   do {
     zw6 = 0;
 
     do {
       ZW5 = 0; // counting loop
       test_rot = 0; test_gruen = 0;
 
       // testing cells 4 diagonally downward
       do {
         if ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         if ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Note the position of the victory
         if (winner == 0) {
           if (ZW5 == 0) {
             position 1 = zw4;
          };
           if (ZW5 == 1) {
             Position_2 = zw4;
          };
           if (ZW5 == 2) {
             Position_3 = zw4;
          };
           if (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 + 9; ZW5++;
      }
       while (ZW5 != 4);
 
       if (test_rot == 4) {
         winner = 1;
      } Else {
         test_rot = 0;
      };
       if (test_gruen == 4) {
         winner = 2;
      } Else {
         test_gruen = 0;
      };
       zw4 = zw4 - 28; zw6++;
       if (winner != 0) {
         zw6 = 4;
      };
    }
     while ( zw6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     if (winner != 0) {
       zw7 = 5;
    };
  }
   while (zw7 != 5);
 
   // ------------ test perpendicular ---------------
   // ---------- ---------- 3 verschaltelte cycles
 
   zw4 = 8; // Startup field when testing
   zw7 = 0;
   do {
     zw6 = 0;
 
     do {
       ZW5 = 0; // zaelschleife
       test_rot = 0; test_gruen = 0;
 
       // testing 4 cells perpendicular
       do {
         if ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         if ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Note the position of the victory
         if (winner == 0) {
           if (ZW5 == 0) {
             position 1 = zw4;
          };
           if (ZW5 == 1) {
             Position_2 = zw4;
          };
           if (ZW5 == 2) {
             Position_3 = zw4;
          };
           if (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 + 8; ZW5++;
      }
       while (ZW5 != 4);
 
       if (test_rot == 4) {
         winner = 1;
      } Else {
         test_rot = 0;
      };
       if (test_gruen == 4) {
         winner = 2;
      } Else {
         test_gruen = 0;
      };
       zw4 = zw4 - 24; zw6++;
       if (winner != 0) {
         zw6 = 4;
      };
    }
     while ( zw6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     if (winner != 0) {
       zw7 = 8;
    };
  }
   while (zw7 != 8);
 
   // ------------- -------------- Test level
   // ---------- ---------- 3 nested cycles
   zw4 = 8; // Startup field when testing
   zw7 = 0;
   do {
     zw6 = 0;
 
     do {
       ZW5 = 0;
       test_rot = 0; test_gruen = 0;
 
       // Test 4 cells horizontally
       do {
         if ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         if ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Note the position of the victory
         if (winner == 0) {
           if (ZW5 == 0) {
             position 1 = zw4;
          };
           if (ZW5 == 1) {
             Position_2 = zw4;
          };
           if (ZW5 == 2) {
             Position_3 = zw4;
          };
           if (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4++; ZW5++;
      }
       while (ZW5 != 4);
 
       if (test_rot == 4) {
         winner = 1;
      } Else {
         test_rot = 0;
      };
       if (test_gruen == 4) {
         winner = 2;
      } Else {
         test_gruen = 0;
      };
       zw4 = zw4 + 4; zw6++;
       if (winner != 0) {
         zw6 = 7;
      };
    }
     while ( zw6 != 7);
 
     zw4 = zw4 - 55; zw7++;
     if (winner != 0) {
       zw7 = 5;
    };
  }
   while (zw7 != 5);
 
   // set winner colors
   if (winner == 1) {
     color_1 = Red;
     color_2 = Red;
     The End (); // Output winner Red
  };
   if (winner == 2) {
     color_1 = green;
     color_2 = green;
     The End (); // Output winner Color Green
  };
   if (zw8 == 56 ) {
     color_1 = green;
     color_2 = Red;
     The End (); // prints draw
  };
 
   position 1 = 0; Position_2 = 0; Position_3 = 0; Position_4 = 0;
   test_rot = 0; test_gruen = 0;
 }
 
 // ---------- ---------- Color Edition Winners
 
 void The End () {
   SW11 = 0;
 
   if (zw8 != 56 ) {
     do {
       strip.setPixelColor ( position 1, 0, 0, 0);
       strip.setPixelColor ( Position_2, 0, 0, 0);
       strip.setPixelColor ( Position_3, 0, 0, 0);
       strip.setPixelColor ( Position_4, 0, 0, 0);
       strip.show(); delay(200);
       strip.setPixelColor ( position 1, color_1);
       strip.setPixelColor ( Position_2, color_1);
       strip.setPixelColor ( Position_3, color_1);
       strip.setPixelColor ( Position_4, color_1);
       strip.show(); delay(200);
       SW11++;
    }
     while ( SW11 != 5);
  }
 
   zwart = 0;
   do {
     strip.setPixelColor ( zwart, color_1); zwart++;
     strip.setPixelColor ( zwart, color_2); zwart++;
  }
   while (zwart != 64);
   strip.show();
 
   delay(2000);
 
   // ---------- ----------- preparing new start
 
   ZW10 = 0;
   do {
     strip.setPixelColor ( ZW10, 0, 0, 0); matchfield [ZW10] = 0;
     ZW10++;
  }
   while ( ZW10 != 64);
   strip.show();
 
   matchfield [0] = 1; ausgabe_spielfeld ();
   zw1 = 0; Zw2 = 0; zw3 = 0; zw4 = 0; ZW5 = 0; zw6 = 0; zw7 = 0; zw8 = 0; zwart = 0; ZW10 = 0;
   position 1 = 0; Position_2 = 0; Position_3 = 0; Position_4 = 0;
   position_0 = 0;
 
   // change Start game Color
   color_1 = 0; color_2 = 0; winner = 0;  
 
   if (status_start == 1) {
     colour = green; status_spiel = 2;status_start=2;
     matchfield [0] = 2;
  } Else {
     colour = Red;
     matchfield [0] = 1; status_spiel = 1;status_start=1;
  };
   
   ausgabe_spielfeld ();
 }
 
 // ---------- ---------- One step left
 void links_0 () {
   if (position_0 != 0) {
     matchfield [position_0] = 0;
     position_0--;
     matchfield [ position_0 ] = status_spiel;
  };
 }
 
 // ---------- ---------- A step to the right
 void rechts_0 () {
   if (position_0 != 7) {
     matchfield [position_0] = 0;
     position_0++;
     matchfield [ position_0 ] = status_spiel;
  };
 }
 
 // ---------- ---------- lowering the playing piece
 void runter_0 () {
   zw3 = 0;
   do {
     if (matchfield [position_0 + 8] == 0 ) {
       matchfield [position_0] = 0; position_0 = position_0 + 8; matchfield [position_0] = status_spiel;
       zw3++;
       ausgabe_spielfeld (); delay(200);
    }
     Else {
       zw3 = 7;
    }
  }
   while (zw3 != 7) ;
   direction = 0; position_0 = 0;
   if (status_spiel == 1 ) {
     status_spiel = 2;
     matchfield [position_0] = 2;
  } Else {
     status_spiel = 1;
     matchfield [position_0] = 1;
  };
   ausgabe_spielfeld ();
 }
 
 // ---------- ---------- output field
 void ausgabe_spielfeld () {
   zw1 = 0;
 
   do {
     Zw2 = matchfield [zw1];
     if (Zw2 == 0) {
       strip.setPixelColor ( zw1, 0, 0, 0);
    };
     if (Zw2 == 1) {
       strip.setPixelColor ( zw1, Red);
    };
     if (Zw2 == 2) {
       strip.setPixelColor ( zw1, green);
    };
     zw1++;
  }
   while (zw1 != 64);
   strip.show();
 }
 
 // HUK Vier_gewinnt_4.4 07/27/2021

Alternatively, you can play four wins on the Wall housing AZ-Touch. This possibility had Jörn Weise presented in his Blog on July 3, 2021.

Both presented versions are designed for two players and offer both, the beautiful display and the test routine, if a player already has won. For those, who want to play against a strong playing computer, the version of Al Sweigart on the Raspberry Pi is recommended. I must confess to my shame that I lose every now and then. So rather play with the sketch of Mr. Küster on the U 64 LED Matrix Panel CJMCU-8 * 8 module  against my granddaughter?


Have fun reading and playing.

DisplaysFor arduinoProjects for beginners

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN