feat: fruits, globals, input, snake, point, window

This commit is contained in:
DarthMooMancer
2025-05-09 21:30:19 -04:00
parent 636ebae6a3
commit cdcffc40ea
13 changed files with 231 additions and 57 deletions
+8
View File
@@ -4,11 +4,19 @@ include_directories(include)
set(SOURCES set(SOURCES
src/main.cpp src/main.cpp
src/snake.cpp src/snake.cpp
src/input.cpp
src/window.cpp
src/point.cpp
src/fruit.cpp
) )
add_executable(snake ${SOURCES}) add_executable(snake ${SOURCES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON) 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 # find_package(SDL3 CONFIG REQUIRED) # An example of how to import libraries from vcpkg
# target_link_libraries(Game PRIVATE SDL3::SDL3) # target_link_libraries(Game PRIVATE SDL3::SDL3)
+14
View File
@@ -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
+7
View File
@@ -0,0 +1,7 @@
#ifndef GLOBALS_HPP
#define GLOBALS_HPP
constexpr unsigned int ROW = 10;
constexpr unsigned int COL = 10;
#endif // GLOBALS_HPP
+9
View File
@@ -0,0 +1,9 @@
#ifndef INPUT_HPP
#define INPUT_HPP
struct Input {
char m_current_key = ' ';
void get_input();
};
#endif // INPUT_HPP
+18
View File
@@ -0,0 +1,18 @@
#ifndef POINT_HPP
#define POINT_HPP
#include <array>
#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<std::array<char, COL>, ROW> &arr) const;
std::pair<int, int> get_point(int direction, int row, int col);
};
#endif // POINT_HPP
+6 -2
View File
@@ -1,7 +1,11 @@
#ifndef SNAKE_HPP #ifndef SNAKE_HPP
#define SNAKE_HPP #define SNAKE_HPP
void create_snake(); struct Snake {
void draw_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 #endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef WINDOW_HPP
#define WINDOW_HPP
#include <array>
#include "globals.hpp"
struct Window {
std::array<std::array<char, COL>, 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
+13
View File
@@ -0,0 +1,13 @@
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "util.h"
#include "fruit.hpp"
Fruit::Fruit() {
std::srand(std::time(0));
}
void Fruit::create_point() {
m_point = Point {rand() % 9, rand() % 9};
}
+16
View File
@@ -0,0 +1,16 @@
#include "input.hpp"
#include <ncurses.h>
void Input::get_input() {
while(true) {
initscr();
cbreak();
noecho();
m_current_key = getch();
endwin();
if(m_current_key == 'q') {
break;
}
}
}
+47 -51
View File
@@ -1,60 +1,56 @@
#include <iostream> #include <iostream>
#include <termios.h> #include <thread>
#include <cstdlib>
#include <unistd.h> #include <unistd.h>
#include "snake.hpp" #include "snake.hpp"
#include "point.hpp"
#include "fruit.hpp"
#include "window.hpp"
#include "globals.hpp"
#include "input.hpp"
const int ROW = 10; Snake snake {1};
const int COL = 10; Window window;
Input input;
char getch(); Fruit fruit;
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";
}
}
int main() { int main() {
create_board(); // int randomNum = random() % 101;
draw_board(); //
draw_snake(); // std::cout << randomNum;
// int count = 0; fruit.create_point();
// std::cout << "Press any key other than space or esc: " << std::endl; std::cout << fruit.m_point.get_point() << std::endl;
// while(count < 10) { // std::array<std::array<char, COL>, ROW> &board = window.m_board;
// char ch = getch(); // bool update = true;
// std::cout << "\nYou pressed: " << ch << '\n'; // int row = 0, col = 0;
// ++count; //
// 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; return 0;
} }
+27
View File
@@ -0,0 +1,27 @@
#include <iostream>
#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<std::array<char, COL>, ROW> &arr) const {
arr[m_row][m_col] = '.';
}
std::pair<int, int> 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};
}
+15 -4
View File
@@ -1,11 +1,16 @@
#include "snake.hpp" #include "snake.hpp"
#include <iostream> #include <iostream>
void create_snake() { Snake::Snake(int default_direction) {
std::cout << "Create Snake Test" << std::endl; 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) /* 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 * 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 * 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
*/
+34
View File
@@ -0,0 +1,34 @@
#include "window.hpp"
#include <iostream>
#include <chrono>
#include <thread>
Window::Window() {
for(std::array<char, COL> &row : m_board) {
row.fill('.');
}
}
void Window::draw_window() {
for(std::array<char, COL> &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();
}