removed the input thread and integrated it to the SnakeGame engine itself

This commit is contained in:
DarthMooMancer
2025-11-04 23:31:23 -05:00
parent 183be3c24a
commit e87094ce13
8 changed files with 59 additions and 67 deletions
-1
View File
@@ -9,7 +9,6 @@ include_directories(include)
set(SOURCES set(SOURCES
src/main.cpp src/main.cpp
src/element.cpp src/element.cpp
src/input.cpp
src/window.cpp src/window.cpp
) )
add_executable(snake ${SOURCES}) add_executable(snake ${SOURCES})
+9 -5
View File
@@ -4,6 +4,8 @@
#include <vector> #include <vector>
#include "globals.hpp" #include "globals.hpp"
class Window;
enum Direction { enum Direction {
UP, DOWN, LEFT, RIGHT UP, DOWN, LEFT, RIGHT
}; };
@@ -19,19 +21,21 @@ struct Vector2i {
class SnakeGame { class SnakeGame {
public: public:
SnakeGame(); SnakeGame();
// ~SnakeGame(); ~SnakeGame();
// Vector2i* buf[MAX_LEN] = {}; void run();
private:
std::vector<Vector2i> buf; std::vector<Vector2i> buf;
bool running = true; bool running = true;
enum Direction m_dir; enum Direction m_dir;
int m_score = 0;
Window* win;
void process_input();
void determine_index_zero_pos(); void determine_index_zero_pos();
void move_tail_indicies(); void move_tail_indicies();
void on_fruit_eaten(Vector2i (*board)[COL]); void on_fruit_eaten(Vector2i (*board)[COL]);
bool segment_overlap(); bool segment_overlap();
bool exit_summary(); bool exit_summary();
private:
int m_score = 0;
// int m_snake_size = 3;
}; };
#endif // ELEMENT_HPP #endif // ELEMENT_HPP
-7
View File
@@ -1,7 +0,0 @@
#ifndef INPUT_HPP
#define INPUT_HPP
#include "element.hpp"
void get_input(enum Direction &dir, bool &r);
#endif // INPUT_HPP
+1 -1
View File
@@ -7,7 +7,7 @@
struct Window { struct Window {
Vector2i board[ROW][COL] = {}; Vector2i board[ROW][COL] = {};
void clear_display(); void clear_display();
void draw_display(int milliseconds); void draw_display();
void update_display(std::vector<Vector2i> &buf); void update_display(std::vector<Vector2i> &buf);
}; };
+47 -9
View File
@@ -2,8 +2,12 @@
#include "globals.hpp" #include "globals.hpp"
#include <cstdlib> #include <cstdlib>
#include <ctime> #include <ctime>
#include <ncurses.h>
#include <ranges> #include <ranges>
#include <iostream> #include <iostream>
#include <window.hpp>
#include <thread>
#include <chrono>
void Vector2i::set(int _x, int _y) { void Vector2i::set(int _x, int _y) {
y = _y; y = _y;
@@ -11,14 +15,49 @@ void Vector2i::set(int _x, int _y) {
} }
SnakeGame::SnakeGame() { SnakeGame::SnakeGame() {
std::srand(std::time(0));
initscr();
cbreak();
noecho();
curs_set(0);
nodelay(stdscr, true);
buf.push_back(Vector2i{ COL / 2, ROW / 2, '*' }); buf.push_back(Vector2i{ COL / 2, ROW / 2, '*' });
buf.push_back(Vector2i{ buf.front().x, buf.front().y, '.' }); buf.push_back(Vector2i{ buf.front().x, buf.front().y, '.' });
buf.push_back(Vector2i{ (rand() % COL), (rand() % ROW), 'o' }); buf.push_back(Vector2i{ (rand() % COL), (rand() % ROW), 'o' });
win = new Window();
} }
// SnakeGame::~SnakeGame() { SnakeGame::~SnakeGame() {
// for(auto& p : buf) delete p; delete win;
// } endwin();
}
void SnakeGame::run() {
while (exit_summary()) {
process_input();
on_fruit_eaten(win->board);
determine_index_zero_pos();
move_tail_indicies();
win->clear_display();
win->update_display(buf);
win->draw_display();
std::this_thread::sleep_for(std::chrono::milliseconds((int) (200)));
}
}
void SnakeGame::process_input() {
int ch;
while((ch = getch()) != ERR) {
switch(ch) {
case 'w': if(m_dir != DOWN) m_dir = UP; break;
case 's': if(m_dir != UP) m_dir = DOWN; break;
case 'd': if(m_dir != LEFT) m_dir = RIGHT; break;
case 'a': if(m_dir != RIGHT) m_dir = LEFT; break;
case 'q': running = false; break;
}
}
}
bool SnakeGame::exit_summary() { bool SnakeGame::exit_summary() {
if(!running) { if(!running) {
@@ -34,14 +73,13 @@ bool SnakeGame::exit_summary() {
} }
void SnakeGame::determine_index_zero_pos() { void SnakeGame::determine_index_zero_pos() {
auto& head = buf[HEAD]; buf.at(PREVIOUS_HEAD).set(buf[HEAD].x, buf[HEAD].y);
buf.at(PREVIOUS_HEAD).set(head.x, head.y);
switch(m_dir) { switch(m_dir) {
case LEFT: head.x = (head.x + COL - 1) % COL; break; case LEFT: buf[HEAD].x = (buf[HEAD].x + COL - 1) % COL; break;
case RIGHT: head.x = (head.x + 1) % COL; break; case RIGHT: buf[HEAD].x = (buf[HEAD].x + 1) % COL; break;
case UP: head.y = (head.y + ROW - 1) % ROW; break; case UP: buf[HEAD].y = (buf[HEAD].y + ROW - 1) % ROW; break;
case DOWN: head.y = (head.y + 1) % ROW; break; case DOWN: buf[HEAD].y = (buf[HEAD].y + 1) % ROW; break;
} }
} }
-21
View File
@@ -1,21 +0,0 @@
#include "input.hpp"
#include <cstdint>
#include <ncurses.h>
void get_input(enum Direction &dir, bool &running) {
uint16_t m_getch;
while(running) {
initscr();
cbreak();
noecho();
m_getch = getch();
endwin();
if(m_getch == 65) if(dir != DOWN) dir = UP;
if(m_getch == 66) if(dir != UP) dir = DOWN;
if(m_getch == 67) if(dir != LEFT) dir = RIGHT;
if(m_getch == 68) if(dir != RIGHT) dir = LEFT;
if(m_getch == 113) running = false;
}
}
+1 -19
View File
@@ -1,25 +1,7 @@
#include <thread>
#include "element.hpp" #include "element.hpp"
#include "window.hpp"
#include "input.hpp"
int main () { int main () {
std::srand(std::time(0));
SnakeGame engine; SnakeGame engine;
Window win; engine.run();
std::thread input_thread([&] { get_input(engine.m_dir, engine.running ); } );
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(engine.buf);
win.draw_display(200);
}
input_thread.join();
return 0; return 0;
} }
+1 -4
View File
@@ -1,9 +1,7 @@
#include "window.hpp" #include "window.hpp"
#include "element.hpp" #include "element.hpp"
#include <iostream> #include <iostream>
#include <chrono>
#include <ranges> #include <ranges>
#include <thread>
#include <vector> #include <vector>
void Window::clear_display() { void Window::clear_display() {
@@ -14,7 +12,7 @@ void Window::clear_display() {
} }
} }
void Window::draw_display(int milliseconds) { void Window::draw_display() {
std::cout << "\033[H" << std::flush; // Clear screen std::cout << "\033[H" << std::flush; // Clear screen
for(int i : std::ranges::views::iota(0, ROW)) { for(int i : std::ranges::views::iota(0, ROW)) {
for(int j : std::ranges::views::iota(0, COL)) { for(int j : std::ranges::views::iota(0, COL)) {
@@ -23,7 +21,6 @@ void Window::draw_display(int milliseconds) {
} }
std::cout << "\r\n"; std::cout << "\r\n";
} }
std::this_thread::sleep_for(std::chrono::milliseconds((int) (milliseconds))); // 1000 / fps; 200ms = 5fps
} }
void Window::update_display(std::vector<Vector2i> &buf) { void Window::update_display(std::vector<Vector2i> &buf) {