From cdcffc40eaa3848c5bd67a496e664c02a0f639df Mon Sep 17 00:00:00 2001 From: DarthMooMancer <107283522+DarthMooMancer@users.noreply.github.com> Date: Fri, 9 May 2025 21:30:19 -0400 Subject: [PATCH] feat: fruits, globals, input, snake, point, window --- CMakeLists.txt | 8 ++++ include/fruit.hpp | 14 +++++++ include/globals.hpp | 7 ++++ include/input.hpp | 9 +++++ include/point.hpp | 18 +++++++++ include/snake.hpp | 8 +++- include/window.hpp | 17 ++++++++ src/fruit.cpp | 13 ++++++ src/input.cpp | 16 ++++++++ src/main.cpp | 98 ++++++++++++++++++++++----------------------- src/point.cpp | 27 +++++++++++++ src/snake.cpp | 19 +++++++-- src/window.cpp | 34 ++++++++++++++++ 13 files changed, 231 insertions(+), 57 deletions(-) create mode 100644 include/fruit.hpp create mode 100644 include/globals.hpp create mode 100644 include/input.hpp create mode 100644 include/point.hpp create mode 100644 include/window.hpp create mode 100644 src/fruit.cpp create mode 100644 src/input.cpp create mode 100644 src/point.cpp create mode 100644 src/window.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f138040..3c55d1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,19 @@ include_directories(include) set(SOURCES src/main.cpp src/snake.cpp + src/input.cpp + src/window.cpp + src/point.cpp + src/fruit.cpp ) add_executable(snake ${SOURCES}) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD_REQUIRED ON) +find_package(Curses REQUIRED) +include_directories(${CURSES_INCLUDE_DIR}) +target_link_libraries(snake ${CURSES_LIBRARIES}) + # find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg # target_link_libraries(Game PRIVATE SDL3::SDL3) diff --git a/include/fruit.hpp b/include/fruit.hpp new file mode 100644 index 0000000..86c4f5b --- /dev/null +++ b/include/fruit.hpp @@ -0,0 +1,14 @@ +#ifndef FRUIT_HPP +#define FRUIT_HPP + +#include "point.hpp" + +struct Fruit { + int unsigned m_row; + int unsigned m_col; + + Point m_point; + Fruit(); + void create_point(); +}; +#endif // FRUIT_HPP diff --git a/include/globals.hpp b/include/globals.hpp new file mode 100644 index 0000000..ae1c778 --- /dev/null +++ b/include/globals.hpp @@ -0,0 +1,7 @@ +#ifndef GLOBALS_HPP +#define GLOBALS_HPP + +constexpr unsigned int ROW = 10; +constexpr unsigned int COL = 10; + +#endif // GLOBALS_HPP diff --git a/include/input.hpp b/include/input.hpp new file mode 100644 index 0000000..f2931b5 --- /dev/null +++ b/include/input.hpp @@ -0,0 +1,9 @@ +#ifndef INPUT_HPP +#define INPUT_HPP + +struct Input { + char m_current_key = ' '; + void get_input(); +}; + +#endif // INPUT_HPP diff --git a/include/point.hpp b/include/point.hpp new file mode 100644 index 0000000..8d41611 --- /dev/null +++ b/include/point.hpp @@ -0,0 +1,18 @@ +#ifndef POINT_HPP +#define POINT_HPP + +#include +#include "globals.hpp" + +struct Point { + int m_row; + int m_col; + Point() {} + Point(int x, int y) : m_row(x), m_col(y) {} + + std::string get_point() const; + void clear(std::array, ROW> &arr) const; + std::pair get_point(int direction, int row, int col); +}; + +#endif // POINT_HPP diff --git a/include/snake.hpp b/include/snake.hpp index fecb7a6..b659d20 100644 --- a/include/snake.hpp +++ b/include/snake.hpp @@ -1,7 +1,11 @@ #ifndef SNAKE_HPP #define SNAKE_HPP -void create_snake(); -void draw_snake(); +struct Snake { + Snake(int default_direction); + int get_direction() const; + void set_direction(int x); + int direction; // 1: Down, 2: Up, 3: Left, 4: Right +}; #endif diff --git a/include/window.hpp b/include/window.hpp new file mode 100644 index 0000000..86fa0c6 --- /dev/null +++ b/include/window.hpp @@ -0,0 +1,17 @@ +#ifndef WINDOW_HPP +#define WINDOW_HPP +#include +#include "globals.hpp" + +struct Window { + std::array, ROW> m_board; + // Initializes board with . for each value + Window(); + + void draw_window(); + void clear_window(); + void tick(double frames_per_second); + void update_loop(int fps); +}; + +#endif // WINDOW_HPP diff --git a/src/fruit.cpp b/src/fruit.cpp new file mode 100644 index 0000000..28fca7f --- /dev/null +++ b/src/fruit.cpp @@ -0,0 +1,13 @@ +#include +#include +#include +#include "util.h" +#include "fruit.hpp" + +Fruit::Fruit() { + std::srand(std::time(0)); +} + +void Fruit::create_point() { + m_point = Point {rand() % 9, rand() % 9}; +} diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..3635b90 --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,16 @@ +#include "input.hpp" +#include + +void Input::get_input() { + while(true) { + initscr(); + cbreak(); + noecho(); + + m_current_key = getch(); + endwin(); + if(m_current_key == 'q') { + break; + } + } +} diff --git a/src/main.cpp b/src/main.cpp index 51ced0a..df7e254 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,60 +1,56 @@ #include -#include +#include +#include #include #include "snake.hpp" +#include "point.hpp" +#include "fruit.hpp" +#include "window.hpp" +#include "globals.hpp" +#include "input.hpp" -const int ROW = 10; -const int COL = 10; - -char getch(); -void create_board(); -void draw_board(); - -struct { - char board[ROW][COL]; -} window; - -char (*g_pboard)[ROW][COL] = &window.board; - -char getch() { - termios oldt, newt; - char ch; - tcgetattr(STDIN_FILENO, &oldt); // get current terminal attributes - newt = oldt; - newt.c_lflag &= ~(ICANON | ECHO); // disable canonical mode and echo - tcsetattr(STDIN_FILENO, TCSANOW, &newt); // apply new settings - read(STDIN_FILENO, &ch, 1); // read one char - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // restore original settings - return ch; -} - -void create_board() { - for(int i = 0; i < ROW; i++) { - for(int a = 0; a < COL; a++) { - (*g_pboard)[i][a] = '.'; - } - } -} - -void draw_board() { - for(int i = 0; i < ROW; i++) { - for(int a = 0; a < COL; a++) { - std::cout << (*g_pboard)[i][a] << " "; - } - std::cout << "\n"; - } -} +Snake snake {1}; +Window window; +Input input; +Fruit fruit; int main() { - create_board(); - draw_board(); - draw_snake(); - // int count = 0; - // std::cout << "Press any key other than space or esc: " << std::endl; - // while(count < 10) { - // char ch = getch(); - // std::cout << "\nYou pressed: " << ch << '\n'; - // ++count; + // int randomNum = random() % 101; + // + // std::cout << randomNum; + fruit.create_point(); + std::cout << fruit.m_point.get_point() << std::endl; + // std::array, ROW> &board = window.m_board; + // bool update = true; + // int row = 0, col = 0; + // + // Point previous {row,col}; + // std::thread input_thread(&Input::get_input, &input); + // while(update) { + // if (input.m_current_key == 's') snake.set_direction(1); + // if (input.m_current_key == 'w') snake.set_direction(2); + // if (input.m_current_key == 'a') snake.set_direction(3); + // if (input.m_current_key == 'd') snake.set_direction(4); + // if (input.m_current_key == 'q') break; + // + // std::tie(row, col) = previous.get_point(snake.get_direction(), row, col); + // + // board[row][col] = '*'; + // previous.clear(board); // Clear old point + // previous = Point {row, col}; // Set new previous + // window.update_loop(5); // Update loop to clear board, tick and redisplay board // } + // + // input_thread.join(); + /* First + * Learn how to make threads, + * for the input thread call the thread then use a while loop within the thread, DO NOT use a while loop to call the thread + * + * for the update display thread use a while loop within the thread, DO NOT USE a while loop to call the thread. + * + * the update display thread will ALSO BE YOUR GAME UPDATE THREAD. Your input thread should only be used for INPUT no other function calls should be made and it should NEVER be put to sleep. + * + */ + return 0; } diff --git a/src/point.cpp b/src/point.cpp new file mode 100644 index 0000000..16e5714 --- /dev/null +++ b/src/point.cpp @@ -0,0 +1,27 @@ +#include +#include "point.hpp" + +std::string Point::get_point() const { + return "(" + std::to_string(m_row) + ", " + std::to_string(m_col) + ")"; +} + +void Point::clear(std::array, ROW> &arr) const { + arr[m_row][m_col] = '.'; +} + +std::pair Point::get_point(int direction, int row, int col) { + if (direction == 1) { + row++; + if (row >= ROW) row = 0; + } else if (direction == 2) { + row--; + if (row < 0) row = ROW - 1; + } else if (direction == 3) { + col--; + if (col < 0) col = COL - 1; + } else if (direction == 4) { + col++; + if (col >= COL) col = 0; + } + return {row, col}; +} diff --git a/src/snake.cpp b/src/snake.cpp index b10add5..550693e 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -1,11 +1,16 @@ #include "snake.hpp" #include -void create_snake() { - std::cout << "Create Snake Test" << std::endl; +Snake::Snake(int default_direction) { + direction = default_direction; } -void draw_snake() { - std::cout << "Draw Snake Test" << std::endl; + +int Snake::get_direction() const { + return direction; +} + +void Snake::set_direction(int x) { + direction = x; } /* snake head for instance is (3, 0) @@ -15,3 +20,9 @@ void draw_snake() { * so if I change direction at (0, 0) from north to west then at (0, 0) there is a postion change saved and once a body hits that * switch direction */ + +/* Make a way to get key input + * Create a sense of direction + * save last position for head and head, save posisition for direction changes + * head class and body subclass maybe +*/ diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..d960468 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,34 @@ +#include "window.hpp" +#include +#include +#include + +Window::Window() { + for(std::array &row : m_board) { + row.fill('.'); + } +} + +void Window::draw_window() { + for(std::array &row : m_board) { + for(char &col : row) { + std::cout << col << " "; + } + std::cout << "\r\n"; + } + 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_loop(int fps) { + clear_window(); + tick(fps); + draw_window(); +}