[refactor] Progressive difficulty, blunder logic and documentation.
This commit is contained in:
@@ -1,95 +1,82 @@
|
||||
# Connect Four: ESP32-C3 LED Edition
|
||||
# 🕹️ Connect 4 AI: Master Edition
|
||||
|
||||
A hardware-based Connect Four game featuring an 8x8 NeoPixel matrix, a strategic Minimax AI, and a dynamic "Attract Mode" for public display.
|
||||
|
||||
## How the Program Works
|
||||
|
||||
The program is built as a **Finite State Machine (FSM)**.
|
||||
It manages the game flow by transitioning between distinct states based on user input, game outcomes, or inactivity timers.
|
||||
|
||||
### 1. Game States
|
||||
|
||||
- **Menu**: Displays stylized Roman numerals (**I** or **II**) to select between Single Player or Two Player modes.
|
||||
- **Game Play**: The main loop handles the real-time gravity of falling discs, encoder tracking for column selection, and the hand-off between the human and the AI.
|
||||
- **Game Over**: Triggered when a win or draw is detected. It "locks" the board, dims the background discs to 15% intensity, and flashes the winning line.
|
||||
- **Demo Mode**: Triggered after 60 seconds of inactivity. The AI plays against itself to act as a visual "attract mode."
|
||||
|
||||
### 2. Win Detection Logic
|
||||
|
||||
To ensure 100% accuracy, the program performs a synchronous, multi-directional scan of the 7x6 grid after every single move.
|
||||
It checks for four matching non-zero values in the following patterns:
|
||||
|
||||
- **Horizontal**: `[column] [row]` to `[column + 3] [row]`
|
||||
- **Vertical**: `[column] [row]` to `[column] [row + 3]`
|
||||
- **Diagonal Up**: `[column] [row]` to `[column + 3] [row + 3]`
|
||||
- **Diagonal Down**: `[column] [row]` to `[column + 3] [row - 3]`
|
||||
A high-performance Connect 4 implementation for ESP32-C3 and 8x8 WS2812B matrices. Features dynamic difficulty scaling, "humanized" AI movement, and a mobile-friendly web administration portal.
|
||||
|
||||
---
|
||||
|
||||
## The AI: Strategic Minimax
|
||||
## 🛠 Hardware Configuration
|
||||
|
||||
The computer opponent uses the **Minimax Algorithm**, a classic artificial intelligence method for zero-sum games.
|
||||
### 🔌 Pin Mapping (Lolin C3 Mini)
|
||||
|
||||
### 1. Look-Ahead (Depth Search)
|
||||
| Component | ESP32-C3 Pin | Function |
|
||||
| :------------------- | :----------- | :--------------- |
|
||||
| **NeoPixel Matrix** | `GPIO 4` | Data Input (DIN) |
|
||||
| **Rotary Encoder A** | `GPIO 0` | Directional CLK |
|
||||
| **Rotary Encoder B** | `GPIO 1` | Directional DT |
|
||||
| **Encoder Button** | `GPIO 2` | Selection (SW) |
|
||||
|
||||
The AI does not just look at the current board; it simulates the game **6 to 8 moves into the future**.
|
||||
It explores a "tree" of possibilities: _"If I play here, and the player plays there, then I can play here..."_
|
||||
### 📐 Physical Dimensions
|
||||
|
||||
### 2. Alpha-Beta Pruning
|
||||
Designed for standard 8x8 matrix modules (approx. 65mm x 67mm).
|
||||
|
||||
Because searching millions of possibilities would be too slow for a microcontroller, we use **Alpha-Beta Pruning**.
|
||||
This allows the AI to "prune" (ignore) branches of the game tree that are mathematically
|
||||
guaranteed to be worse than moves it has already found, significantly speeding up the calculation.
|
||||
|
||||
### 3. Immediate Threat Reaction
|
||||
|
||||
To prevent the AI from being "distracted" by deep strategies while missing a simple win or loss,
|
||||
we implemented a high-priority **Reaction Scanner**:
|
||||
|
||||
- **Kill Move**: If the AI can win in exactly one move, it takes it immediately.
|
||||
- **Block Move**: If the player is one move away from winning (3-in-a-row), the AI identifies the threat and blocks it regardless of the Minimax score.
|
||||
|
||||
### 4. Controlled Randomness (Demo Mode)
|
||||
|
||||
To keep the Demo Mode interesting for spectators, the AI has a 25% chance to ignore the "perfect" move and pick a random column.
|
||||
This ensures that every demo game is unique and not a repetitive loop of the same strategy.
|
||||
- **Top Row (0):** Interaction and AI decision visualization.
|
||||
- **Game Board:** Standard $7 \times 6$ grid.
|
||||
- **UI Borders:** Fixed blue frame for visibility.
|
||||
|
||||
---
|
||||
|
||||
## Technical Specifications
|
||||
## 🧠 Advanced AI Features
|
||||
|
||||
### Hardware Pins (Lolin C3 Mini)
|
||||
### 1. Progressive Difficulty (Evolution Mode)
|
||||
|
||||
| Component | Pin | Function |
|
||||
| :---------- | :-- | :--------------------------------------- |
|
||||
| **LED_PIN** | 4 | WS2812B NeoPixel Data |
|
||||
| **ENC_A** | 0 | Rotary Encoder Phase A |
|
||||
| **ENC_B** | 1 | Rotary Encoder Phase B |
|
||||
| **ENC_SW** | 2 | Switch (Includes 50ms Software Debounce) |
|
||||
The AI search depth (Ply) increases as the board fills. This ensures the AI is fast in the opening and lethal in the endgame.
|
||||
|
||||
### NeoPixel Grid Layout
|
||||
- **Formula:** $DynamicPly = BasePly + \lfloor \frac{DiscsOnBoard}{7} \rfloor$
|
||||
- **Benefit:** High-level tactical precision exactly when the game becomes critical.
|
||||
|
||||
The 8x8 matrix is mapped as follows:
|
||||
### 2. Strategic Blunder Injection
|
||||
|
||||
- **Play Area**: 7 columns (0-6) by 6 rows (0-5).
|
||||
- **Boundaries**: Row 1 and Column 7 are lit in **Blue** to mark the board limits.
|
||||
- **Indicators**: The top-right pixel (7,0) pulses in the computer's color while it is "thinking."
|
||||
- **Glowing Frame**: During Demo mode, the blue borders pulse with a white "glow" effect using a `beat8` sine wave to indicate autonomous play.
|
||||
To avoid endless stalemate draws between high-level AIs, a "Blunder" logic is used.
|
||||
|
||||
- **Demo Mode:** Always active; 20% chance to make a suboptimal move.
|
||||
- **Player Mode:** Toggleable via Web Portal to make the AI more "human."
|
||||
|
||||
### 3. Alpha-Beta Pruning & Column Ordering
|
||||
|
||||
The engine evaluates the center column first. This triggers pruning earlier in the search tree, skipping millions of unnecessary calculations and keeping the ESP32-C3 responsive.
|
||||
|
||||
---
|
||||
|
||||
## Controls & Interaction
|
||||
## 📖 Code Architecture Details
|
||||
|
||||
- **Rotate Encoder**: Move the cursor (top row) to select a column.
|
||||
- **Press Encoder Button**: Drop a disc.
|
||||
- **Full Column Warning**: If you attempt to play in a full column, the selection disc will blink rapidly, and the move will be ignored.
|
||||
- **Reset**: After a game ends, press the button once to return to the Menu.
|
||||
### 🔄 State Machine
|
||||
|
||||
## Build Flags (platformio.ini)
|
||||
The software cycles through states:
|
||||
|
||||
Tweak the game performance without changing the source code:
|
||||
- **MENU:** Select mode using the rotary encoder.
|
||||
- **PLAYING:** Manages player turns and the gravity-acceleration drop animation.
|
||||
- **DEMO:** Auto-starts after inactivity. Randomizes Ply (3-6) and enforces blunders to ensure definitive game results.
|
||||
|
||||
- `IDLE_TIMEOUT`: Time (ms) before Demo Mode starts.
|
||||
- `DEMO_RESET_PAUSE`: Delay (ms) between games in Demo Mode.
|
||||
- `DEBOUNCE_DELAY`: Sensitivity of the encoder button.
|
||||
- `BRIGHTNESS`: Global brightness of the NeoPixels.
|
||||
### 🎨 Rendering & Mapping
|
||||
|
||||
The `getIdx(x, y)` function maps the 2D game board to the 1D NeoPixel array. The `updateThinkingVisuals()` function provides real-time feedback of the AI's internal search process by moving a pulsing disc across the top row.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Web Admin Portal
|
||||
|
||||
Connect to the **"Connect4-Config"** Access Point to adjust:
|
||||
|
||||
- **Base Ply:** Minimum search depth.
|
||||
- **Brightness:** Global LED intensity.
|
||||
- **Idle Timeout:** Inactivity period before Demo Mode.
|
||||
- **Toggles:** Enable/Disable Blunders and Evolution Mode.
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Setup & Installation
|
||||
|
||||
1. Install **PlatformIO**.
|
||||
2. Add dependencies: `FastLED`, `Encoder`.
|
||||
3. Set your WiFi Password in `platformio.ini`: `-D WIFI_PASSWORD=\"your_pass\"`.
|
||||
4. Upload to ESP32-C3.
|
||||
|
||||
Reference in New Issue
Block a user