#include "game_logic.h" #include #include #include #include void update_snake(GameState &state) { std::array headpos = state.snake.front(); std::array newHead = headpos; if (state.snakeDirection == 0) { newHead = {headpos[0], headpos[1] - 1, state.snakeDirection}; } else if (state.snakeDirection == 1) { newHead = {headpos[0] + 1, headpos[1], state.snakeDirection}; } else if (state.snakeDirection == 2) { newHead = {headpos[0], headpos[1] + 1, state.snakeDirection}; } else if (state.snakeDirection == 3) { newHead = {headpos[0] - 1, headpos[1], state.snakeDirection}; } if (newHead[0] > X_MAX) { newHead[0] = 0; } if (newHead[1] > Y_MAX) { newHead[1] = 0; } if (newHead[0] < 0) { newHead[0] = X_MAX; } if (newHead[1] < 0) { newHead[1] = Y_MAX; } state.snake.push_front(newHead); state.snake.resize(state.snakelength); } bool check_collision_self(GameState &state) { if (state.snake.size() < 2 || state.gameOver) { return false; } const std::array headpos = state.snake.front(); for (auto it = state.snake.begin() + 1; it != state.snake.end(); ++it) { if ((*it)[0] == headpos[0] && (*it)[1] == headpos[1]) { state.gameOver = true; return true; } } return false; } bool check_collision_apples(GameState &state) { const std::array headpos = state.snake.front(); auto it = std::find_if(state.apples.begin(), state.apples.end(), [&](const std::array &apple) { return apple[0] == headpos[0] && apple[1] == headpos[1]; }); if (it == state.apples.end()) { return false; } state.score += APPLE_SCORE; state.snakelength++; state.applesEaten++; state.apples.erase(it); return true; } bool check_collision_apples_rotten(GameState &state) { const std::array headpos = state.snake.front(); auto it = std::find_if(state.bad_apples.begin(), state.bad_apples.end(), [&](const std::array &apple) { return apple[0] == headpos[0] && apple[1] == headpos[1]; }); if (it == state.bad_apples.end()) { return false; } state.snakelength--; state.bad_apples.erase(it); if (state.snakelength < 2) { state.gameOver = true; } return true; } bool check_collision_apples_cursed(GameState &state) { const std::array headpos = state.snake.front(); auto it = std::find_if(state.cursed_apples.begin(), state.cursed_apples.end(), [&](const std::array &apple) { return apple[0] == headpos[0] && apple[1] == headpos[1]; }); if (it == state.cursed_apples.end()) { return false; } state.cursed_apples.erase(it); state.curseTicksRemaining = CURSE_DURATION_TICKS; return true; } void spawn_apples(GameState &state) { if (state.apples.size() < 1) { std::array apple = {rand() % (X_MAX + 1), rand() % (Y_MAX + 1)}; state.apples.push_back(apple); } } void spawn_apples_rotten(GameState &state) { if ((state.ticks % 10 == 0) && state.hardMode && ((rand() % 10) < 10) && (state.bad_apples.size() < 20)) { std::array badApple = {rand() % (X_MAX + 1), rand() % (Y_MAX + 1)}; state.bad_apples.push_back(badApple); } } void spawn_apples_cursed(GameState &state) { if (state.cursed_apples.empty() && (state.ticks % 20 == 0) && ((rand() % 5) == 0)) { std::array cursedApple = {rand() % (X_MAX + 1), rand() % (Y_MAX + 1)}; state.cursed_apples.push_back(cursedApple); } } void tick_status_effects(GameState &state) { if (state.curseTicksRemaining > 0) { state.curseTicksRemaining--; } } uint8_t calculate_intensity_31(const GameState &state) { const uint16_t current_apples = state.applesEaten; const uint16_t apples = std::min(current_apples, static_cast(SPEED_APPLES_CAP)); return static_cast((static_cast(apples) * 31U) / static_cast(SPEED_APPLES_CAP)); } uint16_t calculate_timer_freq_mhz(const GameState &state) { const uint16_t base_mhz = state.hardMode ? SPEED_BASE_HARD_MHZ : SPEED_BASE_NORMAL_MHZ; const uint16_t max_mhz = state.hardMode ? SPEED_MAX_HARD_MHZ : SPEED_MAX_NORMAL_MHZ; const uint16_t current_apples = state.applesEaten; const uint16_t apples = std::min(current_apples, static_cast(SPEED_APPLES_CAP)); const uint32_t diff = static_cast(max_mhz - base_mhz); return static_cast( base_mhz + ((static_cast(apples) * diff) / static_cast(SPEED_APPLES_CAP))); } uint16_t calculate_timer_reload(const GameState &state) { const uint32_t freq_mhz = calculate_timer_freq_mhz(state); // Timer clock with ClockDivider_1024 is BUS_CLOCK >> 10 (32728 Hz) const uint32_t timer_clock_mhz = (BUS_CLOCK >> 10U) * 1000U; const uint32_t period_ticks = timer_clock_mhz / freq_mhz; return static_cast(-static_cast(period_ticks)); }