feat: pogoda, poprawki w wyświetlaniu. Clean Architecture
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
#include <unity.h>
|
||||
#include "BuddyLogic.h"
|
||||
|
||||
static int32_t fixed_rng(int32_t lo, int32_t hi) { (void)hi; return lo; }
|
||||
|
||||
void setUp() {}
|
||||
void tearDown() {}
|
||||
|
||||
// ── initBuddy ──────────────────────────────────────────────────────────────
|
||||
|
||||
void test_initBuddy_sets_open_blink() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
TEST_ASSERT_EQUAL(BLINK_OPEN, b.blinkState);
|
||||
TEST_ASSERT_EQUAL(EYE_RY, b.blinkRy);
|
||||
}
|
||||
|
||||
void test_initBuddy_sets_normal_mood() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
TEST_ASSERT_EQUAL(MOOD_NORMAL, b.mood);
|
||||
}
|
||||
|
||||
void test_initBuddy_timestamps_relative_to_now() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 1000);
|
||||
TEST_ASSERT_EQUAL(1000u, b.lastEvent);
|
||||
TEST_ASSERT_EQUAL(1000u + 3000, b.nextBlink);
|
||||
TEST_ASSERT_EQUAL(1000u + 2000, b.nextLook);
|
||||
}
|
||||
|
||||
// ── setBuddyMood ───────────────────────────────────────────────────────────
|
||||
|
||||
void test_setBuddyMood_no_duration_sets_revertAt_zero() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 1000, 0);
|
||||
TEST_ASSERT_EQUAL(0u, b.revertAt);
|
||||
}
|
||||
|
||||
void test_setBuddyMood_with_duration_sets_revertAt() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 1000, 4000);
|
||||
TEST_ASSERT_EQUAL(5000u, b.revertAt);
|
||||
}
|
||||
|
||||
void test_setBuddyMood_updates_lastEvent() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 5000);
|
||||
TEST_ASSERT_EQUAL(5000u, b.lastEvent);
|
||||
}
|
||||
|
||||
void test_setBuddyMood_happy_sets_pupil_target_up() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 0);
|
||||
TEST_ASSERT_EQUAL( 0, b.pupilTargetDx);
|
||||
TEST_ASSERT_EQUAL(-2, b.pupilTargetDy);
|
||||
}
|
||||
|
||||
void test_setBuddyMood_sad_sets_pupil_target_down() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_SAD, 0);
|
||||
TEST_ASSERT_EQUAL(0, b.pupilTargetDx);
|
||||
TEST_ASSERT_EQUAL(4, b.pupilTargetDy);
|
||||
}
|
||||
|
||||
// ── updateBuddyAnim — mood revert ─────────────────────────────────────────
|
||||
|
||||
void test_updateBuddyAnim_reverts_mood_when_revertAt_passed() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 0, 4000); // revertAt = 4000
|
||||
updateBuddyAnim(b, 5000, fixed_rng); // now > revertAt
|
||||
TEST_ASSERT_EQUAL(MOOD_NORMAL, b.mood);
|
||||
TEST_ASSERT_EQUAL(0u, b.revertAt);
|
||||
}
|
||||
|
||||
void test_updateBuddyAnim_does_not_revert_before_revertAt() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_HAPPY, 0, 4000);
|
||||
updateBuddyAnim(b, 3999, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(MOOD_HAPPY, b.mood);
|
||||
}
|
||||
|
||||
void test_updateBuddyAnim_goes_sleepy_after_idle() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0); // lastEvent = 0, mood = NORMAL
|
||||
updateBuddyAnim(b, 300001, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(MOOD_SLEEPY, b.mood);
|
||||
}
|
||||
|
||||
void test_updateBuddyAnim_no_sleepy_before_idle() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
updateBuddyAnim(b, 299999, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(MOOD_NORMAL, b.mood);
|
||||
}
|
||||
|
||||
// ── Blink state machine ────────────────────────────────────────────────────
|
||||
|
||||
void test_blink_open_to_closing_when_nextBlink_passed() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0); // nextBlink = 3000
|
||||
updateBuddyAnim(b, 3001, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(BLINK_CLOSING, b.blinkState);
|
||||
}
|
||||
|
||||
void test_blink_closing_decrements_blinkRy() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.blinkState = BLINK_CLOSING;
|
||||
b.blinkRy = 15;
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(11, b.blinkRy);
|
||||
TEST_ASSERT_EQUAL(BLINK_CLOSING, b.blinkState);
|
||||
}
|
||||
|
||||
void test_blink_closing_reaches_closed_when_small() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.blinkState = BLINK_CLOSING;
|
||||
b.blinkRy = 3;
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(BLINK_CLOSED, b.blinkState);
|
||||
TEST_ASSERT_EQUAL(1, b.blinkRy);
|
||||
}
|
||||
|
||||
void test_blink_closed_ticks_to_opening() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.blinkState = BLINK_CLOSED;
|
||||
b.closedTicks = 2;
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(BLINK_OPENING, b.blinkState);
|
||||
}
|
||||
|
||||
void test_blink_opening_increments_blinkRy() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.blinkState = BLINK_OPENING;
|
||||
b.blinkRy = 7; // 7+4=11 < EYE_RY(15), stays OPENING
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(11, b.blinkRy);
|
||||
TEST_ASSERT_EQUAL(BLINK_OPENING, b.blinkState);
|
||||
}
|
||||
|
||||
void test_blink_opening_returns_to_open_at_eye_ry() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.blinkState = BLINK_OPENING;
|
||||
b.blinkRy = 13; // 13+4=17 >= EYE_RY(15) → OPEN
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(BLINK_OPEN, b.blinkState);
|
||||
TEST_ASSERT_EQUAL(EYE_RY, b.blinkRy);
|
||||
}
|
||||
|
||||
void test_surprised_does_not_blink() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
setBuddyMood(b, MOOD_SURPRISED, 0);
|
||||
b.nextBlink = 0; // past-due
|
||||
updateBuddyAnim(b, 1000, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(BLINK_OPEN, b.blinkState); // no transition
|
||||
TEST_ASSERT_EQUAL(EYE_RY, b.blinkRy); // stays full
|
||||
}
|
||||
|
||||
// ── Pupil saccade ──────────────────────────────────────────────────────────
|
||||
|
||||
void test_pupil_moves_fast_when_far() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.pupilDx = 0;
|
||||
b.pupilTargetDx = 8; // |delta| = 8 >= 4 → step 3
|
||||
b.pupilDy = b.pupilTargetDy = 0;
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(3, b.pupilDx);
|
||||
}
|
||||
|
||||
void test_pupil_moves_slow_when_close() {
|
||||
BuddyState b{};
|
||||
initBuddy(b, 0);
|
||||
b.pupilDx = 0;
|
||||
b.pupilTargetDx = 2; // |delta| = 2 < 4 → step 1
|
||||
b.pupilDy = b.pupilTargetDy = 0;
|
||||
updateBuddyAnim(b, 0, fixed_rng);
|
||||
TEST_ASSERT_EQUAL(1, b.pupilDx);
|
||||
}
|
||||
|
||||
// ── main ──────────────────────────────────────────────────────────────────
|
||||
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_initBuddy_sets_open_blink);
|
||||
RUN_TEST(test_initBuddy_sets_normal_mood);
|
||||
RUN_TEST(test_initBuddy_timestamps_relative_to_now);
|
||||
RUN_TEST(test_setBuddyMood_no_duration_sets_revertAt_zero);
|
||||
RUN_TEST(test_setBuddyMood_with_duration_sets_revertAt);
|
||||
RUN_TEST(test_setBuddyMood_updates_lastEvent);
|
||||
RUN_TEST(test_setBuddyMood_happy_sets_pupil_target_up);
|
||||
RUN_TEST(test_setBuddyMood_sad_sets_pupil_target_down);
|
||||
RUN_TEST(test_updateBuddyAnim_reverts_mood_when_revertAt_passed);
|
||||
RUN_TEST(test_updateBuddyAnim_does_not_revert_before_revertAt);
|
||||
RUN_TEST(test_updateBuddyAnim_goes_sleepy_after_idle);
|
||||
RUN_TEST(test_updateBuddyAnim_no_sleepy_before_idle);
|
||||
RUN_TEST(test_blink_open_to_closing_when_nextBlink_passed);
|
||||
RUN_TEST(test_blink_closing_decrements_blinkRy);
|
||||
RUN_TEST(test_blink_closing_reaches_closed_when_small);
|
||||
RUN_TEST(test_blink_closed_ticks_to_opening);
|
||||
RUN_TEST(test_blink_opening_increments_blinkRy);
|
||||
RUN_TEST(test_blink_opening_returns_to_open_at_eye_ry);
|
||||
RUN_TEST(test_surprised_does_not_blink);
|
||||
RUN_TEST(test_pupil_moves_fast_when_far);
|
||||
RUN_TEST(test_pupil_moves_slow_when_close);
|
||||
return UNITY_END();
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
#include <unity.h>
|
||||
#include "TamaLogic.h"
|
||||
|
||||
void setUp() {}
|
||||
void tearDown() {}
|
||||
|
||||
// Helper: build a minimal BuddyState for updateTama calls
|
||||
static BuddyState makeBuddy(uint32_t revertAt = 0, Mood m = MOOD_NORMAL) {
|
||||
BuddyState b{};
|
||||
b.revertAt = revertAt;
|
||||
b.mood = m;
|
||||
return b;
|
||||
}
|
||||
|
||||
// ── initTama ──────────────────────────────────────────────────────────────
|
||||
|
||||
void test_initTama_sets_initial_values() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
TEST_ASSERT_EQUAL(10, t.hunger);
|
||||
TEST_ASSERT_EQUAL(80, t.happiness);
|
||||
TEST_ASSERT_EQUAL(90, t.hygiene);
|
||||
}
|
||||
|
||||
void test_initTama_sets_tick_timestamps() {
|
||||
TamaState t{};
|
||||
initTama(t, 1000);
|
||||
TEST_ASSERT_EQUAL(1000u + 120000u, t.nextHungerTick);
|
||||
TEST_ASSERT_EQUAL(1000u + 180000u, t.nextHappyTick);
|
||||
TEST_ASSERT_EQUAL(1000u + 240000u, t.nextHygieneTick);
|
||||
}
|
||||
|
||||
// ── updateTama ticks ──────────────────────────────────────────────────────
|
||||
|
||||
void test_updateTama_increments_hunger_on_tick() {
|
||||
TamaState t{};
|
||||
initTama(t, 0); // nextHungerTick = 120000
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 120000);
|
||||
TEST_ASSERT_EQUAL(11, t.hunger);
|
||||
}
|
||||
|
||||
void test_updateTama_does_not_increment_hunger_before_tick() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 119999);
|
||||
TEST_ASSERT_EQUAL(10, t.hunger);
|
||||
}
|
||||
|
||||
void test_updateTama_caps_hunger_at_100() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.hunger = 100;
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 120000);
|
||||
TEST_ASSERT_EQUAL(100, t.hunger);
|
||||
}
|
||||
|
||||
void test_updateTama_decrements_happiness_on_tick() {
|
||||
TamaState t{};
|
||||
initTama(t, 0); // nextHappyTick = 180000
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 180000);
|
||||
TEST_ASSERT_EQUAL(79, t.happiness);
|
||||
}
|
||||
|
||||
void test_updateTama_caps_happiness_at_zero() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.happiness = 0;
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 180000);
|
||||
TEST_ASSERT_EQUAL(0, t.happiness);
|
||||
}
|
||||
|
||||
void test_updateTama_decrements_hygiene_on_tick() {
|
||||
TamaState t{};
|
||||
initTama(t, 0); // nextHygieneTick = 240000
|
||||
BuddyState b = makeBuddy();
|
||||
updateTama(t, b, 240000);
|
||||
TEST_ASSERT_EQUAL(89, t.hygiene);
|
||||
}
|
||||
|
||||
// ── updateTama mood returns ───────────────────────────────────────────────
|
||||
|
||||
void test_updateTama_returns_hungry_when_hunger_high() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.hunger = 80;
|
||||
t.nextHungerTick = 999999; // prevent tick
|
||||
BuddyState b = makeBuddy();
|
||||
TEST_ASSERT_EQUAL(MOOD_HUNGRY, updateTama(t, b, 0));
|
||||
}
|
||||
|
||||
void test_updateTama_returns_dirty_when_hygiene_low() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.hygiene = 20;
|
||||
t.nextHygieneTick = 999999;
|
||||
BuddyState b = makeBuddy();
|
||||
TEST_ASSERT_EQUAL(MOOD_DIRTY, updateTama(t, b, 0));
|
||||
}
|
||||
|
||||
void test_updateTama_returns_playful_when_happiness_low() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.happiness = 20;
|
||||
t.nextHappyTick = 999999;
|
||||
BuddyState b = makeBuddy();
|
||||
TEST_ASSERT_EQUAL(MOOD_PLAYFUL, updateTama(t, b, 0));
|
||||
}
|
||||
|
||||
void test_updateTama_no_override_when_revertAt_set() {
|
||||
TamaState t{};
|
||||
initTama(t, 0);
|
||||
t.hunger = 90;
|
||||
t.nextHungerTick = 999999;
|
||||
BuddyState b = makeBuddy(5000); // revertAt != 0 → guard blocks
|
||||
TEST_ASSERT_EQUAL(MOOD_NORMAL, updateTama(t, b, 0));
|
||||
}
|
||||
|
||||
void test_updateTama_returns_normal_when_needs_ok() {
|
||||
TamaState t{};
|
||||
initTama(t, 0); // hunger=10, happy=80, hygiene=90 — all fine
|
||||
t.nextHungerTick = t.nextHappyTick = t.nextHygieneTick = 999999;
|
||||
BuddyState b = makeBuddy();
|
||||
TEST_ASSERT_EQUAL(MOOD_NORMAL, updateTama(t, b, 0));
|
||||
}
|
||||
|
||||
// ── tamaFeed ──────────────────────────────────────────────────────────────
|
||||
|
||||
void test_tamaFeed_reduces_hunger_by_30() {
|
||||
TamaState t{};
|
||||
t.hunger = 50;
|
||||
tamaFeed(t);
|
||||
TEST_ASSERT_EQUAL(20, t.hunger);
|
||||
}
|
||||
|
||||
void test_tamaFeed_floors_hunger_at_zero() {
|
||||
TamaState t{};
|
||||
t.hunger = 10;
|
||||
tamaFeed(t);
|
||||
TEST_ASSERT_EQUAL(0, t.hunger);
|
||||
}
|
||||
|
||||
// ── tamaPlay ──────────────────────────────────────────────────────────────
|
||||
|
||||
void test_tamaPlay_increases_happiness_by_25() {
|
||||
TamaState t{};
|
||||
t.happiness = 50;
|
||||
tamaPlay(t);
|
||||
TEST_ASSERT_EQUAL(75, t.happiness);
|
||||
}
|
||||
|
||||
void test_tamaPlay_caps_happiness_at_100() {
|
||||
TamaState t{};
|
||||
t.happiness = 90;
|
||||
tamaPlay(t);
|
||||
TEST_ASSERT_EQUAL(100, t.happiness);
|
||||
}
|
||||
|
||||
// ── tamaClean ─────────────────────────────────────────────────────────────
|
||||
|
||||
void test_tamaClean_increases_hygiene_by_40() {
|
||||
TamaState t{};
|
||||
t.hygiene = 50;
|
||||
tamaClean(t);
|
||||
TEST_ASSERT_EQUAL(90, t.hygiene);
|
||||
}
|
||||
|
||||
void test_tamaClean_caps_hygiene_at_100() {
|
||||
TamaState t{};
|
||||
t.hygiene = 80;
|
||||
tamaClean(t);
|
||||
TEST_ASSERT_EQUAL(100, t.hygiene);
|
||||
}
|
||||
|
||||
// ── main ──────────────────────────────────────────────────────────────────
|
||||
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_initTama_sets_initial_values);
|
||||
RUN_TEST(test_initTama_sets_tick_timestamps);
|
||||
RUN_TEST(test_updateTama_increments_hunger_on_tick);
|
||||
RUN_TEST(test_updateTama_does_not_increment_hunger_before_tick);
|
||||
RUN_TEST(test_updateTama_caps_hunger_at_100);
|
||||
RUN_TEST(test_updateTama_decrements_happiness_on_tick);
|
||||
RUN_TEST(test_updateTama_caps_happiness_at_zero);
|
||||
RUN_TEST(test_updateTama_decrements_hygiene_on_tick);
|
||||
RUN_TEST(test_updateTama_returns_hungry_when_hunger_high);
|
||||
RUN_TEST(test_updateTama_returns_dirty_when_hygiene_low);
|
||||
RUN_TEST(test_updateTama_returns_playful_when_happiness_low);
|
||||
RUN_TEST(test_updateTama_no_override_when_revertAt_set);
|
||||
RUN_TEST(test_updateTama_returns_normal_when_needs_ok);
|
||||
RUN_TEST(test_tamaFeed_reduces_hunger_by_30);
|
||||
RUN_TEST(test_tamaFeed_floors_hunger_at_zero);
|
||||
RUN_TEST(test_tamaPlay_increases_happiness_by_25);
|
||||
RUN_TEST(test_tamaPlay_caps_happiness_at_100);
|
||||
RUN_TEST(test_tamaClean_increases_hygiene_by_40);
|
||||
RUN_TEST(test_tamaClean_caps_hygiene_at_100);
|
||||
return UNITY_END();
|
||||
}
|
||||
Reference in New Issue
Block a user