p2s2
This commit is contained in:
parent
852939830c
commit
3b2f8957e4
@ -26,8 +26,8 @@ enum class Button: uint8_t {
|
|||||||
B3 = 2,
|
B3 = 2,
|
||||||
B4 = 3,
|
B4 = 3,
|
||||||
GREEN = 0,
|
GREEN = 0,
|
||||||
YELLOW = 1,
|
RED = 1,
|
||||||
RED = 2,
|
YELLOW = 2,
|
||||||
BLUE = 3,
|
BLUE = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#ifndef SD_H
|
#ifndef SD_H
|
||||||
#define SD_H
|
#define SD_H
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -15,7 +16,6 @@ extern sdmmc_card_t *card;
|
|||||||
#define SD_PIN_CLK GPIO_NUM_39
|
#define SD_PIN_CLK GPIO_NUM_39
|
||||||
#define SD_PIN_CMD GPIO_NUM_40
|
#define SD_PIN_CMD GPIO_NUM_40
|
||||||
#define SD_PIN_D0 GPIO_NUM_38
|
#define SD_PIN_D0 GPIO_NUM_38
|
||||||
#define SD_PIN_D1 GPIO_NUM_45
|
|
||||||
#define SD_PIN_D2 GPIO_NUM_42
|
#define SD_PIN_D2 GPIO_NUM_42
|
||||||
#define SD_PIN_D3 GPIO_NUM_41
|
#define SD_PIN_D3 GPIO_NUM_41
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,272 @@
|
|||||||
#include "p002_step2.h"
|
#include "p002_step2.h"
|
||||||
|
#include "helper.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static const char *TAG = "step2";
|
static const char *TAG = "step2";
|
||||||
|
|
||||||
void p002_step2(void) {
|
static const uint8_t BOARD_COUNT = 9;
|
||||||
// TODO: implement step 2
|
static const uint8_t BOARD_SIZE = 6;
|
||||||
|
static const uint8_t PART_SHOTS[3] = {20, 15, 12};
|
||||||
|
static const char *PART_LABELS[3] = {"Alpha", "Bravo", "Charlie"};
|
||||||
|
static const char ROW_LABELS[BOARD_SIZE] = {'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
|
static std::random_device random_device;
|
||||||
|
static std::mt19937 random_engine(random_device());
|
||||||
|
static std::uniform_int_distribution<int> random_board(0, BOARD_COUNT - 1);
|
||||||
|
|
||||||
|
static const uint8_t ALL_BOARDS[BOARD_COUNT][BOARD_SIZE][BOARD_SIZE] = {
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{0,0,1,1,1,1},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,1,1,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,1,1,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,1,1,1,1},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,1,0,0,0,0},
|
||||||
|
{0,0,1,0,0,0},
|
||||||
|
{1,0,1,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,1},
|
||||||
|
{1,0,0,0,0,1},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{1,1,0,1,0,0},
|
||||||
|
{0,0,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{0,1,1,1,1,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{1,0,1,0,1,0},
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{0,0,1,0,0,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,0,0,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,1},
|
||||||
|
{1,1,0,0,0,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{1,1,1,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,1,1,0,0,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,0,0,1,0},
|
||||||
|
{0,0,1,0,1,0},
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,1,1,1,0,0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0,0,0,0,0,0},
|
||||||
|
{1,0,0,0,0,0},
|
||||||
|
{0,1,0,0,1,1},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
{0,1,0,1,0,0},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool row_from_button_state(uint8_t state, uint8_t *row) {
|
||||||
|
switch (state) {
|
||||||
|
case 0b1100: *row = 0; return true; // B1 + B2 -> A
|
||||||
|
case 0b1010: *row = 1; return true; // B1 + B3 -> B
|
||||||
|
case 0b1001: *row = 2; return true; // B1 + B4 -> C
|
||||||
|
case 0b0110: *row = 3; return true; // B2 + B3 -> D
|
||||||
|
case 0b0101: *row = 4; return true; // B2 + B4 -> E
|
||||||
|
case 0b0011: *row = 5; return true; // B3 + B4 -> F
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool column_from_switch_state(uint8_t state, uint8_t *col) {
|
||||||
|
uint8_t value = state & 0xF;
|
||||||
|
if (value >= 1 && value <= 6) {
|
||||||
|
*col = value - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count_ship_segments(const uint8_t board[BOARD_SIZE][BOARD_SIZE]) {
|
||||||
|
int count = 0;
|
||||||
|
for (uint8_t row = 0; row < BOARD_SIZE; ++row) {
|
||||||
|
for (uint8_t col = 0; col < BOARD_SIZE; ++col) {
|
||||||
|
if (board[row][col] == 1) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_board(uint8_t dest[BOARD_SIZE][BOARD_SIZE], const uint8_t src[BOARD_SIZE][BOARD_SIZE]) {
|
||||||
|
memcpy(dest, src, BOARD_SIZE * BOARD_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_status(const char *part_name,
|
||||||
|
int shots_left,
|
||||||
|
int hits,
|
||||||
|
int misses,
|
||||||
|
int row,
|
||||||
|
int col,
|
||||||
|
const char *info) {
|
||||||
|
char line0[21] = {0};
|
||||||
|
char line1[21] = {0};
|
||||||
|
char line2[21] = {0};
|
||||||
|
char line3[21] = {0};
|
||||||
|
|
||||||
|
snprintf(line0, sizeof(line0), "%s Shots:%2d", part_name, shots_left);
|
||||||
|
if (row >= 0 && col >= 0) {
|
||||||
|
snprintf(line1, sizeof(line1), "Row %c Col %d", ROW_LABELS[row], col + 1);
|
||||||
|
} else {
|
||||||
|
snprintf(line1, sizeof(line1), "Row - Col -");
|
||||||
|
}
|
||||||
|
snprintf(line2, sizeof(line2), "Hits:%2d Misses:%2d", hits, misses);
|
||||||
|
snprintf(line3, sizeof(line3), "%s", info);
|
||||||
|
|
||||||
|
lcd_clear();
|
||||||
|
lcd_print(0, 0, line0);
|
||||||
|
lcd_print(0, 1, line1);
|
||||||
|
lcd_print(0, 2, line2);
|
||||||
|
lcd_print(0, 3, line3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void p002_step2(void) {
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
for (int part = 0; part < 3; ++part) {
|
||||||
|
const char *part_name = PART_LABELS[part];
|
||||||
|
const int max_shots = PART_SHOTS[part];
|
||||||
|
bool completed = false;
|
||||||
|
|
||||||
|
while (!completed) {
|
||||||
|
uint8_t board[BOARD_SIZE][BOARD_SIZE];
|
||||||
|
copy_board(board, ALL_BOARDS[random_board(random_engine)]);
|
||||||
|
|
||||||
|
int shots_taken = 0;
|
||||||
|
int hits = 0;
|
||||||
|
int misses = 0;
|
||||||
|
int current_row = -1;
|
||||||
|
int current_col = -1;
|
||||||
|
const char *status = "Hold 2 buttons + set switches";
|
||||||
|
|
||||||
|
render_status(part_name, max_shots - shots_taken, hits, misses, -1, -1, status);
|
||||||
|
clean_bomb();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint8_t button_state = get_button_state();
|
||||||
|
uint8_t switch_state = get_switch_state();
|
||||||
|
uint8_t row = 0;
|
||||||
|
uint8_t col = 0;
|
||||||
|
bool row_valid = row_from_button_state(button_state, &row);
|
||||||
|
bool col_valid = column_from_switch_state(switch_state, &col);
|
||||||
|
|
||||||
|
if (row_valid) {
|
||||||
|
current_row = row;
|
||||||
|
} else {
|
||||||
|
current_row = -1;
|
||||||
|
}
|
||||||
|
if (col_valid) {
|
||||||
|
current_col = col;
|
||||||
|
} else {
|
||||||
|
current_col = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeypadKey key;
|
||||||
|
if (get_keypad_pressed(&key)) {
|
||||||
|
if (key == KeypadKey::k5) {
|
||||||
|
if (!row_valid) {
|
||||||
|
status = "Invalid row selection";
|
||||||
|
} else if (!col_valid) {
|
||||||
|
status = "Invalid column value";
|
||||||
|
} else {
|
||||||
|
uint8_t cell = board[row][col];
|
||||||
|
if (cell == 2 || cell == 3) {
|
||||||
|
status = "Already fired there";
|
||||||
|
} else {
|
||||||
|
shots_taken += 1;
|
||||||
|
if (cell == 1) {
|
||||||
|
board[row][col] = 3;
|
||||||
|
hits += 1;
|
||||||
|
status = "Hit!";
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_RED);
|
||||||
|
} else {
|
||||||
|
board[row][col] = 2;
|
||||||
|
misses += 1;
|
||||||
|
status = "Miss!";
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_WHITE);
|
||||||
|
}
|
||||||
|
leds_flush();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
|
led_set(IndicatorLED::LED_LCD, LEDColor::LED_COLOR_OFF);
|
||||||
|
leds_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_status(part_name,
|
||||||
|
max_shots - shots_taken,
|
||||||
|
hits,
|
||||||
|
misses,
|
||||||
|
current_row,
|
||||||
|
current_col,
|
||||||
|
status);
|
||||||
|
|
||||||
|
if (count_ship_segments(board) == 0) {
|
||||||
|
completed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shots_taken >= max_shots) {
|
||||||
|
strike("Out of shots!");
|
||||||
|
status = "Out of shots! Retry";
|
||||||
|
render_status(part_name,
|
||||||
|
0,
|
||||||
|
hits,
|
||||||
|
misses,
|
||||||
|
current_row,
|
||||||
|
current_col,
|
||||||
|
status);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part < 2)
|
||||||
|
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
|
||||||
|
clean_bomb();
|
||||||
|
}
|
||||||
|
|
||||||
|
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
|
||||||
|
lcd_clear();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user