diff --git a/CMakeLists.txt b/CMakeLists.txt index 817e200..b737180 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,10 @@ include_directories(include) set(SOURCES src/main.cpp - src/snake.cpp + src/element.cpp src/input.cpp src/window.cpp src/point.cpp - src/fruit.cpp ) add_executable(snake ${SOURCES}) diff --git a/include/element.hpp b/include/element.hpp new file mode 100644 index 0000000..2443498 --- /dev/null +++ b/include/element.hpp @@ -0,0 +1,36 @@ +#ifndef ELEMENT_HPP +#define ELEMENT_HPP + +#include +#include "point.hpp" + +struct Head { + Head(); + Point m_head; + Point m_previous_head; + void get_new_pos(); +}; + +struct Tail { + Point m_tail_pos; + Point m_previous_tail_pos; +}; + +struct Body { + Body(); + std::vector m_body; + int m_score; + bool m_collision; + void clear(std::array, ROW> &arr); + void add_tail(); + void get_new_points(Head &head); + void collision(Head &head); +}; + +struct Fruit { + Fruit(); + Point m_point; + void get_new_pos(std::array, ROW> &board, Head &head, int &score); +}; + +#endif // ELEMENT_HPP diff --git a/include/fruit.hpp b/include/fruit.hpp deleted file mode 100644 index 4e5c511..0000000 --- a/include/fruit.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef FRUIT_HPP -#define FRUIT_HPP - -#include "point.hpp" - -struct Fruit { - Fruit(); - Point m_point; - void reset(std::array, ROW> &board, int row, int col, int &score); -}; - -#endif // FRUIT_HPP diff --git a/include/globals.hpp b/include/globals.hpp index b8783bb..b907a05 100644 --- a/include/globals.hpp +++ b/include/globals.hpp @@ -5,6 +5,5 @@ constexpr uint16_t ROW = 11; constexpr uint16_t COL = 11; -constexpr uint16_t FPS = 5; #endif // GLOBALS_HPP diff --git a/include/input.hpp b/include/input.hpp index 68abbfb..f2460b8 100644 --- a/include/input.hpp +++ b/include/input.hpp @@ -4,7 +4,7 @@ struct Input { int m_current_key = 0; char m_getch = ' '; - void get_input(int &d, bool &c, bool &r); + void get_input(int &d, bool &r); }; #endif // INPUT_HPP diff --git a/include/point.hpp b/include/point.hpp index 228965d..50d8328 100644 --- a/include/point.hpp +++ b/include/point.hpp @@ -2,7 +2,6 @@ #define POINT_HPP #include -#include #include "globals.hpp" struct Point { @@ -13,9 +12,8 @@ struct Point { Point(int x, int y) : m_row(x), m_col(y) {} Point(int x, int y, int dir) : m_row(x), m_col(y), m_direction(dir) {} - std::string to_string() const; - void clear(std::array, ROW> &arr) const; - void set_new_point(int x, int y, int dir); + void clear(std::array, ROW> &board) const; + void set_new_point(int row, int col, int dir); }; #endif // POINT_HPP diff --git a/include/snake.hpp b/include/snake.hpp deleted file mode 100644 index 76fb9bb..0000000 --- a/include/snake.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef SNAKE_HPP -#define SNAKE_HPP - -#include -#include "point.hpp" - -struct Head { - Head(); - Head(int default_direction, int row, int col); - Point m_head; - Point m_previous_head; - void get_new_point(int direction); - void get_previous_point(); -}; - -struct Tail { - Tail(int follow_direction, int row, int col); - Point m_tail_pos; - Point m_previous_tail_pos; - std::vector m_move_history; - void get_previous_point(); -}; - -struct Body { - std::vector m_body; - void clear(std::array, ROW> &arr); - 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 047620e..41b9457 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -2,22 +2,12 @@ #define WINDOW_HPP #include #include "globals.hpp" -#include "fruit.hpp" -#include "snake.hpp" +#include "element.hpp" struct Window { Window(); std::array, ROW> m_board; - int m_score; - int m_reset; - int m_previous_reset; - - void draw_window(); - void tick(double frames_per_second); - void kill(bool &running); - void update_score(Fruit &fruit, Body &body); - void update_display(int fps); - void check_exit(bool &running, Body &body, bool &collision); + void update_display(Fruit &fruit, Head &head, Body &body); }; #endif // WINDOW_HPP diff --git a/src/element.cpp b/src/element.cpp new file mode 100644 index 0000000..508e3c4 --- /dev/null +++ b/src/element.cpp @@ -0,0 +1,78 @@ +#include "element.hpp" +#include +#include + +Fruit::Fruit() { + std::srand(std::time(0)); + m_point.set_new_point((rand() % 9), (rand() % 9), 0); +} + +void Fruit::get_new_pos(std::array, ROW> &board, Head &head, int &score) { + if(m_point.m_row == head.m_head.m_row && m_point.m_col == head.m_head.m_col) { + m_point.set_new_point((rand() % 9), (rand() % 9), 0); + score++; + } +} + +Head::Head() { + m_head.set_new_point(5, 5, 2); +} + +void Head::get_new_pos() { + if (m_head.m_direction == -1) { + if (m_head.m_col <= 0) m_head.m_col = COL - 1; + else m_head.m_col--; + } else if (m_head.m_direction == 1) { + if (m_head.m_col >= COL - 1) m_head.m_col = 0; + else m_head.m_col++; + } else if (m_head.m_direction == -2) { + if (m_head.m_row <= 0) m_head.m_row = ROW - 1; + else m_head.m_row--; + } else if (m_head.m_direction == 2) { + if (m_head.m_row >= ROW - 1) m_head.m_row = 0; + else m_head.m_row++; + } +} + +Body::Body() { + m_score = 0; + m_collision = false; +} + +void Body::collision(Head &head) { + 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) { + m_collision = true; + } + } + } +} + +void Body::add_tail() { + if(m_score >= 1) { + m_score = 0; + m_body.push_back(Tail{}); + } +} + +void Body::get_new_points(Head &head) { + for (int i = 0; i < m_body.size(); i++) { + m_body.front().m_previous_tail_pos.set_new_point( + head.m_previous_head.m_row, + head.m_previous_head.m_col, + head.m_previous_head.m_direction); + if(i > 0) { + m_body.at(i).m_previous_tail_pos.set_new_point( + m_body.at(i - 1).m_tail_pos.m_row, + m_body.at(i - 1).m_tail_pos.m_col, + m_body.at(i - 1).m_tail_pos.m_direction); + } + } + for (int i = 0; i < m_body.size(); i++) { + m_body.at(i).m_tail_pos.set_new_point( + m_body.at(i).m_previous_tail_pos.m_row, + m_body.at(i).m_previous_tail_pos.m_col, + m_body.at(i).m_previous_tail_pos.m_direction); + } +} diff --git a/src/fruit.cpp b/src/fruit.cpp deleted file mode 100644 index a9bd36d..0000000 --- a/src/fruit.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include "fruit.hpp" -#include "globals.hpp" - -Fruit::Fruit() { - std::srand(std::time(0)); - m_point.m_row = (rand() % 9); - m_point.m_col = (rand() % 9); -} - -void Fruit::reset(std::array, ROW> &board, int row, int col, int &score) { - if(m_point.m_row == row && m_point.m_col == col) { - m_point.clear(board); - m_point.m_row = (rand() % 9); - m_point.m_col = (rand() % 9); - score++; - } -} diff --git a/src/input.cpp b/src/input.cpp index f00f3fa..771e583 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,9 +1,8 @@ #include "input.hpp" #include -void Input::get_input(int &d, bool &c, bool &r) { - bool running = true; - while(running && !(c)) { +void Input::get_input(int &direction, bool &running) { + while(running) { initscr(); cbreak(); noecho(); @@ -11,16 +10,15 @@ void Input::get_input(int &d, bool &c, bool &r) { m_getch = getch(); endwin(); if(m_current_key != 1 && (m_getch == 'a' || m_getch == 'D')) { - d = m_current_key = -1; + direction = 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; + direction = m_current_key = 1; } else if(m_current_key != -2 && (m_getch == 's' || m_getch == 'B')) { - d = m_current_key = 2; + direction = m_current_key = 2; } else if(m_current_key != 2 && (m_getch == 'w' || m_getch == 'A')) { - d = m_current_key = -2; + direction = m_current_key = -2; } else if(m_getch == 'q') { - r = running = false; + running = false; } } diff --git a/src/main.cpp b/src/main.cpp index 43e1a87..fe932b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,6 @@ #include -#include "point.hpp" -#include "fruit.hpp" -#include "snake.hpp" +#include +#include "element.hpp" #include "window.hpp" #include "globals.hpp" #include "input.hpp" @@ -13,28 +12,27 @@ int main () { Body body; Head head; 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.collision(head); + body.add_tail(); + if(body.m_body.size() >= (ROW * COL)) { + std::cout << "You win! Score: " + std::to_string(body.m_body.size()) << std::endl; + running = false; + } else if(body.m_collision) { + std::cout << "You died! Score: " + std::to_string(body.m_body.size()) << std::endl; + running = false; + } + head.get_new_pos(); body.get_new_points(head); - head.get_previous_point(); + head.m_previous_head.set_new_point(head.m_head.m_row, head.m_head.m_col, head.m_head.m_direction); - 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_point.m_row][fruit.m_point.m_col] = 'X'; - body.draw(window.m_board); - window.update_display(FPS); - body.clear(window.m_board); - head.m_head.clear(window.m_board); + fruit.get_new_pos(window.m_board, head, body.m_score); + window.update_display(fruit, head, body); } input_thread.join(); diff --git a/src/point.cpp b/src/point.cpp index 2fb0eba..e364d0f 100644 --- a/src/point.cpp +++ b/src/point.cpp @@ -1,12 +1,7 @@ -#include #include "point.hpp" -std::string Point::to_string() const { - return "(" + std::to_string(m_row) + ", " + std::to_string(m_col) + "), " + std::to_string(m_direction); -} - -void Point::clear(std::array, ROW> &arr) const { - arr[m_row][m_col] = '.'; +void Point::clear(std::array, ROW> &board) const { + board[m_row][m_col] = '.'; } void Point::set_new_point(int row, int col, int dir) { diff --git a/src/snake.cpp b/src/snake.cpp deleted file mode 100644 index 4e01725..0000000 --- a/src/snake.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "snake.hpp" - -Head::Head() { - m_head = Point { 5, 5, 2 }; - m_previous_head.set_new_point(m_previous_head.m_row = 0, m_previous_head.m_col = 0, m_previous_head.m_direction = 2); -} - -Head::Head(int default_direction, int row, int col) { - m_head = Point { row, col, default_direction }; - m_previous_head.set_new_point(m_previous_head.m_row = 0, m_previous_head.m_col = 0, m_previous_head.m_direction = 2); -} - -void Head::get_new_point(int direction) { - if (direction == -1) { - if (m_head.m_col <= 0) m_head.m_col = COL - 1; - else m_head.m_col--; - } else if (direction == 1) { - if (m_head.m_col >= COL - 1) m_head.m_col = 0; - else m_head.m_col++; - } else if (direction == -2) { - if (m_head.m_row <= 0) m_head.m_row = ROW - 1; - else m_head.m_row--; - } else if (direction == 2) { - if (m_head.m_row >= ROW - 1) m_head.m_row = 0; - else m_head.m_row++; - } else { - return; - } -} - -void Head::get_previous_point() { - m_previous_head.m_row = m_head.m_row; - m_previous_head.m_col = m_head.m_col; - m_previous_head.m_direction = m_head.m_direction; -} - -Tail::Tail(int follow_direction, int row, int col) { - m_tail_pos = Point { row, col, follow_direction }; -} - -void Tail::get_previous_point() { - m_tail_pos.m_row = m_previous_tail_pos.m_row; - m_tail_pos.m_col = m_previous_tail_pos.m_col; - 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); - } -} - -void Body::draw(std::array, ROW> &arr) { - for(int i = 0; i < m_body.size(); i++) { - if(i < m_body.size()) { - arr[m_body.at(i).m_tail_pos.m_row][m_body.at(i).m_tail_pos.m_col] = '0'; - } - } -} - -void Body::move(Head &head) { - for (int i = 0; i < m_body.size(); i++) { - if(i == 0) { - - } - } -} - -void Body::get_new_points(Head &head) { - for (int i = 0; i < m_body.size(); i++) { - if(i == 0) { - m_body.at(i).m_previous_tail_pos.set_new_point( - head.m_previous_head.m_row, - head.m_previous_head.m_col, - head.m_previous_head.m_direction); - } else { - m_body.at(i).m_previous_tail_pos.set_new_point( - m_body.at(i - 1).m_tail_pos.m_row, - m_body.at(i - 1).m_tail_pos.m_col, - m_body.at(i - 1).m_tail_pos.m_direction); - } - } - for (int i = 0; i < m_body.size(); i++) { - m_body.at(i).get_previous_point(); - } -} diff --git a/src/window.cpp b/src/window.cpp index 55f5a55..5b39dd7 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,51 +1,33 @@ #include "window.hpp" #include #include -#include #include Window::Window() { - for(std::array &row : m_board) { - row.fill('.'); - } - m_score = 0; - m_reset = 0; - m_previous_reset = 0; + for(std::array &row : m_board) { row.fill('.'); } } -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::update_display(Fruit &fruit, Head &head, Body &body) { + // Update symbols of positions + m_board[head.m_head.m_row][head.m_head.m_col] = '*'; + m_board[fruit.m_point.m_row][fruit.m_point.m_col] = 'X'; + for(int i = 0; i < body.m_body.size(); i++) { + m_board[body.m_body.at(i).m_tail_pos.m_row][body.m_body.at(i).m_tail_pos.m_col] = '0'; } -} -void Window::draw_window() { + std::cout << "\033[H" << std::flush; // Clear screen + // Draw Screen for(std::array &row : m_board) { for(char &col : row) { std::cout << col << " "; } std::cout << "\r\n"; } - std::cout << std::flush; -} - -void Window::update_score(Fruit &fruit, Body &body) { - if(m_score >= 1) { - m_score = 0; - body.m_body.push_back(Tail{2, 0, 0}); - } -} - -void Window::kill(bool &running) { - running = false; -} - -void Window::update_display(int fps) { - std::cout<<"\033[H" << std::flush; - draw_window(); std::this_thread::sleep_for(std::chrono::milliseconds((int) (200))); // 1000 / fps; 200ms = 5fps + // Clear old spaces + for(int i = 0; i < body.m_body.size(); i++) { + body.m_body.at(i).m_tail_pos.clear(m_board); + } + head.m_head.clear(m_board); + fruit.m_point.clear(m_board); }