From 4d2e4172a229f4d5d176f5241646291c709e333b Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Tue, 8 Jul 2025 07:44:06 -0400 Subject: [PATCH 1/8] Moved Wordle from legacy to main folder --- movement_faces.h | 1 + watch-faces.mk | 1 + {legacy/watch_faces => watch-faces}/complication/wordle_face.c | 0 {legacy/watch_faces => watch-faces}/complication/wordle_face.h | 0 .../watch_faces => watch-faces}/complication/wordle_face_dict.h | 0 5 files changed, 2 insertions(+) rename {legacy/watch_faces => watch-faces}/complication/wordle_face.c (100%) rename {legacy/watch_faces => watch-faces}/complication/wordle_face.h (100%) rename {legacy/watch_faces => watch-faces}/complication/wordle_face_dict.h (100%) diff --git a/movement_faces.h b/movement_faces.h index f5c087bc..d849636b 100644 --- a/movement_faces.h +++ b/movement_faces.h @@ -61,4 +61,5 @@ #include "totp_face.h" #include "tally_face.h" #include "probability_face.h" +#include "wordle_face.h" // New includes go above this line. diff --git a/watch-faces.mk b/watch-faces.mk index 665ec4b7..a390a3bf 100644 --- a/watch-faces.mk +++ b/watch-faces.mk @@ -16,6 +16,7 @@ SRCS += \ ./watch-faces/complication/squash_face.c \ ./watch-faces/complication/totp_face.c \ ./watch-faces/complication/tally_face.c \ + ./watch-faces/complication/wordle_face.c \ ./watch-faces/demo/all_segments_face.c \ ./watch-faces/demo/character_set_face.c \ ./watch-faces/demo/light_sensor_face.c \ diff --git a/legacy/watch_faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c similarity index 100% rename from legacy/watch_faces/complication/wordle_face.c rename to watch-faces/complication/wordle_face.c diff --git a/legacy/watch_faces/complication/wordle_face.h b/watch-faces/complication/wordle_face.h similarity index 100% rename from legacy/watch_faces/complication/wordle_face.h rename to watch-faces/complication/wordle_face.h diff --git a/legacy/watch_faces/complication/wordle_face_dict.h b/watch-faces/complication/wordle_face_dict.h similarity index 100% rename from legacy/watch_faces/complication/wordle_face_dict.h rename to watch-faces/complication/wordle_face_dict.h From 07116222108a8bb3b602998acea4644c91642f68 Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Tue, 8 Jul 2025 07:51:36 -0400 Subject: [PATCH 2/8] Add delays before registering btns, don't repeat words, cleaned up enum names --- movement_config.h | 1 + watch-faces/complication/wordle_face.c | 152 +++++++++++++++---------- watch-faces/complication/wordle_face.h | 50 +++++--- 3 files changed, 129 insertions(+), 74 deletions(-) diff --git a/movement_config.h b/movement_config.h index 0da8da43..c4cb8c36 100644 --- a/movement_config.h +++ b/movement_config.h @@ -29,6 +29,7 @@ const watch_face_t watch_faces[] = { clock_face, + wordle_face, world_clock_face, sunrise_sunset_face, moon_phase_face, diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index a93a0e0e..4873b5a1 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -35,7 +35,7 @@ static uint32_t get_random(uint32_t max) { #endif } -static uint8_t get_first_pos(WordleLetterResult *word_elements_result) { +static uint8_t get_first_pos(wordle_letter_result *word_elements_result) { for (size_t i = 0; i < WORDLE_LENGTH; i++) { if (word_elements_result[i] != WORDLE_LETTER_CORRECT) return i; @@ -43,7 +43,7 @@ static uint8_t get_first_pos(WordleLetterResult *word_elements_result) { return 0; } -static uint8_t get_next_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) { +static uint8_t get_next_pos(uint8_t curr_pos, wordle_letter_result *word_elements_result) { for (size_t pos = curr_pos; pos < WORDLE_LENGTH;) { if (word_elements_result[++pos] != WORDLE_LETTER_CORRECT) return pos; @@ -51,7 +51,7 @@ static uint8_t get_next_pos(uint8_t curr_pos, WordleLetterResult *word_elements_ return WORDLE_LENGTH; } -static uint8_t get_prev_pos(uint8_t curr_pos, WordleLetterResult *word_elements_result) { +static uint8_t get_prev_pos(uint8_t curr_pos, wordle_letter_result *word_elements_result) { if (curr_pos == 0) return 0; for (int8_t pos = curr_pos; pos >= 0;) { if (word_elements_result[--pos] != WORDLE_LETTER_CORRECT) @@ -99,13 +99,15 @@ static void display_all_letters(wordle_state_t *state) { #if !WORDLE_ALLOW_NON_WORD_AND_REPEAT_GUESSES static void display_not_in_dict(wordle_state_t *state) { - state->curr_screen = SCREEN_NO_DICT; + state->curr_screen = WORDLE_SCREEN_NO_DICT; watch_display_string("nodict", 4); + state->ignore_btn_ticks = WORDLE_TICK_BAD_GUESS; } static void display_already_guessed(wordle_state_t *state) { - state->curr_screen = SCREEN_ALREADY_GUESSED; + state->curr_screen = WORDLE_SCREEN_ALREADY_GUESSED; watch_display_string("GUESSD", 4); + state->ignore_btn_ticks = WORDLE_TICK_BAD_GUESS; } static uint32_t check_word_in_dict(uint8_t *word_elements) { @@ -164,8 +166,8 @@ static bool check_word(wordle_state_t *state) { return false; } -static void show_skip_wrong_letter_indicator(bool skipping, WordleScreen curr_screen) { - if (curr_screen >= SCREEN_PLAYING) return; +static void show_skip_wrong_letter_indicator(bool skipping, wordle_screen curr_screen) { + if (curr_screen >= WORDLE_SCREEN_PLAYING) return; if (skipping) watch_display_string("H", 3); else @@ -201,7 +203,7 @@ static void display_attempt(uint8_t attempt) { } static void display_playing(wordle_state_t *state) { - state->curr_screen = SCREEN_PLAYING; + state->curr_screen = WORDLE_SCREEN_PLAYING; display_attempt(state->attempt); display_all_letters(state); } @@ -230,9 +232,18 @@ static void reset_incorrect_elements(wordle_state_t *state) { } } +static bool is_in_do_not_use_list(uint16_t guess, const uint16_t *not_to_use, uint8_t max_repeats) { + for (size_t i = 0; i < max_repeats; i++) { + if (guess == not_to_use[i]) return true; + } + return false; +} + static void reset_board(wordle_state_t *state) { reset_all_elements(state); - state->curr_answer = get_random(WORDLE_NUM_WORDS); + do { + state->curr_answer = get_random(WORDLE_NUM_WORDS); + } while (is_in_do_not_use_list(state->curr_answer, state->not_to_use, WORDLE_MAX_BETWEEN_REPEATS)); watch_clear_colon(); state->position = get_first_pos(state->word_elements_result); display_playing(state); @@ -243,7 +254,7 @@ static void reset_board(wordle_state_t *state) { } static void display_title(wordle_state_t *state) { - state->curr_screen = SCREEN_TITLE; + state->curr_screen = WORDLE_SCREEN_TITLE; watch_display_string("WO WordLE", 0); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } @@ -254,7 +265,7 @@ static void display_continue_result(bool continuing) { } static void display_continue(wordle_state_t *state) { - state->curr_screen = SCREEN_CONTINUE; + state->curr_screen = WORDLE_SCREEN_CONTINUE; watch_display_string("Cont ", 4); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); display_continue_result(state->continuing); @@ -263,7 +274,7 @@ static void display_continue(wordle_state_t *state) { static void display_streak(wordle_state_t *state) { char buf[12]; - state->curr_screen = SCREEN_STREAK; + state->curr_screen = WORDLE_SCREEN_STREAK; #if WORDLE_USE_DAILY_STREAK == 2 if (state->streak > 99) sprintf(buf, "WO St--dy"); @@ -279,7 +290,7 @@ static void display_streak(wordle_state_t *state) { #if WORDLE_USE_DAILY_STREAK == 2 static void display_wait(wordle_state_t *state) { - state->curr_screen = SCREEN_WAIT; + state->curr_screen = WORDLE_SCREEN_WAIT; if (state->streak < 40) { char buf[13]; sprintf(buf,"WO%2d WaIt ", state->streak); @@ -302,14 +313,14 @@ static uint32_t get_day_unix_time(void) { static void display_lose(wordle_state_t *state, uint8_t subsecond) { char buf[WORDLE_LENGTH + 6]; - sprintf(buf," L %s", subsecond % 2 ? _valid_words[state->curr_answer] : " "); + sprintf(buf,"L %s", subsecond % 2 ? _valid_words[state->curr_answer] : " "); watch_display_string(buf, 0); } static void display_win(wordle_state_t *state, uint8_t subsecond) { (void) state; char buf[13]; - sprintf(buf," W %s ", subsecond % 2 ? "NICE" : "JOb "); + sprintf(buf,"W %s ", subsecond % 2 ? "NICE" : "JOb "); watch_display_string(buf, 0); } @@ -346,15 +357,16 @@ static void display_result(wordle_state_t *state, uint8_t subsecond) { watch_display_string(buf, 5); } -static bool act_on_btn(wordle_state_t *state, const uint8_t pin) { +static bool act_on_btn(wordle_state_t *state, const wordle_pin_enum pin) { + if (state->ignore_btn_ticks > 0) return true; switch (state->curr_screen) { - case SCREEN_RESULT: + case WORDLE_SCREEN_RESULT: reset_incorrect_elements(state); state->position = get_first_pos(state->word_elements_result); display_playing(state); return true; - case SCREEN_TITLE: + case WORDLE_SCREEN_TITLE: #if WORDLE_USE_DAILY_STREAK == 2 if (state->day_last_game_started == get_day_unix_time()) { display_wait(state); @@ -372,26 +384,26 @@ static bool act_on_btn(wordle_state_t *state, const uint8_t pin) { display_streak(state); #endif return true; - case SCREEN_STREAK: + case WORDLE_SCREEN_STREAK: state->day_last_game_started = get_day_unix_time(); reset_board(state); return true; - case SCREEN_WIN: - case SCREEN_LOSE: + case WORDLE_SCREEN_WIN: + case WORDLE_SCREEN_LOSE: display_title(state); return true; - case SCREEN_NO_DICT: - case SCREEN_ALREADY_GUESSED: + case WORDLE_SCREEN_NO_DICT: + case WORDLE_SCREEN_ALREADY_GUESSED: state->position = get_first_pos(state->word_elements_result); display_playing(state); return true; #if WORDLE_USE_DAILY_STREAK == 2 - case SCREEN_WAIT: + case WORDLE_SCREEN_WAIT: (void) pin; display_title(state); return true; #else - case SCREEN_CONTINUE: + case WORDLE_SCREEN_CONTINUE: switch (pin) { case BTN_ALARM: @@ -407,6 +419,8 @@ static bool act_on_btn(wordle_state_t *state, const uint8_t pin) { state->continuing = !state->continuing; display_continue_result(state->continuing); break; + default: + break; } return true; #endif @@ -416,6 +430,13 @@ static bool act_on_btn(wordle_state_t *state, const uint8_t pin) { return false; } +static void win_lose_shared(wordle_state_t *state) { + reset_all_elements(state); + state->ignore_btn_ticks = WORDLE_TICK_WIN_LOSE; + state->not_to_use[state->not_to_use_position] = state->curr_answer; + state->not_to_use_position = (state->not_to_use_position + 1) % WORDLE_MAX_BETWEEN_REPEATS; +} + static void get_result(wordle_state_t *state) { #if !WORDLE_ALLOW_NON_WORD_AND_REPEAT_GUESSES // Check if it's in the dict @@ -437,8 +458,8 @@ static void get_result(wordle_state_t *state) { #endif bool exact_match = check_word(state); if (exact_match) { - reset_all_elements(state); - state->curr_screen = SCREEN_WIN; + state->curr_screen = WORDLE_SCREEN_WIN; + win_lose_shared(state); if (state->streak < 0x7F) state->streak++; #if WORDLE_USE_DAILY_STREAK == 2 @@ -447,13 +468,14 @@ static void get_result(wordle_state_t *state) { return; } if (++state->attempt >= WORDLE_MAX_ATTEMPTS) { - reset_all_elements(state); - state->curr_screen = SCREEN_LOSE; + state->curr_screen = WORDLE_SCREEN_LOSE; + win_lose_shared(state); state->streak = 0; return; } update_known_wrong_letters(state); - state->curr_screen = SCREEN_RESULT; + state->curr_screen = WORDLE_SCREEN_RESULT; + state->ignore_btn_ticks = WORDLE_TICKS_RESULT; return; } @@ -476,21 +498,7 @@ static void insert_random_guess(wordle_state_t *state) { } #endif -void wordle_face_setup(uint8_t watch_face_index, void ** context_ptr) { - (void) watch_face_index; - if (*context_ptr == NULL) { - *context_ptr = malloc(sizeof(wordle_state_t)); - memset(*context_ptr, 0, sizeof(wordle_state_t)); - wordle_state_t *state = (wordle_state_t *)*context_ptr; - state->curr_screen = SCREEN_TITLE; - state->skip_wrong_letter = false; - reset_all_elements(state); - } - // Do any pin or peripheral setup here; this will be called whenever the watch wakes from deep sleep. -} - -void wordle_face_activate(void *context) { - wordle_state_t *state = (wordle_state_t *)context; +static void _activate(wordle_state_t *state) { #if WORDLE_USE_DAILY_STREAK != 0 uint32_t now = get_day_unix_time(); uint32_t one_day = 60 *60 * 24; @@ -501,35 +509,58 @@ void wordle_face_activate(void *context) { } #endif state->using_random_guess = false; - if (is_playing(state) && state->curr_screen >= SCREEN_RESULT) { + if (is_playing(state) && state->curr_screen >= WORDLE_SCREEN_RESULT) { reset_incorrect_elements(state); state->position = get_first_pos(state->word_elements_result); } - movement_request_tick_frequency(2); + movement_request_tick_frequency(WORDLE_FREQ); + watch_clear_all_indicators(); + watch_clear_colon(); display_title(state); } +void wordle_face_setup(uint8_t watch_face_index, void ** context_ptr) { + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(wordle_state_t)); + memset(*context_ptr, 0, sizeof(wordle_state_t)); + wordle_state_t *state = (wordle_state_t *)*context_ptr; + state->curr_screen = WORDLE_SCREEN_TITLE; + state->skip_wrong_letter = true; + reset_all_elements(state); + memset(state->not_to_use, 0xff, sizeof(state->not_to_use)); + } + // Do any pin or peripheral setup here; this will be called whenever the watch wakes from deep sleep. +} + +void wordle_face_activate(void *context) { + wordle_state_t *state = (wordle_state_t *)context; + _activate(state); + +} + bool wordle_face_loop(movement_event_t event, void *context) { wordle_state_t *state = (wordle_state_t *)context; switch (event.event_type) { case EVENT_TICK: + if (state->ignore_btn_ticks > 0) state->ignore_btn_ticks--; switch (state->curr_screen) { - case SCREEN_PLAYING: + case WORDLE_SCREEN_PLAYING: if (event.subsecond % 2) { display_letter(state, true); } else { watch_display_string(" ", state->position + 5); } break; - case SCREEN_RESULT: + case WORDLE_SCREEN_RESULT: display_result(state, event.subsecond); break; - case SCREEN_LOSE: + case WORDLE_SCREEN_LOSE: display_lose(state, event.subsecond); break; - case SCREEN_WIN: + case WORDLE_SCREEN_WIN: display_win(state, event.subsecond); break; default: @@ -542,12 +573,12 @@ bool wordle_face_loop(movement_event_t event, void *context) { display_letter(state, true); break; case EVENT_LIGHT_LONG_PRESS: - if (state->curr_screen < SCREEN_PLAYING) { + if (state->curr_screen < WORDLE_SCREEN_PLAYING) { state->skip_wrong_letter = !state->skip_wrong_letter; show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); break; } - if (state->curr_screen != SCREEN_PLAYING) break; + if (state->curr_screen != WORDLE_SCREEN_PLAYING) break; get_prev_letter(state->position, state->word_elements, state->known_wrong_letters, state->skip_wrong_letter); display_letter(state, true); break; @@ -569,7 +600,7 @@ bool wordle_face_loop(movement_event_t event, void *context) { } break; case EVENT_ALARM_LONG_PRESS: - if (state->curr_screen != SCREEN_PLAYING) break; + if (state->curr_screen != WORDLE_SCREEN_PLAYING) break; display_letter(state, true); state->position = get_prev_pos(state->position, state->word_elements_result); break; @@ -577,17 +608,24 @@ bool wordle_face_loop(movement_event_t event, void *context) { case EVENT_ACTIVATE: break; case EVENT_TIMEOUT: - if (state->curr_screen >= SCREEN_RESULT) { + if (state->curr_screen >= WORDLE_SCREEN_RESULT) { reset_incorrect_elements(state); state->position = get_first_pos(state->word_elements_result); display_title(state); } break; case EVENT_LOW_ENERGY_UPDATE: - if (state->curr_screen != SCREEN_TITLE) + if (state->curr_screen != WORDLE_SCREEN_TITLE) display_title(state); break; - default: + case EVENT_MODE_LONG_PRESS: + if (state->curr_screen >= WORDLE_SCREEN_PLAYING) { + _activate(state); + } else { + movement_move_to_face(0); + } + break; + default: return movement_default_loop_handler(event); } return true; diff --git a/watch-faces/complication/wordle_face.h b/watch-faces/complication/wordle_face.h index 5cc2f09a..e4f7d0f9 100644 --- a/watch-faces/complication/wordle_face.h +++ b/watch-faces/complication/wordle_face.h @@ -83,7 +83,15 @@ * 2 = Allow using a random guess of any value that can be an answer where all of its letters are unique * 3 = Allow using a random guess of any value that can be an answer, and it's considered one of the best initial choices. */ -#define WORDLE_USE_RANDOM_GUESS 2 +#define WORDLE_USE_RANDOM_GUESS 3 +#define WORDLE_FREQ 2 +// To avoid a button press immedietly skipping a screen, we wait this many ticks +#define WORDLE_TICKS_RESULT 4 +#define WORDLE_TICK_WIN_LOSE 2 +#define WORDLE_TICK_BAD_GUESS 0 + +// Store this many words in our list of words that were already used to avoid too much repetition of guesses +#define WORDLE_MAX_BETWEEN_REPEATS 50 #include "wordle_face_dict.h" #define WORDLE_NUM_WORDS (sizeof(_valid_words) / sizeof(_valid_words[0])) @@ -95,28 +103,34 @@ typedef enum { WORDLE_LETTER_WRONG_LOC, WORDLE_LETTER_CORRECT, WORDLE_LETTER_COUNT -} WordleLetterResult; +} wordle_letter_result; typedef enum { - SCREEN_TITLE = 0, - SCREEN_STREAK, - SCREEN_CONTINUE, + WORDLE_SCREEN_TITLE = 0, + WORDLE_SCREEN_STREAK, + WORDLE_SCREEN_CONTINUE, #if WORDLE_USE_DAILY_STREAK - SCREEN_WAIT, + WORDLE_SCREEN_WAIT, #endif - SCREEN_PLAYING, - SCREEN_RESULT, - SCREEN_WIN, - SCREEN_LOSE, - SCREEN_NO_DICT, - SCREEN_ALREADY_GUESSED, - SCREEN_COUNT -} WordleScreen; + WORDLE_SCREEN_PLAYING, + WORDLE_SCREEN_RESULT, + WORDLE_SCREEN_WIN, + WORDLE_SCREEN_LOSE, + WORDLE_SCREEN_NO_DICT, + WORDLE_SCREEN_ALREADY_GUESSED, + WORDLE_SCREEN_COUNT +} wordle_screen; + +typedef enum { + BTN_MODE = 0, + BTN_ALARM, + BTN_LIGHT, +} wordle_pin_enum; typedef struct { // Anything you need to keep track of, put it here! uint8_t word_elements[WORDLE_LENGTH]; - WordleLetterResult word_elements_result[WORDLE_LENGTH]; + wordle_letter_result word_elements_result[WORDLE_LENGTH]; #if !WORDLE_ALLOW_NON_WORD_AND_REPEAT_GUESSES uint16_t guessed_words[WORDLE_MAX_ATTEMPTS]; #endif @@ -127,9 +141,12 @@ typedef struct { bool continuing : 1; bool skip_wrong_letter : 1; uint8_t streak; - WordleScreen curr_screen; + wordle_screen curr_screen; bool known_wrong_letters[WORDLE_NUM_VALID_LETTERS]; uint32_t day_last_game_started; + uint8_t ignore_btn_ticks; + uint16_t not_to_use[WORDLE_MAX_BETWEEN_REPEATS]; + uint8_t not_to_use_position; } wordle_state_t; void wordle_face_setup(uint8_t watch_face_index, void ** context_ptr); @@ -146,4 +163,3 @@ void wordle_face_resign(void *context); }) #endif // WORDLE_FACE_H_ - From befa570a9a3f59ce1a3011734d33b8e340c0fd4f Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Wed, 9 Jul 2025 07:48:59 -0400 Subject: [PATCH 3/8] Updated print logic for second movement --- watch-faces/complication/wordle_face.c | 82 +++++++++++++++----------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index 4873b5a1..c3a2e69a 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -26,6 +26,7 @@ #include #include "wordle_face.h" #include "watch_utility.h" +#include "watch_common_display.h" static uint32_t get_random(uint32_t max) { #if __EMSCRIPTEN__ @@ -75,21 +76,21 @@ static void get_prev_letter(const uint8_t curr_pos, uint8_t *word_elements, cons } static void display_letter(wordle_state_t *state, bool display_dash) { - char buf[1 + 1]; + char buf[3]; if (state->word_elements[state->position] >= WORDLE_NUM_VALID_LETTERS) { if (display_dash) - watch_display_string("-", state->position + 5); + watch_display_character('-', state->position + 5); else - watch_display_string(" ", state->position + 5); + watch_display_character(' ', state->position + 5); return; } sprintf(buf, "%c", _valid_letters[state->word_elements[state->position]]); - watch_display_string(buf, state->position + 5); + watch_display_character(buf[0], state->position + 5); } static void display_all_letters(wordle_state_t *state) { uint8_t prev_pos = state->position; - watch_display_string(" ", 4); + watch_display_character(' ', 4); for (size_t i = 0; i < WORDLE_LENGTH; i++) { state->position = i; display_letter(state, false); @@ -100,13 +101,13 @@ static void display_all_letters(wordle_state_t *state) { #if !WORDLE_ALLOW_NON_WORD_AND_REPEAT_GUESSES static void display_not_in_dict(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_NO_DICT; - watch_display_string("nodict", 4); + watch_display_text(WATCH_POSITION_BOTTOM, "nodict"); state->ignore_btn_ticks = WORDLE_TICK_BAD_GUESS; } static void display_already_guessed(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_ALREADY_GUESSED; - watch_display_string("GUESSD", 4); + watch_display_text(WATCH_POSITION_BOTTOM, "GUESSD"); state->ignore_btn_ticks = WORDLE_TICK_BAD_GUESS; } @@ -169,9 +170,9 @@ static bool check_word(wordle_state_t *state) { static void show_skip_wrong_letter_indicator(bool skipping, wordle_screen curr_screen) { if (curr_screen >= WORDLE_SCREEN_PLAYING) return; if (skipping) - watch_display_string("H", 3); + watch_display_character('H', 3); else - watch_display_string(" ", 3); + watch_display_character(' ', 3); } static void update_known_wrong_letters(wordle_state_t *state) { @@ -199,7 +200,7 @@ static void update_known_wrong_letters(wordle_state_t *state) { static void display_attempt(uint8_t attempt) { char buf[3]; sprintf(buf, "%d", attempt+1); - watch_display_string(buf, 3); + watch_display_character(buf[0], 3); } static void display_playing(wordle_state_t *state) { @@ -247,7 +248,7 @@ static void reset_board(wordle_state_t *state) { watch_clear_colon(); state->position = get_first_pos(state->word_elements_result); display_playing(state); - watch_display_string(" -", 4); + watch_display_character('-', 5); #if __EMSCRIPTEN__ printf("ANSWER: %s\r\n", _valid_words[state->curr_answer]); #endif @@ -255,35 +256,39 @@ static void reset_board(wordle_state_t *state) { static void display_title(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_TITLE; - watch_display_string("WO WordLE", 0); + watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); + watch_display_text(WATCH_POSITION_BOTTOM, "WordLE"); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } #if WORDLE_USE_DAILY_STREAK != 2 static void display_continue_result(bool continuing) { - watch_display_string(continuing ? "y" : "n", 9); + watch_display_character(continuing ? 'y' : 'n', 9); } static void display_continue(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_CONTINUE; - watch_display_string("Cont ", 4); + watch_display_text(WATCH_POSITION_BOTTOM, "Cont "); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); display_continue_result(state->continuing); } #endif static void display_streak(wordle_state_t *state) { - char buf[12]; + char buf[10]; state->curr_screen = WORDLE_SCREEN_STREAK; #if WORDLE_USE_DAILY_STREAK == 2 if (state->streak > 99) - sprintf(buf, "WO St--dy"); + sprintf(buf, "St--dy"); else - sprintf(buf, "WO St%2ddy", state->streak); + sprintf(buf, "St%2ddy", state->streak); #else - sprintf(buf, "WO St%4d", state->streak); + sprintf(buf, "St%4d", state->streak); #endif - watch_display_string(buf, 0); + watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); + watch_display_text(WATCH_POSITION_BOTTOM, buf); watch_set_colon(); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } @@ -292,13 +297,15 @@ static void display_streak(wordle_state_t *state) { static void display_wait(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_WAIT; if (state->streak < 40) { - char buf[13]; - sprintf(buf,"WO%2d WaIt ", state->streak); - watch_display_string(buf, 0); + char buf[5]; + sprintf(buf,"%2d", state->streak); + watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); } else { // Streak too long to display in top-right - watch_display_string("WO WaIt ", 0); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); } + watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text(WATCH_POSITION_BOTTOM, " WaIt "); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } #endif @@ -312,16 +319,18 @@ static uint32_t get_day_unix_time(void) { } static void display_lose(wordle_state_t *state, uint8_t subsecond) { - char buf[WORDLE_LENGTH + 6]; - sprintf(buf,"L %s", subsecond % 2 ? _valid_words[state->curr_answer] : " "); - watch_display_string(buf, 0); + char buf[10]; + sprintf(buf," %s", subsecond % 2 ? _valid_words[state->curr_answer] : " "); + watch_display_text(WATCH_POSITION_TOP, "L "); + watch_display_text(WATCH_POSITION_BOTTOM, buf); } static void display_win(wordle_state_t *state, uint8_t subsecond) { (void) state; - char buf[13]; - sprintf(buf,"W %s ", subsecond % 2 ? "NICE" : "JOb "); - watch_display_string(buf, 0); + char buf[10]; + sprintf(buf," %s ", subsecond % 2 ? "NICE" : "JOb "); + watch_display_text(WATCH_POSITION_TOP, "W "); + watch_display_text(WATCH_POSITION_BOTTOM, buf); } static bool is_playing(const wordle_state_t *state) { @@ -334,27 +343,28 @@ static bool is_playing(const wordle_state_t *state) { } static void display_result(wordle_state_t *state, uint8_t subsecond) { - char buf[WORDLE_LENGTH + 1]; + char buf[10]; + buf[0] = ' '; for (size_t i = 0; i < WORDLE_LENGTH; i++) { switch (state->word_elements_result[i]) { case WORDLE_LETTER_WRONG: - buf[i] = '-'; + buf[i+1] = '-'; break; case WORDLE_LETTER_CORRECT: - buf[i] = _valid_letters[state->word_elements[i]]; + buf[i+1] = _valid_letters[state->word_elements[i]]; break; case WORDLE_LETTER_WRONG_LOC: if (subsecond % 2) - buf[i] = ' '; + buf[i+1] = ' '; else - buf[i] = _valid_letters[state->word_elements[i]]; + buf[i+1] = _valid_letters[state->word_elements[i]]; default: break; } } - watch_display_string(buf, 5); + watch_display_text(WATCH_POSITION_BOTTOM, buf); } static bool act_on_btn(wordle_state_t *state, const wordle_pin_enum pin) { @@ -551,7 +561,7 @@ bool wordle_face_loop(movement_event_t event, void *context) { if (event.subsecond % 2) { display_letter(state, true); } else { - watch_display_string(" ", state->position + 5); + watch_display_character(' ', state->position + 5); } break; case WORDLE_SCREEN_RESULT: From 7c4a498a96e02069b7677825c45e85ea5d703af3 Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Wed, 9 Jul 2025 07:52:42 -0400 Subject: [PATCH 4/8] Removed from watch_faces --- movement_config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/movement_config.h b/movement_config.h index c4cb8c36..0da8da43 100644 --- a/movement_config.h +++ b/movement_config.h @@ -29,7 +29,6 @@ const watch_face_t watch_faces[] = { clock_face, - wordle_face, world_clock_face, sunrise_sunset_face, moon_phase_face, From b68ec8410f2f1364016269014b3dda23b8e7ebf6 Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Sat, 16 Aug 2025 11:33:33 -0400 Subject: [PATCH 5/8] Fixed win/lose text --- watch-faces/complication/wordle_face.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index c3a2e69a..3ea9981b 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -321,15 +321,17 @@ static uint32_t get_day_unix_time(void) { static void display_lose(wordle_state_t *state, uint8_t subsecond) { char buf[10]; sprintf(buf," %s", subsecond % 2 ? _valid_words[state->curr_answer] : " "); - watch_display_text(WATCH_POSITION_TOP, "L "); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); + watch_display_text_with_fallback(WATCH_POSITION_TOP, "LOSE", "L "); watch_display_text(WATCH_POSITION_BOTTOM, buf); } static void display_win(wordle_state_t *state, uint8_t subsecond) { (void) state; char buf[10]; - sprintf(buf," %s ", subsecond % 2 ? "NICE" : "JOb "); - watch_display_text(WATCH_POSITION_TOP, "W "); + sprintf(buf," %s ", subsecond % 2 ? "NICE" : "JOb "); + watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WIN", "W "); watch_display_text(WATCH_POSITION_BOTTOM, buf); } From c5a71e0450cd1fdd17fb0349e075b20be2d26fce Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Tue, 19 Aug 2025 20:09:21 -0400 Subject: [PATCH 6/8] Fixed the Worlde text refresh --- watch-faces/complication/wordle_face.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index 3ea9981b..c71c0842 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -256,7 +256,7 @@ static void reset_board(wordle_state_t *state) { static void display_title(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_TITLE; - watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); watch_display_text(WATCH_POSITION_BOTTOM, "WordLE"); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); @@ -286,7 +286,7 @@ static void display_streak(wordle_state_t *state) { #else sprintf(buf, "St%4d", state->streak); #endif - watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); watch_display_text(WATCH_POSITION_BOTTOM, buf); watch_set_colon(); @@ -304,7 +304,7 @@ static void display_wait(wordle_state_t *state) { else { // Streak too long to display in top-right watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); } - watch_display_text(WATCH_POSITION_TOP_LEFT, "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); watch_display_text(WATCH_POSITION_BOTTOM, " WaIt "); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } From d87bf0d73b5db32729b7d7c14c0bcb0ccb832f2e Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Tue, 19 Aug 2025 20:10:37 -0400 Subject: [PATCH 7/8] Changed custom display to Wdl --- watch-faces/complication/wordle_face.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index c71c0842..4bc9fa15 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -256,7 +256,7 @@ static void reset_board(wordle_state_t *state) { static void display_title(wordle_state_t *state) { state->curr_screen = WORDLE_SCREEN_TITLE; - watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "Wdl", "WO"); watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); watch_display_text(WATCH_POSITION_BOTTOM, "WordLE"); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); @@ -286,7 +286,7 @@ static void display_streak(wordle_state_t *state) { #else sprintf(buf, "St%4d", state->streak); #endif - watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "Wdl", "WO"); watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); watch_display_text(WATCH_POSITION_BOTTOM, buf); watch_set_colon(); @@ -304,7 +304,7 @@ static void display_wait(wordle_state_t *state) { else { // Streak too long to display in top-right watch_display_text(WATCH_POSITION_TOP_RIGHT, " "); } - watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "WO ", "WO"); + watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "Wdl", "WO"); watch_display_text(WATCH_POSITION_BOTTOM, " WaIt "); show_skip_wrong_letter_indicator(state->skip_wrong_letter, state->curr_screen); } From cee51b8595cc6f0c6fb310ddb3f5836a3615b18c Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Sat, 22 Nov 2025 08:41:38 -0500 Subject: [PATCH 8/8] Removed extra newline at end --- watch-faces/complication/wordle_face.c | 1 - 1 file changed, 1 deletion(-) diff --git a/watch-faces/complication/wordle_face.c b/watch-faces/complication/wordle_face.c index 4bc9fa15..d63ef467 100644 --- a/watch-faces/complication/wordle_face.c +++ b/watch-faces/complication/wordle_face.c @@ -646,4 +646,3 @@ bool wordle_face_loop(movement_event_t event, void *context) { void wordle_face_resign(void *context) { (void) context; } -