From 8a4bd077f0cead0d26ad53201595d25c6b0598d8 Mon Sep 17 00:00:00 2001 From: Elwin Hammer Date: Tue, 21 May 2024 20:29:03 +0200 Subject: Update editorconfig.wxl, arduino-neopuzzle.ino, and neo.cpp --- editorconfig.wxl | 12 +++ puzzle/neo/arduino-neopuzzle/arduino-neopuzzle.ino | 101 +++++++++++++++++++++ puzzle/neo/console-neopuzzle/neo.cpp | 100 ++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 editorconfig.wxl create mode 100644 puzzle/neo/arduino-neopuzzle/arduino-neopuzzle.ino create mode 100644 puzzle/neo/console-neopuzzle/neo.cpp diff --git a/editorconfig.wxl b/editorconfig.wxl new file mode 100644 index 0000000..cd37156 --- /dev/null +++ b/editorconfig.wxl @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +insert_final_newline = true + +[*.md] +indent_style = space +indent_size = 2 + + diff --git a/puzzle/neo/arduino-neopuzzle/arduino-neopuzzle.ino b/puzzle/neo/arduino-neopuzzle/arduino-neopuzzle.ino new file mode 100644 index 0000000..df9d6fb --- /dev/null +++ b/puzzle/neo/arduino-neopuzzle/arduino-neopuzzle.ino @@ -0,0 +1,101 @@ +#include +#include + +#define MATRIX_SIZE 8 +#define INT_PIN 5 // Interrupt pin for the NeoTrellis +#define LED_COLOR_ON 0xFFFFFF // Color of the LEDs in ON state +#define LED_COLOR_OFF 0x000000 // Color of the LEDs in OFF state + +enum NeoState { + NEO_UNINITIALIZED, + NEO_PLAYING, + NEO_SOLVED +}; + +Adafruit_NeoTrellis trellis; +NeoState neoState = NEO_UNINITIALIZED; + +// Initialize the NeoTrellis matrix +void initializeNeoMatrix() { + if (!trellis.begin()) { + Serial.println("Failed to initialize NeoTrellis"); + while (1); // Hold here if initialization fails + } + + // Set all buttons to listen for presses and releases + for (int i = 0; i < MATRIX_SIZE; i++) { + for (int j = 0; j < MATRIX_SIZE; j++) { + trellis.activateKey(i * MATRIX_SIZE + j, SEESAW_KEYPAD_EDGE_RISING, true); + trellis.activateKey(i * MATRIX_SIZE + j, SEESAW_KEYPAD_EDGE_FALLING, true); + trellis.pixels.setPixelColor(i * MATRIX_SIZE + j, LED_COLOR_OFF); // Turn off LED + } + } + trellis.pixels.show(); + neoState = NEO_PLAYING; +} + +// Callback to handle button presses +void buttonCallback(keyEvent evt) { + uint8_t i = evt.bit.NUM / MATRIX_SIZE; + uint8_t j = evt.bit.NUM % MATRIX_SIZE; + + // Toggle the central button and adjacent LEDs + toggleAdjacentLEDs(i, j); + if (isNeoPuzzleSolved()) { + neoState = NEO_SOLVED; + Serial.println("The NeoTrellis puzzle is solved!"); + // Additional actions upon solving the puzzle can go here + } + trellis.pixels.show(); +} + +void toggleAdjacentLEDs(int x, int y) { + int idx = x * MATRIX_SIZE + y; + trellis.pixels.setPixelColor(idx, trellis.pixels.getPixelColor(idx) ^ LED_COLOR_ON); // Toggle LED color + + // Toggle adjacent LEDs + if (x > 0) trellis.pixels.setPixelColor((x-1) * MATRIX_SIZE + y, trellis.pixels.getPixelColor((x-1) * MATRIX_SIZE + y) ^ LED_COLOR_ON); + if (x < MATRIX_SIZE - 1) trellis.pixels.setPixelColor((x+1) * MATRIX_SIZE + y, trellis.pixels.getPixelColor((x+1) * MATRIX_SIZE + y) ^ LED_COLOR_ON); + if (y > 0) trellis.pixels.setPixelColor(x * MATRIX_SIZE + (y-1), trellis.pixels.getPixelColor(x * MATRIX_SIZE + (y-1)) ^ LED_COLOR_ON); + if (y < MATRIX_SIZE - 1) trellis.pixels.setPixelColor(x * MATRIX_SIZE + (y+1), trellis.pixels.getPixelColor(x * MATRIX_SIZE + (y+1)) ^ LED_COLOR_ON); +} + +bool isNeoPuzzleSolved() { + for (int i = 0; i < MATRIX_SIZE; i++) { + for (int j = 0; j < MATRIX_SIZE; j++) { + if (trellis.pixels.getPixelColor(i * MATRIX_SIZE + j) != LED_COLOR_OFF) return false; // If any LED is on, puzzle is not solved + } + } + return true; +} + +// Declare a wrapper function that will call your actual callback +void buttonCallbackWrapper(keyEvent evt) { + buttonCallback(evt); +} + +// Adjust the toTrellisCallback function to directly return the wrapper +TrellisCallback toTrellisCallback(void (*callback)(keyEvent)) { + return buttonCallbackWrapper; +} + +void setup() { + Serial.begin(115200); + trellis.begin(INT_PIN); + trellis.pixels.setBrightness(50); // Set brightness of LEDs (0-255) + initializeNeoMatrix(); + + // Register the callback for each key + for (int i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++) { + // Directly use the wrapper function here as the callback is static and does not need conversion + trellis.registerCallback(i, buttonCallbackWrapper); + } +} + + +void loop() { + if (neoState == NEO_PLAYING) { + trellis.read(); // Handle any button events + trellis.pixels.show(); // Update the display + } +} diff --git a/puzzle/neo/console-neopuzzle/neo.cpp b/puzzle/neo/console-neopuzzle/neo.cpp new file mode 100644 index 0000000..56d90f7 --- /dev/null +++ b/puzzle/neo/console-neopuzzle/neo.cpp @@ -0,0 +1,100 @@ +#include +#include + +#define MATRIX_SIZE 8 + +enum NeoState { + NEO_UNINITIALIZED, + NEO_PLAYING, + NEO_SOLVED +}; + +// Simulate the 8x8 LED matrix with a 2D array +std::array, MATRIX_SIZE> neoMatrix; + +NeoState neoState = NEO_UNINITIALIZED; + +// Helper function to toggle LEDs if within bounds +void toggleIfValid(int x, int y) { + if (x >= 0 && x < MATRIX_SIZE && y >= 0 && y < MATRIX_SIZE) { + neoMatrix[x][y] = !neoMatrix[x][y]; + } +} + +void initializeNeoMatrix() { + // The initial pattern from the Appendix A example (assuming red is 'true'/on and white is 'false'/off) + std::array, MATRIX_SIZE> initialPattern = {{ + {false, true, false, true, false, true, false, true}, + {true, false, true, false, true, false, true, false}, + {false, true, false, true, false, true, false, true}, + {true, false, true, false, true, false, true, false}, + {false, true, false, true, false, true, false, true}, + {true, false, true, false, true, false, true, false}, + {false, true, false, true, false, true, false, true}, + {true, false, true, false, true, false, true, false} + }}; + + for (int i = 0; i < MATRIX_SIZE; i++) { + for (int j = 0; j < MATRIX_SIZE; j++) { + neoMatrix[i][j] = initialPattern[i][j]; + } + } + + neoState = NEO_PLAYING; +} + + +void printNeoMatrix() { + // Print the matrix state to the console + for (int i = 0; i < MATRIX_SIZE; i++) { + for (int j = 0; j < MATRIX_SIZE; j++) { + std::cout << (neoMatrix[i][j] ? 1 : 0) << " "; + } + std::cout << std::endl; + } +} + +void toggleAdjacentLEDs(int x, int y) { + // Toggle the LED at (x, y) and adjacent LEDs + toggleIfValid(x, y); // Center + toggleIfValid(x - 1, y); // Up + toggleIfValid(x + 1, y); // Down + toggleIfValid(x, y - 1); // Left + toggleIfValid(x, y + 1); // Right +} + + +bool isNeoPuzzleSolved() { + for (int i = 0; i < MATRIX_SIZE; i++) { + for (int j = 0; j < MATRIX_SIZE; j++) { + if (neoMatrix[i][j]) return false; // If any LED is on, puzzle is not solved + } + } + return true; +} + +/// Integration needed +int main() { + initializeNeoMatrix(); + printNeoMatrix(); + + while (neoState != NEO_SOLVED) { + int x, y; + std::cout << "Enter the coordinates of the button pressed (x y): "; + std::cin >> x >> y; + + if (x >= 0 && x < MATRIX_SIZE && y >= 0 && y < MATRIX_SIZE) { + toggleAdjacentLEDs(x, y); + printNeoMatrix(); + + if (isNeoPuzzleSolved()) { + neoState = NEO_SOLVED; + std::cout << "The NeoTrellis puzzle is solved!\n"; + } + } else { + std::cout << "Invalid coordinates. Please enter values between 0 and " << MATRIX_SIZE - 1 << ".\n"; + } + } + + return 0; +} -- cgit v1.2.3