changed from raw pointer arrays to vectors

This commit is contained in:
DarthMooMancer
2025-11-04 20:11:57 -05:00
parent 1af33ba5a4
commit 183be3c24a
5 changed files with 80 additions and 71 deletions
+19 -10
View File
@@ -1,28 +1,37 @@
#ifndef ELEMENT_HPP
#define ELEMENT_HPP
#include <vector>
#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<Vector2i> 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
+1 -1
View File
@@ -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<Vector2i> &buf);
};
#endif // WINDOW_HPP
+46 -32
View File
@@ -3,58 +3,72 @@
#include <cstdlib>
#include <ctime>
#include <ranges>
int _score = 0;
int _snake_size = 3;
int get_score() { return _score; }
#include <iostream>
void Vector2i::set(int _x, int _y) {
y = _y;
x = _x;
}
void determine_index_zero_pos(Vector2i** buf) {
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' });
}
// 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[PREVIOUS_HEAD]->set(head->x, head->y);
buf.at(PREVIOUS_HEAD).set(head.x, head.y);
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;
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;
}
+7 -23
View File
@@ -1,41 +1,25 @@
#include <thread>
#include <iostream>
#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;
}
+6 -4
View File
@@ -4,6 +4,7 @@
#include <chrono>
#include <ranges>
#include <thread>
#include <vector>
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<Vector2i> &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;
}
}