From b83918c7d3c0925de8d7efa35934a8ad2dc39f7f Mon Sep 17 00:00:00 2001 From: boerge1 Date: Thu, 21 Mar 2024 17:09:56 +0100 Subject: [PATCH 1/3] Issue_182: Quiz game: do not repeat a question until no question remains --- src/poti.hpp | 1 - src/queue.hpp | 16 ++++++++++++ src/rotary_encoder.hpp | 1 - src/settings.hpp | 26 +++++++++---------- src/state_machine.cpp | 30 +++++++++++++++++++++- src/state_machine.hpp | 58 ++++++++++++++++++++++-------------------- 6 files changed, 88 insertions(+), 44 deletions(-) diff --git a/src/poti.hpp b/src/poti.hpp index ce745a4..020238f 100644 --- a/src/poti.hpp +++ b/src/poti.hpp @@ -11,7 +11,6 @@ class Poti: public CommandSource { public: Poti(const Settings& settings, Mp3& mp3); - virtual ~Poti() {} commandRaw getCommandRaw() override; private: diff --git a/src/queue.hpp b/src/queue.hpp index c4a62c4..c61b510 100644 --- a/src/queue.hpp +++ b/src/queue.hpp @@ -3,6 +3,22 @@ #include "array.hpp" +inline void setBit (uint8_t &v, uint8_t b) { v |= (1< +class bitfield { +public: + void setBit (uint8_t n) { uint8_t &v = bits[n/8]; ::setBit (v, n%8); } + void clearBit(uint8_t n) { uint8_t &v = bits[n/8]; ::clearBit(v, n%8); } + bool getBit (uint8_t n) { uint8_t &v = bits[n/8]; return ::getBit(v, n%8); } + void setAll (uint8_t v) { for (uint8_t i = 0; i < BITS/8+1; ++i) bits[i] = v; } + +private: + uint8_t bits[BITS/8+1]{}; +}; + template void swap(T &lhs, T &rhs) { const T t = lhs; diff --git a/src/rotary_encoder.hpp b/src/rotary_encoder.hpp index 9fcf54f..a60f565 100644 --- a/src/rotary_encoder.hpp +++ b/src/rotary_encoder.hpp @@ -19,7 +19,6 @@ class RotaryEncoder: public CommandSource { public: RotaryEncoder(const Settings& settings); - virtual ~RotaryEncoder() {} commandRaw getCommandRaw() override; static void changed(); diff --git a/src/settings.hpp b/src/settings.hpp index b965772..0ec32ec 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -31,19 +31,19 @@ struct Settings { folderSettings getShortCut(uint8_t shortCut); void setShortCut(uint8_t shortCut, const folderSettings& value); - uint32_t cookie; - byte version; - uint8_t maxVolume; - uint8_t minVolume; - uint8_t initVolume; - uint8_t eq; - uint8_t dummy; - uint32_t standbyTimer; - uint8_t invertVolumeButtons; - shortCuts_t shortCuts; - uint8_t adminMenuLocked; - pin_t adminMenuPin; - uint8_t pauseWhenCardRemoved; + uint32_t cookie {}; + byte version {}; + uint8_t maxVolume {}; + uint8_t minVolume {}; + uint8_t initVolume {}; + uint8_t eq {}; + uint8_t dummy {}; + uint32_t standbyTimer {}; + uint8_t invertVolumeButtons {}; + shortCuts_t shortCuts {}; + uint8_t adminMenuLocked {}; + pin_t adminMenuPin {}; + uint8_t pauseWhenCardRemoved{}; }; // emulates EEPROM.put() .get() and .update() on LGT8F328P platform diff --git a/src/state_machine.cpp b/src/state_machine.cpp index bda1e04..4e89acf 100644 --- a/src/state_machine.cpp +++ b/src/state_machine.cpp @@ -850,6 +850,8 @@ void Quiz::entry() { a.push(3); } + remainingQuestions = 0; + timer.start(timeout); if (numAnswer == 0) @@ -895,7 +897,33 @@ void Quiz::react(command_e const &cmd_e) { case QuizState::playQuestion: case QuizState::playSolution: case QuizState::playWeiter: - question = random(0, numQuestion); + if (remainingQuestions == 0) { + remainingQuestions = numQuestion; + r.setAll(0xFF); + } + question = random(0, remainingQuestions); + LOG(state_log, s_debug, F("random: "), question, F(", remain: "), remainingQuestions); + { + uint8_t i = 0; + while (true) { + if (question == 0) { + while (not r.getBit(i)) ++i; + question = i; + r.clearBit(i); + LOG(state_log, s_debug, F("question: "), question); + break; + } + if (r.getBit(i++)) { + --question; + } + } + } + --remainingQuestions; + LOG(state_log, s_debug, F("r: "), lf_no); + for (uint8_t i = 0; i a; + uint8_t numAnswer {}; + uint8_t numSolution {}; + QuizState quizState {}; + uint8_t question {}; + uint8_t trackQuestion{}; + uint8_t numQuestion {}; + uint8_t actAnswer {}; + queue a{}; + bitfield<128> r{}; // max in buzzer mode (num answer = 0, num solution = 1) + uint8_t remainingQuestions{}; static constexpr long timeout{ 5 * 60 * 1000l}; }; @@ -157,8 +159,8 @@ class Memory: public Base void finish(); - uint8_t first; - uint8_t second; + uint8_t first {}; + uint8_t second{}; static constexpr long timeout{ 5 * 60 * 1000l}; }; @@ -248,7 +250,7 @@ class WriteCard : public SM_writeCard end_writeCard, run_waitCardRemoved, }; - subState current_subState; + subState current_subState{}; }; class Admin_BaseSetting: public VoiceMenu_tonuino @@ -280,10 +282,10 @@ class Admin_Allow: public VoiceMenu_tonuino allow, not_allow, }; - subState current_subState; - Settings::pin_t pin; - uint8_t pin_number; -// uint8_t av, bv, cv; + subState current_subState{}; + Settings::pin_t pin {}; + uint8_t pin_number {}; +// uint8_t av{}, bv{}, cv{}; }; class Admin_Entry: public VoiceMenu_tonuino @@ -310,7 +312,7 @@ class Admin_NewCard: public Amin_BaseWriteCard start_writeCard, run_writeCard, }; - subState current_subState; + subState current_subState{}; }; class Admin_SimpleSetting: public Admin_BaseSetting @@ -333,13 +335,13 @@ class Admin_ModCard: public Amin_BaseWriteCard void entry() final; void react(command_e const &) final; private: - pmode_t mode; enum subState: uint8_t { start_writeCard, run_writeCard, }; - subState current_subState; - bool readyToWrite; + pmode_t mode {}; + subState current_subState{}; + bool readyToWrite {}; }; class Admin_ShortCut: public Admin_BaseSetting @@ -353,8 +355,8 @@ class Admin_ShortCut: public Admin_BaseSetting run_setupCard, end_setupCard, }; - subState current_subState; - uint8_t shortcut; + subState current_subState{}; + uint8_t shortcut {}; }; class Admin_StandbyTimer: public Admin_BaseSetting @@ -378,9 +380,9 @@ class Admin_CardsForFolder: public Amin_BaseWriteCard start_writeCard, run_writeCard, }; - subState current_subState; - uint8_t special; - uint8_t special2; + subState current_subState{}; + uint8_t special {}; + uint8_t special2 {}; }; class Admin_InvButtons: public Admin_BaseSetting @@ -408,9 +410,9 @@ class Admin_LockAdmin: public Admin_BaseSetting get_pin, finished, }; - subState current_subState; - Settings::pin_t pin; - uint8_t pin_number; + subState current_subState{}; + Settings::pin_t pin {}; + uint8_t pin_number {}; }; class Admin_PauseIfCardRemoved: public Admin_BaseSetting @@ -432,7 +434,7 @@ class Admin_MemoryGameCards: public Amin_BaseWriteCard start_writeCard, run_writeCard, }; - subState current_subState; + subState current_subState{}; }; #endif From 08462490ff0355683c74ed2df8daa698e9a1623c Mon Sep 17 00:00:00 2001 From: boerge1 Date: Thu, 21 Mar 2024 17:30:39 +0100 Subject: [PATCH 2/3] Issue_182: Quiz game: do not repeat a question until no question remains --- README.md | 3 +++ TonUINO-TNG.ino | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f5d0d14..f5d20d5 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,9 @@ Die SD Karte (Ordner mp3 und advert) hat sich gegenüber der Version 3.1.6 geän # Change Log +## Version 3.1.7 (21.03.2024) +- [Issue 182](https://github.com/tonuino/TonUINO-TNG/issues/182): Quiz game: do not repeat a question until no question remains + ## Version 3.1.7 (01.03.2024) - [Issue 176](https://github.com/tonuino/TonUINO-TNG/issues/176): Implement the memory game diff --git a/TonUINO-TNG.ino b/TonUINO-TNG.ino index 35151af..1a0b783 100644 --- a/TonUINO-TNG.ino +++ b/TonUINO-TNG.ino @@ -35,7 +35,7 @@ void setup() LOG(init_log, s_error, F("TonUINO Version 3.1 - refactored by Boerge1\n")); LOG(init_log, s_error, F("created by Thorsten Voß and licensed under GNU/GPL.")); LOG(init_log, s_error, F("Information and contribution at https://tonuino.de.\n")); - LOG(init_log, s_error, F("V3.1.7 01.03.24\n")); + LOG(init_log, s_error, F("V3.1.7 21.03.24\n")); Tonuino::getTonuino().setup(); } From 147f948718e9d5b2d768a6f81e57508cc39f6e54 Mon Sep 17 00:00:00 2001 From: boerge1 Date: Mon, 25 Mar 2024 12:12:10 +0100 Subject: [PATCH 3/3] Issue_182: Quiz game: do not repeat a question until no question remains * add possibility to increase/decrease volume if not playing the answers --- README.md | 2 +- TonUINO-TNG.ino | 2 +- src/state_machine.cpp | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f5d20d5..3e01965 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ Die SD Karte (Ordner mp3 und advert) hat sich gegenüber der Version 3.1.6 geän # Change Log -## Version 3.1.7 (21.03.2024) +## Version 3.1.7 (25.03.2024) - [Issue 182](https://github.com/tonuino/TonUINO-TNG/issues/182): Quiz game: do not repeat a question until no question remains ## Version 3.1.7 (01.03.2024) diff --git a/TonUINO-TNG.ino b/TonUINO-TNG.ino index 1a0b783..d823296 100644 --- a/TonUINO-TNG.ino +++ b/TonUINO-TNG.ino @@ -35,7 +35,7 @@ void setup() LOG(init_log, s_error, F("TonUINO Version 3.1 - refactored by Boerge1\n")); LOG(init_log, s_error, F("created by Thorsten Voß and licensed under GNU/GPL.")); LOG(init_log, s_error, F("Information and contribution at https://tonuino.de.\n")); - LOG(init_log, s_error, F("V3.1.7 21.03.24\n")); + LOG(init_log, s_error, F("V3.1.7 25.03.24\n")); Tonuino::getTonuino().setup(); } diff --git a/src/state_machine.cpp b/src/state_machine.cpp index 4e89acf..588c85e 100644 --- a/src/state_machine.cpp +++ b/src/state_machine.cpp @@ -968,6 +968,9 @@ void Quiz::react(command_e const &cmd_e) { mp3.enqueueTrack(tonuino.getFolder(), trackQuestion+actAnswer+1); } } + else { + mp3.increaseVolume(); + } break; case command::next: if (quizState == QuizState::playAnswer) { @@ -998,6 +1001,9 @@ void Quiz::react(command_e const &cmd_e) { mp3.enqueueTrack(tonuino.getFolder(), trackQuestion+actAnswer+1); } } + else { + mp3.decreaseVolume(); + } break; case command::previous: if (quizState == QuizState::playAnswer) {