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
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "globals.hpp"
|
||||
|
||||
@@ -11,12 +12,12 @@ enum Direction {
|
||||
UP, DOWN, LEFT, RIGHT
|
||||
};
|
||||
|
||||
struct Vector2i {
|
||||
struct vec {
|
||||
int x, y;
|
||||
char id;
|
||||
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);
|
||||
vec() : x(0), y(0) {}
|
||||
vec(int x, int y) : x(x), y(y) {}
|
||||
void set(int _x, int _y) { x = _x; y = _y; }
|
||||
auto operator <=> (const vec&) const = default;
|
||||
};
|
||||
|
||||
class SnakeGame {
|
||||
@@ -26,15 +27,15 @@ public:
|
||||
void run();
|
||||
|
||||
private:
|
||||
Window* win;
|
||||
std::vector<Vector2i> buf;
|
||||
std::unique_ptr<Window> win;
|
||||
std::vector<vec> buf;
|
||||
bool running = true;
|
||||
enum Direction m_dir;
|
||||
uint8_t m_score = 0;
|
||||
void process_input();
|
||||
void determine_index_zero_pos();
|
||||
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 exit_summary();
|
||||
};
|
||||
|
||||
+3
-3
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "globals.hpp"
|
||||
#include "element.hpp"
|
||||
#include <array>
|
||||
|
||||
struct Window {
|
||||
Vector2i board[ROW][COL] = {};
|
||||
void clear_display();
|
||||
std::array<std::array<char, COL>, ROW> board;
|
||||
void draw_display();
|
||||
void update_display(std::vector<Vector2i> &buf);
|
||||
void update_display(std::vector<vec> &buf);
|
||||
};
|
||||
|
||||
#endif // WINDOW_HPP
|
||||
|
||||
+15
-23
@@ -2,6 +2,7 @@
|
||||
#include "globals.hpp"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <ncurses.h>
|
||||
#include <ranges>
|
||||
#include <iostream>
|
||||
@@ -9,11 +10,6 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
void Vector2i::set(int _x, int _y) {
|
||||
y = _y;
|
||||
x = _x;
|
||||
}
|
||||
|
||||
SnakeGame::SnakeGame() {
|
||||
std::srand(std::time(0));
|
||||
initscr();
|
||||
@@ -21,25 +17,25 @@ SnakeGame::SnakeGame() {
|
||||
noecho();
|
||||
curs_set(0);
|
||||
nodelay(stdscr, true);
|
||||
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' });
|
||||
win = new Window();
|
||||
buf.push_back(vec{ COL / 2, ROW / 2 });
|
||||
buf.push_back(vec{ buf.front().x, buf.front().y });
|
||||
buf.push_back(vec{ (rand() % COL), (rand() % ROW) });
|
||||
win = std::make_unique<Window>();
|
||||
}
|
||||
|
||||
SnakeGame::~SnakeGame() {
|
||||
delete win;
|
||||
endwin();
|
||||
}
|
||||
|
||||
void SnakeGame::run() {
|
||||
while (exit_summary()) {
|
||||
process_input();
|
||||
on_fruit_eaten(win->board);
|
||||
if(buf[FRUIT] == buf[HEAD]) {
|
||||
add_tail_and_respawn_fruit(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)));
|
||||
@@ -60,9 +56,8 @@ void SnakeGame::process_input() {
|
||||
}
|
||||
|
||||
bool SnakeGame::exit_summary() {
|
||||
if(!running) {
|
||||
return false;
|
||||
} if(buf.size() >= MAX_LEN - 1) {
|
||||
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()) {
|
||||
@@ -85,29 +80,26 @@ void SnakeGame::determine_index_zero_pos() {
|
||||
|
||||
void SnakeGame::move_tail_indicies() {
|
||||
if(buf.size() <= 3) return;
|
||||
Vector2i last_point = buf.back();
|
||||
vec 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 SnakeGame::on_fruit_eaten(Vector2i (*board)[COL]) {
|
||||
if(buf[FRUIT].y != buf[HEAD].y || buf[FRUIT].x != buf[HEAD].x) return;
|
||||
void SnakeGame::add_tail_and_respawn_fruit(std::array<std::array<char, COL>, ROW> board) {
|
||||
int row, col;
|
||||
do {
|
||||
row = (rand() % ROW);
|
||||
col = (rand() % COL);
|
||||
} while (board[row][col].id != '.');
|
||||
} while (board[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++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if(buf[i] == buf[HEAD]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+16
-17
@@ -1,31 +1,30 @@
|
||||
#include "window.hpp"
|
||||
#include "element.hpp"
|
||||
#include <iostream>
|
||||
#include <ncurses.h>
|
||||
#include <ranges>
|
||||
#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() {
|
||||
std::cout << "\033[H" << std::flush; // Clear screen
|
||||
for(int i : std::ranges::views::iota(0, ROW)) {
|
||||
for(int j : std::ranges::views::iota(0, COL)) {
|
||||
if(board[i][j].id != '.') { std::cout << board[i][j].id << " "; }
|
||||
else { std::cout << ". "; }
|
||||
mvaddch(i, j * 2, board[i][j]);
|
||||
}
|
||||
std::cout << "\r\n";
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
void Window::update_display(std::vector<Vector2i> &buf) {
|
||||
for(int i : std::ranges::views::iota(0, (int)buf.size())) {
|
||||
if(i == 1) continue;
|
||||
board[buf[i].y][buf[i].x].id = buf[i].id;
|
||||
void Window::update_display(std::vector<vec> &buf) {
|
||||
for(auto& row : board) row.fill('.');
|
||||
const auto &head = buf.at(HEAD);
|
||||
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