From 684041b3c1d38872aed62822b7a0b1580b22eced Mon Sep 17 00:00:00 2001 From: DarthMooMancer <107283522+DarthMooMancer@users.noreply.github.com> Date: Fri, 29 Aug 2025 17:25:09 -0400 Subject: [PATCH] feat: (snake) collision with head and body --- include/input.hpp | 4 ++-- include/snake.hpp | 1 + include/window.hpp | 5 +++-- src/input.cpp | 29 ++++++++++++----------------- src/main.cpp | 15 +++++++-------- src/snake.cpp | 10 ++++++++++ src/window.cpp | 29 ++++++++++++++++++++--------- 7 files changed, 55 insertions(+), 38 deletions(-) diff --git a/include/input.hpp b/include/input.hpp index 8846585..68abbfb 100644 --- a/include/input.hpp +++ b/include/input.hpp @@ -2,9 +2,9 @@ #define INPUT_HPP struct Input { - char m_current_key = ' '; + int m_current_key = 0; char m_getch = ' '; - void get_input(int &d, bool &r); + void get_input(int &d, bool &c, bool &r); }; #endif // INPUT_HPP diff --git a/include/snake.hpp b/include/snake.hpp index be3d70a..5bfcad9 100644 --- a/include/snake.hpp +++ b/include/snake.hpp @@ -26,6 +26,7 @@ struct Body { void draw(std::array, ROW> &arr); void move(Head &head); void get_new_points(Head &head); + void collision(Head &head, bool &running); }; #endif diff --git a/include/window.hpp b/include/window.hpp index 708ef3b..2f99804 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -12,12 +12,13 @@ struct Window { int m_reset; int m_previous_reset; - void draw_score(); void draw_window(); void clear_window(); void tick(double frames_per_second); + void kill(bool &running); void update_score(Fruit &fruit, Body &body); - void update_loop(int fps); + void update_display(int fps); + void check_exit(bool &running, Body &body, bool &collision); }; #endif // WINDOW_HPP diff --git a/src/input.cpp b/src/input.cpp index c7b2fc0..f00f3fa 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,32 +1,27 @@ #include "input.hpp" #include -void Input::get_input(int &d, bool &r) { +void Input::get_input(int &d, bool &c, bool &r) { bool running = true; - while(running) { + while(running && !(c)) { initscr(); cbreak(); noecho(); m_getch = getch(); endwin(); - // TODO - // m_current_key should be the m_getch and then as long as the opposite doesnt equal m_current_key - if(m_getch == 'a' || m_getch == 'D') { - d = -1; - m_current_key = -1; - } else if(m_getch == 'd' || m_getch == 'C') { - d = 1; + if(m_current_key != 1 && (m_getch == 'a' || m_getch == 'D')) { + d = m_current_key = -1; + } else if(m_current_key != - 1 && (m_getch == 'd' || m_getch == 'C')) { + d = m_current_key = 1; m_current_key = 1; - } else if(m_getch == 's' || m_getch == 'B') { - d = 2; - m_current_key = m_getch; - } else if(m_getch == 'w' || m_getch == 'A') { - d = -2; - m_current_key = m_getch; + } else if(m_current_key != -2 && (m_getch == 's' || m_getch == 'B')) { + d = m_current_key = 2; + } else if(m_current_key != 2 && (m_getch == 'w' || m_getch == 'A')) { + d = m_current_key = -2; } else if(m_getch == 'q') { - r = false; - running = false; + r = running = false; } } + } diff --git a/src/main.cpp b/src/main.cpp index c0e6638..612c809 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,4 @@ -#include #include -#include -#include #include "point.hpp" #include "fruit.hpp" #include "snake.hpp" @@ -16,25 +13,27 @@ int main (int argc, char *argv[]) { Body body; Head head { 2, 0, 0 }; bool running = true; + bool collision = false; std::thread input_thread( &Input::get_input, &input, std::ref(head.m_head.m_direction), + std::ref(collision), std::ref(running)); - while (running) { + body.collision(head, collision); window.update_score(fruit, body); + window.check_exit(running, body, collision); + head.get_new_point(head.m_head.m_direction); body.get_new_points(head); head.get_previous_point(); - fruit.reset(window.m_board, head.m_head.m_row, head.m_head.m_col, window.m_score); + fruit.reset(window.m_board, head.m_head.m_row, head.m_head.m_col, window.m_score); window.m_board[head.m_head.m_row][head.m_head.m_col] = '*'; window.m_board[fruit.m_row][fruit.m_col] = 'X'; body.draw(window.m_board); - window.draw_score(); - window.update_loop(FPS); + window.update_display(FPS); body.clear(window.m_board); head.m_head.clear(window.m_board); - head.get_new_point(head.m_head.m_direction); } input_thread.join(); diff --git a/src/snake.cpp b/src/snake.cpp index 626d19e..e868a54 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -40,6 +40,16 @@ void Tail::get_previous_point() { m_tail_pos.m_direction = m_previous_tail_pos.m_direction; } +void Body::collision(Head &head, bool &collision) { + for(int i = 0; i < m_body.size(); i++) { + if(m_body.at(i).m_tail_pos.m_row == head.m_head.m_row) { + if(m_body.at(i).m_tail_pos.m_col == head.m_head.m_col) { + collision = true; + } + } + } +} + void Body::clear(std::array, ROW> &arr) { for(int i = 0; i < m_body.size(); i++) { m_body.at(i).m_tail_pos.clear(arr); diff --git a/src/window.cpp b/src/window.cpp index 93fb511..370473e 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,6 +1,7 @@ #include "window.hpp" #include #include +#include #include Window::Window() { @@ -12,9 +13,16 @@ Window::Window() { m_previous_reset = 0; } -void Window::draw_score() { - std::cout << "Score: " << m_score << std::endl; +void Window::check_exit(bool &running, Body &body, bool &collision) { + if(body.m_body.size() >= (ROW * COL)) { + std::cout << "You win! Score: " + std::to_string(body.m_body.size()) << std::endl; + kill(running); + } else if(collision) { + std::cout << "You died! Score: " + std::to_string(body.m_body.size()) << std::endl; + kill(running); + } } + void Window::draw_window() { for(std::array &row : m_board) { for(char &col : row) { @@ -25,6 +33,13 @@ void Window::draw_window() { std::cout << std::flush; } +void Window::clear_window() { + std::cout<<"\033[H" << std::flush; +} + +void Window::tick(double frames_per_second) { + std::this_thread::sleep_for(std::chrono::milliseconds((int) (1000 / frames_per_second))); +} void Window::update_score(Fruit &fruit, Body &body) { if(m_score % 1 == 0 && m_score >= 1) { @@ -34,15 +49,11 @@ void Window::update_score(Fruit &fruit, Body &body) { } } -void Window::clear_window() { - std::cout<<"\033[H" << std::flush; +void Window::kill(bool &running) { + running = false; } -void Window::tick(double frames_per_second) { - std::this_thread::sleep_for(std::chrono::milliseconds((int) (1000 / frames_per_second))); -} - -void Window::update_loop(int fps) { +void Window::update_display(int fps) { clear_window(); draw_window(); tick(fps);