day streak and further wordle dev

This commit is contained in:
David Volovskiy 2024-08-15 08:17:10 -04:00
parent ee53e83ae7
commit 3a24ede3de
3 changed files with 72 additions and 26 deletions

View file

@ -25,14 +25,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "wordle_face.h" #include "wordle_face.h"
#if USE_DAILY_STREAK
#include "watch_utility.h"
#endif
/* /*
TODO: TODO:
* Add quick iteration (8x freq to get to the letter we want) * Add quick iteration (8x freq to get to the letter we want)
* Fix the word matching (if answer is AAAAA and we put in AACAA, the C blinks) * Fix the word matching (if answer is AAAAA and we put in AACAA, the C blinks)
* Verify pressing back always work when the board is G_G_G * Add a way to recount previous attempts
* Add daily streak and wait for next day
* Add a way tpo recount previous attempts
*/ */
@ -54,7 +55,7 @@ C | 525
U | 514 P has more words with the other letters here (281 vs 198) U | 514 P has more words with the other letters here (281 vs 198)
P | 448 P | 448
*/ */
static const char _valid_letters[] = {'E', 'S', 'A', 'R', 'O', 'L', 'I', 'N', 'C', 'P'}; static const char _valid_letters[] = {'A', 'C', 'E', 'I', 'L', 'N', 'O', 'P', 'R', 'S'};
// Number of words found: 281 // Number of words found: 281
static const char _legal_words[][WORDLE_LENGTH + 1] = { static const char _legal_words[][WORDLE_LENGTH + 1] = {
@ -126,12 +127,13 @@ static void display_all_letters(wordle_state_t *state) {
} }
static bool check_word(wordle_state_t *state) { static bool check_word(wordle_state_t *state) {
WordleLetterResult checked_letter_in_answer[WORDLE_LENGTH] = {WORDLE_LETTER_WRONG};
// Exact // Exact
bool is_exact_match = true; bool is_exact_match = true;
for (size_t i = 0; i < WORDLE_LENGTH; i++) { for (size_t i = 0; i < WORDLE_LENGTH; i++) {
if (_valid_letters[state->word_elements[i]] == _legal_words[state->curr_answer][i]) if (_valid_letters[state->word_elements[i]] == _legal_words[state->curr_answer][i]) {
state->word_elements_result[i] = WORDLE_LETTER_CORRECT; state->word_elements_result[i] = checked_letter_in_answer[i] = WORDLE_LETTER_CORRECT;
}
else { else {
state->word_elements_result[i] = WORDLE_LETTER_WRONG; state->word_elements_result[i] = WORDLE_LETTER_WRONG;
is_exact_match = false; is_exact_match = false;
@ -141,10 +143,10 @@ static bool check_word(wordle_state_t *state) {
// Wrong Location // Wrong Location
for (size_t i = 0; i < WORDLE_LENGTH; i++) { for (size_t i = 0; i < WORDLE_LENGTH; i++) {
for (size_t j = 0; j < WORDLE_LENGTH; j++) { for (size_t j = 0; j < WORDLE_LENGTH; j++) {
if (state->word_elements_result[j] != WORDLE_LETTER_WRONG) continue; if (checked_letter_in_answer[j] != WORDLE_LETTER_WRONG) continue;
if (_valid_letters[state->word_elements[i]] == _legal_words[state->curr_answer][j]) { if (_valid_letters[state->word_elements[i]] == _legal_words[state->curr_answer][j]) {
printf("me: %c them: %c\r\n", _valid_letters[state->word_elements[i]], _legal_words[state->curr_answer][j]); printf("me: %c them: %c\r\n", _valid_letters[state->word_elements[i]], _legal_words[state->curr_answer][j]);
state->word_elements_result[j] = WORDLE_LETTER_WRONG_LOC; state->word_elements_result[i] = checked_letter_in_answer[j] = WORDLE_LETTER_WRONG_LOC;
break; break;
} }
} }
@ -190,12 +192,29 @@ static void display_title(wordle_state_t *state) {
static void display_streak(wordle_state_t *state) { static void display_streak(wordle_state_t *state) {
char buf[12]; char buf[12];
state->curr_screen = SCREEN_STREAK; state->curr_screen = SCREEN_STREAK;
printf("streak %d \r\n", state->streak); #if USE_DAILY_STREAK
sprintf(buf, "WO St%2ddy", state->streak); sprintf(buf, "WO St%2ddy", state->streak);
#else
sprintf(buf, "WO St%4d", state->streak);
#endif
watch_display_string(buf, 0); watch_display_string(buf, 0);
watch_set_colon(); watch_set_colon();
} }
#if USE_DAILY_STREAK
static void display_wait(wordle_state_t *state) {
state->curr_screen = SCREEN_WAIT;
if (state->streak < 40) {
char buf[13];
sprintf(buf,"WO%2d WaIt ", state->streak);
watch_display_string(buf, 0);
}
else { // Streak too long to display in top-right
watch_display_string("WO WaIt ", 0);
}
}
#endif
static void display_lose(wordle_state_t *state, uint8_t subsecond) { static void display_lose(wordle_state_t *state, uint8_t subsecond) {
char buf[WORDLE_LENGTH + 6]; char buf[WORDLE_LENGTH + 6];
sprintf(buf," L %s", subsecond % 2 ? _legal_words[state->curr_answer] : " "); sprintf(buf," L %s", subsecond % 2 ? _legal_words[state->curr_answer] : " ");
@ -218,23 +237,30 @@ static uint8_t get_first_pos(WordleLetterResult *word_elements_result) {
} }
static uint8_t get_next_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) { static uint8_t get_next_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) {
uint8_t pos = curr_pos; for (size_t pos = curr_pos+1; pos < WORDLE_LENGTH; pos++) {
do { if (word_elements_result[pos] != WORDLE_LETTER_CORRECT)
pos++; return pos;
if (pos > WORDLE_LENGTH) return WORDLE_LENGTH + 1; }
} while (word_elements_result[pos] == WORDLE_LETTER_CORRECT); return WORDLE_LENGTH;
return pos;
} }
static uint8_t get_prev_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) { static uint8_t get_prev_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) {
int8_t pos = curr_pos; if (curr_pos == 0) return 0;
do { for (int8_t pos = curr_pos-1; pos >= 0; pos--) {
pos--; if (word_elements_result[pos] != WORDLE_LETTER_CORRECT)
if (pos < 0) return curr_pos; return pos;
} while (word_elements_result[pos] == WORDLE_LETTER_CORRECT); }
return pos; return curr_pos;
} }
#if USE_DAILY_STREAK
static uint32_t get_day_unix_time(void) {
watch_date_time now = watch_rtc_get_date_time();
now.unit.hour = now.unit.minute = now.unit.second = 0;
return watch_utility_date_time_to_unix_time(now, 0);
}
#endif
static void display_result(wordle_state_t *state, uint8_t subsecond) { static void display_result(wordle_state_t *state, uint8_t subsecond) {
char buf[WORDLE_LENGTH + 1]; char buf[WORDLE_LENGTH + 1];
for (size_t i = 0; i < WORDLE_LENGTH; i++) for (size_t i = 0; i < WORDLE_LENGTH; i++)
@ -273,6 +299,12 @@ static bool act_on_btn(wordle_state_t *state) {
state->curr_screen = SCREEN_PLAYING; state->curr_screen = SCREEN_PLAYING;
return true; return true;
case SCREEN_TITLE: case SCREEN_TITLE:
#if USE_DAILY_STREAK
if (state->prev_day == get_day_unix_time()) {
display_wait(state);
return true;
}
#endif
display_streak(state); display_streak(state);
return true; return true;
case SCREEN_STREAK: case SCREEN_STREAK:
@ -281,7 +313,12 @@ static bool act_on_btn(wordle_state_t *state) {
case SCREEN_WIN: case SCREEN_WIN:
case SCREEN_LOSE: case SCREEN_LOSE:
display_title(state); display_title(state);
return true; return true;
#if USE_DAILY_STREAK
case SCREEN_WAIT:
display_title(state);
return true;
#endif
default: default:
return false; return false;
} }
@ -296,7 +333,6 @@ void wordle_face_setup(movement_settings_t *settings, uint8_t watch_face_index,
memset(*context_ptr, 0, sizeof(wordle_state_t)); memset(*context_ptr, 0, sizeof(wordle_state_t));
wordle_state_t *state = (wordle_state_t *)*context_ptr; wordle_state_t *state = (wordle_state_t *)*context_ptr;
state->curr_screen = SCREEN_TITLE; state->curr_screen = SCREEN_TITLE;
} }
// Do any pin or peripheral setup here; this will be called whenever the watch wakes from deep sleep. // Do any pin or peripheral setup here; this will be called whenever the watch wakes from deep sleep.
} }
@ -305,6 +341,9 @@ void wordle_face_activate(movement_settings_t *settings, void *context) {
(void) settings; (void) settings;
wordle_state_t *state = (wordle_state_t *)context; wordle_state_t *state = (wordle_state_t *)context;
movement_request_tick_frequency(2); movement_request_tick_frequency(2);
#if USE_DAILY_STREAK
if (state->prev_day <= (get_day_unix_time() + (60 *60 * 24))) state->streak = 0;
#endif
if (state->curr_screen == SCREEN_TITLE) if (state->curr_screen == SCREEN_TITLE)
display_title(state); display_title(state);
} }
@ -356,11 +395,14 @@ bool wordle_face_loop(movement_event_t event, movement_settings_t *settings, voi
display_letter(state, true); display_letter(state, true);
if (state->word_elements[state->position] == _num_valid_letters) break; if (state->word_elements[state->position] == _num_valid_letters) break;
state->position = get_next_pos(state->position, state->word_elements_result); state->position = get_next_pos(state->position, state->word_elements_result);
if(WORDLE_LENGTH == (state->position)) { if (state->position >= WORDLE_LENGTH) {
bool exact_match = check_word(state); bool exact_match = check_word(state);
if (exact_match) { if (exact_match) {
state->curr_screen = SCREEN_WIN; state->curr_screen = SCREEN_WIN;
state->streak++; state->streak++;
#if USE_DAILY_STREAK
state->prev_day = get_day_unix_time();
#endif
break; break;
} }
if (state->attempt++ >= WORDLE_MAX_ATTEMPTS) { if (state->attempt++ >= WORDLE_MAX_ATTEMPTS) {

View file

@ -50,6 +50,9 @@ typedef enum {
SCREEN_RESULT, SCREEN_RESULT,
SCREEN_TITLE, SCREEN_TITLE,
SCREEN_STREAK, SCREEN_STREAK,
#if USE_DAILY_STREAK
SCREEN_WAIT,
#endif
SCREEN_WIN, SCREEN_WIN,
SCREEN_LOSE, SCREEN_LOSE,
SCREEN_COUNT SCREEN_COUNT
@ -66,7 +69,7 @@ typedef struct {
uint8_t streak; uint8_t streak;
WordleScreen curr_screen; WordleScreen curr_screen;
#if USE_DAILY_STREAK #if USE_DAILY_STREAK
// For the day info uint32_t prev_day;
#endif #endif
} wordle_state_t; } wordle_state_t;

View file

@ -336,6 +336,7 @@ def most_used_letters():
def list_of_valid_words(): def list_of_valid_words():
letters = ['e', 's', 'a', 'r', 'o', 'l', 'i', 'n', 'c', 'p'] letters = ['e', 's', 'a', 'r', 'o', 'l', 'i', 'n', 'c', 'p']
letters = sorted(letters)
for i, letter in enumerate(letters): # Force all letters to be capitalized for i, letter in enumerate(letters): # Force all letters to be capitalized
letters[i] = letter.upper() letters[i] = letter.upper()