diff options
| author | Elwin Hammer <elwinhammer@gmail.com> | 2024-05-29 21:41:24 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-29 21:41:24 +0200 | 
| commit | 1f78927e2e399a504368fb9b407de12d06dddcb5 (patch) | |
| tree | f80ba30274ca75704075610a39fc28930f7ac4fa /puzzle/vault | |
| parent | d7616546dd5e8ba35c2b1b1ece736bca60e0b990 (diff) | |
| parent | 8894d20ff0d1c1dde69879a21e756e01bcfa5262 (diff) | |
Merge pull request #11 from lonkaars/masterprot/software-puzzle
Bring software-puzzle up-to-date
Diffstat (limited to 'puzzle/vault')
| -rw-r--r-- | puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino | 150 | ||||
| -rw-r--r-- | puzzle/vault/console-vaultpuzzle/vault.cpp | 130 | 
2 files changed, 280 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..4dd8ac8 --- /dev/null +++ b/puzzle/vault/arduino-vaultpuzzle/arduino-vaultpuzzle.ino @@ -0,0 +1,150 @@ +#include <Wire.h> +#include <TM1637Display.h> + +// Definitions for GPIO numbers, change these according to your hardware setup +#define TOTAL_LEVELS 5 +#define TAG "VaultPuzzle" + +// Key Matrix Pin Configuration +#define ROWS 4 +#define COLS 3 + +// Module connection pins (Digital Pins for TM1637) +#define CLK 2 +#define DIO 3 + +// Pin to indicate puzzle solved state +#define SOLVED_PIN 53 + +// Initialize the TM1637 display +TM1637Display display(CLK, DIO); + +//TODO Update these pin numbers based on your Arduino setup +const int ROW_PINS[ROWS] = {7, 6, 5, 4};  +const int COL_PINS[COLS] = {10, 9, 8};  + +typedef enum { +    STATE_UNINITIALIZED = 0x00, +    STATE_RESET = 0x01, +    STATE_PLAYING = 0x02, +    STATE_SOLVED = 0x03, +    STATE_ERROR = 0x04 +} PuzzleState; + +const char* validButtons[TOTAL_LEVELS] = {"A2", "B1", "D3", "C2", "C1"}; +PuzzleState puzzleState = STATE_UNINITIALIZED; +int currentLevel = 0; + +// Function prototypes +void display_code(int level); +void initialize_system(); +void check_button_press(); +void update_state_after_button_press(bool validPress); +void play_error_sound(); +void blink_display(); + +void setup() { +  Serial.begin(115200); // Initialize default Serial for debug messages +  pinMode(SOLVED_PIN, OUTPUT); // Initialize the solved indicator pin +  digitalWrite(SOLVED_PIN, LOW); // Start with the solved pin LOW + +  display.setBrightness(0x0f); // Set the brightness of the TM1637 display +  initialize_system(); +  Serial.println("GPIO and display initialized."); + +  // Test to light up all segments +  uint8_t allOn[] = {0xFF, 0xFF, 0xFF, 0xFF}; // All segments on +  display.setSegments(allOn); +  delay(2000); // Keep it on for 2 seconds before proceeding + +  // Initialize the game +  if (true) { // Simulating isVaultClosed +      puzzleState = STATE_RESET; +      currentLevel = 0; +      display_code(currentLevel); +  } else { +      Serial.println("Vault door is open. Please close the door to start the puzzle."); +  } +} + +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 +  } +  // When puzzle is solved, you might want to display a final message and set the solved pin high +  if (puzzleState == STATE_SOLVED) { +      digitalWrite(SOLVED_PIN, HIGH); // Set the solved pin high +      display.showNumberDec(currentLevel, true); // Show final level or a special message +      Serial.println("Final display shown. Puzzle complete."); +      while (1) { delay(1000); } // Hold on the final display +  } +} + +void display_code(int level) { +    Serial.print("Displaying code for level "); Serial.println(level); +    // Display the level on the TM1637 4-digit 7-segment display +    display.showNumberDec(level, true); // True to show leading zeros +    Serial.print("Code for level "); Serial.print(level); Serial.println(" displayed successfully."); +} + +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 +                delay(50); // Debounce delay +                if (digitalRead(ROW_PINS[row]) == LOW) { // Confirm the button is still pressed +                    keyPress[0] = 'A' + row; +                    keyPress[1] = '1' + col; +                    keyPress[2] = '\0'; +                    Serial.print("Keypress detected: "); Serial.println(keyPress); +                    if (strcmp(keyPress, validButtons[currentLevel]) == 0) { +                        currentLevel++; +                        if (currentLevel >= TOTAL_LEVELS) { +                            puzzleState = STATE_SOLVED; +                            Serial.println("Puzzle solved!"); +                            display.showNumberDec(currentLevel + 1, true);  // Display the final level +                            digitalWrite(SOLVED_PIN, HIGH); // Set the solved pin high +                        } else { +                            puzzleState = STATE_PLAYING; +                            display_code(currentLevel); +                        } +                    } else { +                        play_error_sound(); +                        blink_display(); +                        puzzleState = STATE_ERROR; +                        currentLevel = 0; +                        display_code(currentLevel); +                    } +                    while (digitalRead(ROW_PINS[row]) == LOW) {} // Wait for release +                } +            } +        } +        digitalWrite(COL_PINS[col], HIGH); // Deactivate column +    } +} + +void play_error_sound() { +    // Simulate error sound - connect a buzzer to play actual sound +    Serial.println("Playing error sound."); +} + +void blink_display() { +    // Simulate blinking the display - use LEDs or other methods to show visual feedback +    Serial.println("7-segment display is blinking to indicate an error."); +} 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; +} |