window is no longer a raw pointer and is a unique_ptr, id no longer exists
This commit is contained in:
+9
-8
@@ -2,6 +2,7 @@
|
|||||||
#define ELEMENT_HPP
|
#define ELEMENT_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
@@ -11,12 +12,12 @@ enum Direction {
|
|||||||
UP, DOWN, LEFT, RIGHT
|
UP, DOWN, LEFT, RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector2i {
|
struct vec {
|
||||||
int x, y;
|
int x, y;
|
||||||
char id;
|
vec() : x(0), y(0) {}
|
||||||
Vector2i() : x(0), y(0), id('@') {}
|
vec(int x, int y) : x(x), y(y) {}
|
||||||
Vector2i(int x, int y, char s) : x(x), y(y), id(s) {}
|
void set(int _x, int _y) { x = _x; y = _y; }
|
||||||
void set(int x, int y);
|
auto operator <=> (const vec&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SnakeGame {
|
class SnakeGame {
|
||||||
@@ -26,15 +27,15 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window* win;
|
std::unique_ptr<Window> win;
|
||||||
std::vector<Vector2i> buf;
|
std::vector<vec> buf;
|
||||||
bool running = true;
|
bool running = true;
|
||||||
enum Direction m_dir;
|
enum Direction m_dir;
|
||||||
uint8_t m_score = 0;
|
uint8_t m_score = 0;
|
||||||
void process_input();
|
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 add_tail_and_respawn_fruit(std::array<std::array<char, COL>, ROW> board);
|
||||||
bool segment_overlap();
|
bool segment_overlap();
|
||||||
bool exit_summary();
|
bool exit_summary();
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-3
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "element.hpp"
|
#include "element.hpp"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
Vector2i board[ROW][COL] = {};
|
std::array<std::array<char, COL>, ROW> board;
|
||||||
void clear_display();
|
|
||||||
void draw_display();
|
void draw_display();
|
||||||
void update_display(std::vector<Vector2i> &buf);
|
void update_display(std::vector<vec> &buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINDOW_HPP
|
#endif // WINDOW_HPP
|
||||||
|
|||||||
+15
-23
@@ -2,6 +2,7 @@
|
|||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <memory>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -9,11 +10,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
void Vector2i::set(int _x, int _y) {
|
|
||||||
y = _y;
|
|
||||||
x = _x;
|
|
||||||
}
|
|
||||||
|
|
||||||
SnakeGame::SnakeGame() {
|
SnakeGame::SnakeGame() {
|
||||||
std::srand(std::time(0));
|
std::srand(std::time(0));
|
||||||
initscr();
|
initscr();
|
||||||
@@ -21,25 +17,25 @@ SnakeGame::SnakeGame() {
|
|||||||
noecho();
|
noecho();
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
nodelay(stdscr, true);
|
nodelay(stdscr, true);
|
||||||
buf.push_back(Vector2i{ COL / 2, ROW / 2, '*' });
|
buf.push_back(vec{ COL / 2, ROW / 2 });
|
||||||
buf.push_back(Vector2i{ buf.front().x, buf.front().y, '.' });
|
buf.push_back(vec{ buf.front().x, buf.front().y });
|
||||||
buf.push_back(Vector2i{ (rand() % COL), (rand() % ROW), 'o' });
|
buf.push_back(vec{ (rand() % COL), (rand() % ROW) });
|
||||||
win = new Window();
|
win = std::make_unique<Window>();
|
||||||
}
|
}
|
||||||
|
|
||||||
SnakeGame::~SnakeGame() {
|
SnakeGame::~SnakeGame() {
|
||||||
delete win;
|
|
||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnakeGame::run() {
|
void SnakeGame::run() {
|
||||||
while (exit_summary()) {
|
while (exit_summary()) {
|
||||||
process_input();
|
process_input();
|
||||||
on_fruit_eaten(win->board);
|
if(buf[FRUIT] == buf[HEAD]) {
|
||||||
|
add_tail_and_respawn_fruit(win->board);
|
||||||
|
}
|
||||||
determine_index_zero_pos();
|
determine_index_zero_pos();
|
||||||
move_tail_indicies();
|
move_tail_indicies();
|
||||||
|
|
||||||
win->clear_display();
|
|
||||||
win->update_display(buf);
|
win->update_display(buf);
|
||||||
win->draw_display();
|
win->draw_display();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds((int) (200)));
|
std::this_thread::sleep_for(std::chrono::milliseconds((int) (200)));
|
||||||
@@ -60,9 +56,8 @@ void SnakeGame::process_input() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SnakeGame::exit_summary() {
|
bool SnakeGame::exit_summary() {
|
||||||
if(!running) {
|
if(!running) return false;
|
||||||
return false;
|
if(buf.size() >= MAX_LEN - 1) {
|
||||||
} if(buf.size() >= MAX_LEN - 1) {
|
|
||||||
std::cout << "You filled the whole board and won! Score: " << m_score << "\n";
|
std::cout << "You filled the whole board and won! Score: " << m_score << "\n";
|
||||||
return false;
|
return false;
|
||||||
} if(segment_overlap()) {
|
} if(segment_overlap()) {
|
||||||
@@ -85,29 +80,26 @@ void SnakeGame::determine_index_zero_pos() {
|
|||||||
|
|
||||||
void SnakeGame::move_tail_indicies() {
|
void SnakeGame::move_tail_indicies() {
|
||||||
if(buf.size() <= 3) return;
|
if(buf.size() <= 3) return;
|
||||||
Vector2i last_point = buf.back();
|
vec last_point = buf.back();
|
||||||
buf.pop_back();
|
buf.pop_back();
|
||||||
buf.insert(buf.begin() + 3, last_point);
|
buf.insert(buf.begin() + 3, last_point);
|
||||||
buf[3].set(buf[PREVIOUS_HEAD].x, buf[PREVIOUS_HEAD].y);
|
buf[3].set(buf[PREVIOUS_HEAD].x, buf[PREVIOUS_HEAD].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnakeGame::on_fruit_eaten(Vector2i (*board)[COL]) {
|
void SnakeGame::add_tail_and_respawn_fruit(std::array<std::array<char, COL>, ROW> board) {
|
||||||
if(buf[FRUIT].y != buf[HEAD].y || buf[FRUIT].x != buf[HEAD].x) return;
|
|
||||||
int row, col;
|
int row, col;
|
||||||
do {
|
do {
|
||||||
row = (rand() % ROW);
|
row = (rand() % ROW);
|
||||||
col = (rand() % COL);
|
col = (rand() % COL);
|
||||||
} while (board[row][col].id != '.');
|
} while (board[row][col] != '.');
|
||||||
buf[FRUIT].set(row, col);
|
buf[FRUIT].set(row, col);
|
||||||
buf.insert(buf.begin() + 3, Vector2i { ROW, COL, '~' });
|
buf.insert(buf.begin() + 3, vec { ROW, COL });
|
||||||
m_score++;
|
m_score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnakeGame::segment_overlap() {
|
bool SnakeGame::segment_overlap() {
|
||||||
for(int i : std::ranges::views::iota(3, (int)buf.size())) {
|
for(int i : std::ranges::views::iota(3, (int)buf.size())) {
|
||||||
if( buf[i].y == buf[HEAD].y && buf[i].x == buf[HEAD].x) {
|
if(buf[i] == buf[HEAD]) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-17
@@ -1,31 +1,30 @@
|
|||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
#include "element.hpp"
|
#include "element.hpp"
|
||||||
#include <iostream>
|
#include <ncurses.h>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
void Window::clear_display() {
|
|
||||||
for(int i : std::ranges::views::iota(0, ROW)) {
|
|
||||||
for(int j : std::ranges::views::iota(0, COL)) {
|
|
||||||
board[i][j].id = '.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::draw_display() {
|
void Window::draw_display() {
|
||||||
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)) {
|
||||||
if(board[i][j].id != '.') { std::cout << board[i][j].id << " "; }
|
mvaddch(i, j * 2, board[i][j]);
|
||||||
else { std::cout << ". "; }
|
|
||||||
}
|
}
|
||||||
std::cout << "\r\n";
|
|
||||||
}
|
}
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::update_display(std::vector<Vector2i> &buf) {
|
void Window::update_display(std::vector<vec> &buf) {
|
||||||
for(int i : std::ranges::views::iota(0, (int)buf.size())) {
|
for(auto& row : board) row.fill('.');
|
||||||
if(i == 1) continue;
|
const auto &head = buf.at(HEAD);
|
||||||
board[buf[i].y][buf[i].x].id = buf[i].id;
|
board[head.y][head.x] = '*';
|
||||||
|
|
||||||
|
const auto &fruit = buf.at(FRUIT);
|
||||||
|
board[fruit.y][fruit.x] = 'o';
|
||||||
|
|
||||||
|
for(int i : std::ranges::views::iota(3, (int)buf.size())) {
|
||||||
|
const auto &segments = buf.at(i);
|
||||||
|
if(segments.x < COL && segments.y < ROW) {
|
||||||
|
board[segments.y][segments.x] = '~';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user