aboutsummaryrefslogtreecommitdiff
path: root/puzzle/vault
diff options
context:
space:
mode:
authorElwin Hammer <elwinhamer@gmail.com>2024-05-21 20:52:34 +0200
committerElwin Hammer <elwinhamer@gmail.com>2024-05-21 20:52:34 +0200
commita407d920293ebc1d442abcc5bb4e43fc8a6cbe65 (patch)
treed8b547abd753c9b28bd516bf6f68817e560e6b81 /puzzle/vault
parentb73a609fad2a8e97ed9e708d9d91258b9ac1831c (diff)
Feedback applied
Diffstat (limited to 'puzzle/vault')
-rw-r--r--puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino129
-rw-r--r--puzzle/vault/console-vaultpuzzle/vault.cpp130
2 files changed, 259 insertions, 0 deletions
diff --git a/puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino b/puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino
new file mode 100644
index 0000000..977fc01
--- /dev/null
+++ b/puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino
@@ -0,0 +1,129 @@
+#include <Wire.h>
+
+// Definitions for GPIO numbers, change these according to your hardware setup
+#define TOTAL_LEVELS 5
+#define TAG "VaultPuzzle"
+
+// Define the I2C slave address
+#define I2C_SLAVE_ADDR 0x40 // Replace 0x40 with your actual I2C slave device address
+
+// Key Matrix Pin Configuration
+#define ROWS 4
+#define COLS 3
+
+//TODO Update these pin numbers based on your Arduino setup
+const int ROW_PINS[ROWS] = {32, 33, 25, 26};
+const int COL_PINS[COLS] = {27, 14, 12};
+
+typedef enum {
+ STATE_UNINITIALIZED = 0x00,
+ STATE_RESET = 0x01,
+ STATE_PLAYING = 0x02,
+ STATE_SOLVED = 0x03,
+} PuzzleState;
+
+const char* validButtons[TOTAL_LEVELS] = {"A3", "F1", "U4", "C2", "L1"};
+PuzzleState puzzleState = STATE_UNINITIALIZED;
+int currentLevel = 0;
+
+// Function prototypes
+void send_i2c_update(PuzzleState state);
+void display_code(int level);
+void initialize_system();
+void check_button_press();
+void update_state_after_button_press(bool validPress);
+
+void setup() {
+ Serial.begin(115200);
+ Wire.begin(); // Initialize I2C as master
+ initialize_system();
+ Serial.println("GPIO and I2C initialized.");
+}
+
+void initialize_system() {
+ // Configure the rows as input with pull-up
+ for (int i = 0; i < ROWS; i++) {
+ pinMode(ROW_PINS[i], INPUT_PULLUP);
+ }
+
+ // Configure the columns as output
+ for (int i = 0; i < COLS; i++) {
+ pinMode(COL_PINS[i], OUTPUT);
+ digitalWrite(COL_PINS[i], HIGH);
+ }
+}
+
+void loop() {
+ while (puzzleState != STATE_SOLVED) {
+ check_button_press();
+ delay(100); // Non-blocking delay
+ }
+}
+
+void send_i2c_update(PuzzleState state) {
+ uint8_t data;
+ switch (state) {
+ case STATE_UNINITIALIZED: data = STATE_UNINITIALIZED; break;
+ case STATE_RESET: data = STATE_RESET; break;
+ case STATE_PLAYING: data = STATE_PLAYING; break;
+ case STATE_SOLVED: data = STATE_SOLVED; break;
+ default: data = 0xFF; // Unknown state
+ }
+ Serial.print("Sending state "); Serial.println(state);
+
+ Wire.beginTransmission(I2C_SLAVE_ADDR);
+ Wire.write(data);
+ byte error = Wire.endTransmission();
+
+ if (error == 0) {
+ Serial.println("State update sent successfully.");
+ } else {
+ Serial.println("Failed to send state update via I2C.");
+ }
+}
+
+void display_code(int level) {
+ Serial.print("Displaying code for level "); Serial.println(level);
+
+ Wire.beginTransmission(I2C_SLAVE_ADDR);
+ Wire.write(level);
+ byte error = Wire.endTransmission();
+
+ if (error == 0) {
+ Serial.print("Code for level "); Serial.print(level); Serial.println(" displayed successfully.");
+ } else {
+ Serial.print("Failed to display code for level "); Serial.print(level); Serial.println(" via I2C.");
+ }
+}
+
+void check_button_press() {
+ char keyPress[3] = {0};
+ for (int col = 0; col < COLS; col++) {
+ digitalWrite(COL_PINS[col], LOW); // Activate column
+ for (int row = 0; row < ROWS; row++) {
+ if (digitalRead(ROW_PINS[row]) == LOW) { // Detect if any row is activated
+ keyPress[0] = 'A' + row;
+ keyPress[1] = '1' + col;
+ keyPress[2] = '\0';
+ Serial.print("Keypress detected: "); Serial.println(keyPress);
+ update_state_after_button_press(strcmp(keyPress, validButtons[currentLevel]) == 0);
+ while (digitalRead(ROW_PINS[row]) == LOW) {} // Wait for release
+ }
+ }
+ digitalWrite(COL_PINS[col], HIGH); // Deactivate column
+ }
+}
+
+void update_state_after_button_press(bool validPress) {
+ if (validPress) {
+ if (currentLevel >= TOTAL_LEVELS) {
+ puzzleState = STATE_SOLVED;
+ Serial.println("Puzzle solved!");
+ send_i2c_update(puzzleState);
+ } else {
+ puzzleState = STATE_PLAYING;
+ currentLevel++;
+ display_code(currentLevel);
+ }
+ }
+}
diff --git a/puzzle/vault/console-vaultpuzzle/vault.cpp b/puzzle/vault/console-vaultpuzzle/vault.cpp
new file mode 100644
index 0000000..3566b3e
--- /dev/null
+++ b/puzzle/vault/console-vaultpuzzle/vault.cpp
@@ -0,0 +1,130 @@
+#include <iostream>
+#include <string>
+#include <array>
+
+// Definitions for puzzle requirements
+constexpr int TOTAL_LEVELS = 5;
+
+// Enumeration for the states of the puzzle
+enum PuzzleState {
+ STATE_UNINITIALIZED,
+ STATE_RESET,
+ STATE_PLAYING,
+ STATE_SOLVED,
+ STATE_ERROR
+};
+
+// This array maps each level to the correct button press
+const std::array<std::string, TOTAL_LEVELS> validButtons = {"A3", "F1", "U4", "C2", "L1"};
+
+PuzzleState puzzleState = STATE_UNINITIALIZED;
+int currentLevel = 0;
+
+// Function prototypes
+void displayCode(int level);
+void sendI2CUpdate(PuzzleState state);
+
+// Simulate sending an I2C update
+void sendI2CUpdate(PuzzleState state) {
+ std::cout << "Sending state " << state << " to main controller via I2C.\n";
+}
+
+// Simulate checking if the vault door is closed
+bool isVaultClosed() {
+ return true; // Return true if the door sensor indicates closed
+}
+
+// Function to display a code on the 7-segment display
+void displayCode(int level) {
+ std::cout << "Displaying code for level " << level << " on the 7-segment display.\n";
+}
+
+// Function to initialize the puzzle
+void initializePuzzle() {
+ if (isVaultClosed()) {
+ puzzleState = STATE_RESET;
+ currentLevel = 1; // Start at level 1
+ std::cout << "Puzzle initialized. Starting at level " << currentLevel << ".\n";
+ displayCode(currentLevel); // Show the first code
+ } else {
+ std::cout << "Vault door is open. Please close the door to start the puzzle.\n";
+ }
+}
+
+// Function to lock the vault
+void lockVault() {
+ std::cout << "Vault locked.\n";
+}
+
+// Function to unlock the vault
+void unlockVault() {
+ std::cout << "Vault unlocked!\n";
+}
+
+// Function to simulate the buzzer sound
+void playErrorSound() {
+ std::cout << "Playing error sound.\n";
+}
+
+// Function to simulate blinking the 7-segment display
+void blinkDisplay() {
+ std::cout << "7-segment display is blinking to indicate an error.\n";
+}
+
+// Validate the button press for the current level
+bool isValidButtonPress(const std::string& button, int level) {
+ return button == validButtons[level - 1];
+}
+
+// Function to update the state of the puzzle based on the current level
+void updateStateAfterButtonPress(bool validPress) {
+ if (validPress) {
+ if (currentLevel >= TOTAL_LEVELS) {
+ puzzleState = STATE_SOLVED;
+ unlockVault();
+ } else {
+ puzzleState = STATE_PLAYING;
+ displayCode(currentLevel);
+ }
+ } else {
+ puzzleState = STATE_ERROR;
+ playErrorSound();
+ blinkDisplay();
+ lockVault();
+ currentLevel = 1; // Reset to level 1
+ displayCode(currentLevel);
+ }
+ sendI2CUpdate(puzzleState); // Notify main controller of the state change
+}
+
+int main() {
+ initializePuzzle();
+
+ std::string buttonInput;
+
+ while (puzzleState != STATE_SOLVED) {
+ std::cout << "Enter the button pressed for level " << currentLevel << " (format Xn, e.g., A3): ";
+ std::getline(std::cin, buttonInput);
+
+ if (!buttonInput.empty() && isValidButtonPress(buttonInput, currentLevel)) {
+ currentLevel++;
+ if (currentLevel > TOTAL_LEVELS) {
+ puzzleState = STATE_SOLVED;
+ unlockVault();
+ std::cout << "The puzzle is solved and the vault is open!\n";
+ } else {
+ displayCode(currentLevel);
+ }
+ } else {
+ playErrorSound();
+ blinkDisplay();
+ lockVault();
+ puzzleState = STATE_RESET;
+ currentLevel = 1;
+ displayCode(currentLevel);
+ }
+ sendI2CUpdate(puzzleState);
+ }
+
+ return 0;
+}