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.
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 |
||
Breadboard (Breadboard), 3 Button and Cable (Jumper Wire) |
For the manufactured finished set you still need:
1 |
casing |
|
1 |
Battery pack |
|
1 |
Here is the 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).
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:
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.