From 183be3c24a086037eeaccc986e95fb51acb6aad6 Mon Sep 17 00:00:00 2001 From: DarthMooMancer <107283522+DarthMooMancer@users.noreply.github.com> Date: Tue, 4 Nov 2025 20:11:57 -0500 Subject: [PATCH] changed from raw pointer arrays to vectors --- include/element.hpp | 29 ++++++++++------ include/window.hpp | 2 +- src/element.cpp | 80 ++++++++++++++++++++++++++------------------- src/main.cpp | 30 ++++------------- src/window.cpp | 10 +++--- 5 files changed, 80 insertions(+), 71 deletions(-) diff --git a/include/element.hpp b/include/element.hpp index af9cd05..e7d4654 100644 --- a/include/element.hpp +++ b/include/element.hpp @@ -1,28 +1,37 @@ #ifndef ELEMENT_HPP #define ELEMENT_HPP +#include #include "globals.hpp" enum Direction { - UP = -2, - DOWN = 2, - LEFT = -1, - RIGHT = 1 + UP, DOWN, LEFT, RIGHT }; struct Vector2i { int x, y; char id; - enum Direction m_dir; Vector2i() : x(0), y(0), id('@') {} Vector2i(int x, int y, char s) : x(x), y(y), id(s) {} void set(int x, int y); }; -int get_score(); -void determine_index_zero_pos(Vector2i** buf); -void move_tail_indicies(Vector2i** buf); -void on_fruit_eaten(Vector2i (*board)[COL], Vector2i** buf); -bool segment_overlap(Vector2i** buf); +class SnakeGame { +public: + SnakeGame(); + // ~SnakeGame(); + // Vector2i* buf[MAX_LEN] = {}; + std::vector buf; + bool running = true; + enum Direction m_dir; + void determine_index_zero_pos(); + void move_tail_indicies(); + void on_fruit_eaten(Vector2i (*board)[COL]); + bool segment_overlap(); + bool exit_summary(); +private: + int m_score = 0; + // int m_snake_size = 3; +}; #endif // ELEMENT_HPP diff --git a/include/window.hpp b/include/window.hpp index f4eb766..914c1d8 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -8,7 +8,7 @@ struct Window { Vector2i board[ROW][COL] = {}; void clear_display(); void draw_display(int milliseconds); - void update_display(Vector2i** buf); + void update_display(std::vector &buf); }; #endif // WINDOW_HPP diff --git a/src/element.cpp b/src/element.cpp index 73c9c19..fe2728a 100644 --- a/src/element.cpp +++ b/src/element.cpp @@ -3,58 +3,72 @@ #include #include #include - -int _score = 0; -int _snake_size = 3; - -int get_score() { return _score; } +#include void Vector2i::set(int _x, int _y) { y = _y; x = _x; } -void determine_index_zero_pos(Vector2i** buf) { - auto& head = buf[HEAD]; - buf[PREVIOUS_HEAD]->set(head->x, head->y); +SnakeGame::SnakeGame() { + buf.push_back(Vector2i{ COL / 2, ROW / 2, '*' }); + buf.push_back(Vector2i{ buf.front().x, buf.front().y, '.' }); + buf.push_back(Vector2i{ (rand() % COL), (rand() % ROW), 'o' }); +} - switch(head->m_dir) { - case LEFT: head->x = (head->x + COL - 1) % COL; break; - case RIGHT: head->x = (head->x + 1) % COL; break; - case UP: head->y = (head->y + ROW - 1) % ROW; break; - case DOWN: head->y = (head->y + 1) % ROW; break; +// SnakeGame::~SnakeGame() { +// for(auto& p : buf) delete p; +// } + +bool SnakeGame::exit_summary() { + if(!running) { + return false; + } if(buf.size() >= MAX_LEN - 1) { + std::cout << "You filled the whole board and won! Score: " << m_score << "\n"; + return false; + } if(segment_overlap()) { + std::cout << "You collided with yourself and died! Score: " << m_score << "\n"; + return false; + } + return true; +} + +void SnakeGame::determine_index_zero_pos() { + auto& head = buf[HEAD]; + buf.at(PREVIOUS_HEAD).set(head.x, head.y); + + switch(m_dir) { + case LEFT: head.x = (head.x + COL - 1) % COL; break; + case RIGHT: head.x = (head.x + 1) % COL; break; + case UP: head.y = (head.y + ROW - 1) % ROW; break; + case DOWN: head.y = (head.y + 1) % ROW; break; } } -void move_tail_indicies(Vector2i** buf) { - if(_snake_size <= 3) return; - Vector2i* last_point = buf[_snake_size - 1]; - - std::memmove(buf + 4, buf + 3, (_snake_size - 4) * sizeof(Vector2i*)); - - buf[3] = last_point; - if(buf[3] != nullptr) last_point->set(buf[PREVIOUS_HEAD]->x, buf[PREVIOUS_HEAD]->y); +void SnakeGame::move_tail_indicies() { + if(buf.size() <= 3) return; + Vector2i last_point = buf.back(); + buf.pop_back(); + buf.insert(buf.begin() + 3, last_point); + buf[3].set(buf[PREVIOUS_HEAD].x, buf[PREVIOUS_HEAD].y); } -void on_fruit_eaten(Vector2i (*board)[COL], Vector2i** buf) { +void SnakeGame::on_fruit_eaten(Vector2i (*board)[COL]) { + if(buf[FRUIT].y != buf[HEAD].y || buf[FRUIT].x != buf[HEAD].x) return; int row, col; - if(buf[FRUIT]->y != buf[HEAD]->y || buf[FRUIT]->x != buf[HEAD]->x) return; do { row = (rand() % ROW); col = (rand() % COL); } while (board[row][col].id != '.'); - buf[FRUIT]->set(row, col); - std::memmove(buf + 4, buf + 3, (_snake_size - 3) * sizeof(Vector2i*)); - buf[3] = new Vector2i { ROW, COL, '@' }; - _score++; - _snake_size++; + buf[FRUIT].set(row, col); + buf.insert(buf.begin() + 3, Vector2i { ROW, COL, '@' }); + m_score++; } -bool segment_overlap(Vector2i** buf) { - for(int i : std::ranges::views::iota(3, _snake_size)) { - if(buf[i] && - buf[i]->y == buf[HEAD]->y && - buf[i]->x == buf[HEAD]->x) +bool SnakeGame::segment_overlap() { + for(int i : std::ranges::views::iota(3, (int)buf.size())) { + if( buf[i].y == buf[HEAD].y && + buf[i].x == buf[HEAD].x) { return true; } diff --git a/src/main.cpp b/src/main.cpp index 541474c..27456b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,41 +1,25 @@ #include -#include #include "element.hpp" #include "window.hpp" -#include "globals.hpp" #include "input.hpp" int main () { std::srand(std::time(0)); + SnakeGame engine; Window win; - bool running = true; - Vector2i* buf[MAX_LEN] = {}; // 2 for head, 1 for fruit, rest for tail - buf[HEAD] = new Vector2i { COL / 2, ROW / 2, '*' }; - buf[PREVIOUS_HEAD] = new Vector2i { buf[HEAD]->x, buf[HEAD]->y, '.' }; - buf[FRUIT] = new Vector2i { (rand() % COL), (rand() % ROW), 'o' }; + std::thread input_thread([&] { get_input(engine.m_dir, engine.running ); } ); - std::thread input_thread([&] { get_input(buf[HEAD]->m_dir, running ); } ); - - while (running) { - on_fruit_eaten(win.board, buf); - determine_index_zero_pos(buf); - move_tail_indicies(buf); - - if(buf[MAX_LEN - 1] != nullptr) { - std::cout << "You filled the whole board and won! Score: " << get_score() << std::endl; - running = false; - } if(segment_overlap(buf)) { - std::cout << "You collided with yourself and died! Score: " << get_score() << std::endl; - running = false; - } + while (engine.exit_summary()) { + engine.on_fruit_eaten(win.board); + engine.determine_index_zero_pos(); + engine.move_tail_indicies(); win.clear_display(); - win.update_display(buf); + win.update_display(engine.buf); win.draw_display(200); } input_thread.join(); - for(auto& p : buf) delete p; return 0; } diff --git a/src/window.cpp b/src/window.cpp index 83591ee..825b685 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -4,6 +4,7 @@ #include #include #include +#include void Window::clear_display() { for(int i : std::ranges::views::iota(0, ROW)) { @@ -25,9 +26,10 @@ void Window::draw_display(int milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds((int) (milliseconds))); // 1000 / fps; 200ms = 5fps } -void Window::update_display(Vector2i** buf) { - for(int i : std::ranges::views::iota(0, ROW * COL)) { - if(buf[i] == nullptr || i == 1 || buf[i]->y > ROW - 1 || buf[i]->x > COL - 1) continue; - board[buf[i]->y][buf[i]->x].id = buf[i]->id; +void Window::update_display(std::vector &buf) { + for(int i : std::ranges::views::iota(0, (int)buf.size())) { + // if(i == 1 || buf[i]->y > ROW - 1 || buf[i]->x > COL - 1) continue; + if(i == 1) continue; + board[buf[i].y][buf[i].x].id = buf[i].id; } }