changed from raw pointer arrays to vectors
This commit is contained in:
+19
-10
@@ -1,28 +1,37 @@
|
|||||||
#ifndef ELEMENT_HPP
|
#ifndef ELEMENT_HPP
|
||||||
#define ELEMENT_HPP
|
#define ELEMENT_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
UP = -2,
|
UP, DOWN, LEFT, RIGHT
|
||||||
DOWN = 2,
|
|
||||||
LEFT = -1,
|
|
||||||
RIGHT = 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector2i {
|
struct Vector2i {
|
||||||
int x, y;
|
int x, y;
|
||||||
char id;
|
char id;
|
||||||
enum Direction m_dir;
|
|
||||||
Vector2i() : x(0), y(0), id('@') {}
|
Vector2i() : x(0), y(0), id('@') {}
|
||||||
Vector2i(int x, int y, char s) : x(x), y(y), id(s) {}
|
Vector2i(int x, int y, char s) : x(x), y(y), id(s) {}
|
||||||
void set(int x, int y);
|
void set(int x, int y);
|
||||||
};
|
};
|
||||||
|
|
||||||
int get_score();
|
class SnakeGame {
|
||||||
void determine_index_zero_pos(Vector2i** buf);
|
public:
|
||||||
void move_tail_indicies(Vector2i** buf);
|
SnakeGame();
|
||||||
void on_fruit_eaten(Vector2i (*board)[COL], Vector2i** buf);
|
// ~SnakeGame();
|
||||||
bool segment_overlap(Vector2i** buf);
|
// 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
|
#endif // ELEMENT_HPP
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ struct Window {
|
|||||||
Vector2i board[ROW][COL] = {};
|
Vector2i board[ROW][COL] = {};
|
||||||
void clear_display();
|
void clear_display();
|
||||||
void draw_display(int milliseconds);
|
void draw_display(int milliseconds);
|
||||||
void update_display(Vector2i** buf);
|
void update_display(std::vector<Vector2i> &buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINDOW_HPP
|
#endif // WINDOW_HPP
|
||||||
|
|||||||
+46
-32
@@ -3,58 +3,72 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <iostream>
|
||||||
int _score = 0;
|
|
||||||
int _snake_size = 3;
|
|
||||||
|
|
||||||
int get_score() { return _score; }
|
|
||||||
|
|
||||||
void Vector2i::set(int _x, int _y) {
|
void Vector2i::set(int _x, int _y) {
|
||||||
y = _y;
|
y = _y;
|
||||||
x = _x;
|
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];
|
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) {
|
switch(m_dir) {
|
||||||
case LEFT: head->x = (head->x + COL - 1) % COL; break;
|
case LEFT: head.x = (head.x + COL - 1) % COL; break;
|
||||||
case RIGHT: head->x = (head->x + 1) % COL; break;
|
case RIGHT: head.x = (head.x + 1) % COL; break;
|
||||||
case UP: head->y = (head->y + ROW - 1) % ROW; break;
|
case UP: head.y = (head.y + ROW - 1) % ROW; break;
|
||||||
case DOWN: head->y = (head->y + 1) % ROW; break;
|
case DOWN: head.y = (head.y + 1) % ROW; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_tail_indicies(Vector2i** buf) {
|
void SnakeGame::move_tail_indicies() {
|
||||||
if(_snake_size <= 3) return;
|
if(buf.size() <= 3) return;
|
||||||
Vector2i* last_point = buf[_snake_size - 1];
|
Vector2i last_point = buf.back();
|
||||||
|
buf.pop_back();
|
||||||
std::memmove(buf + 4, buf + 3, (_snake_size - 4) * sizeof(Vector2i*));
|
buf.insert(buf.begin() + 3, last_point);
|
||||||
|
buf[3].set(buf[PREVIOUS_HEAD].x, buf[PREVIOUS_HEAD].y);
|
||||||
buf[3] = last_point;
|
|
||||||
if(buf[3] != nullptr) last_point->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;
|
int row, col;
|
||||||
if(buf[FRUIT]->y != buf[HEAD]->y || buf[FRUIT]->x != buf[HEAD]->x) return;
|
|
||||||
do {
|
do {
|
||||||
row = (rand() % ROW);
|
row = (rand() % ROW);
|
||||||
col = (rand() % COL);
|
col = (rand() % COL);
|
||||||
} while (board[row][col].id != '.');
|
} while (board[row][col].id != '.');
|
||||||
buf[FRUIT]->set(row, col);
|
buf[FRUIT].set(row, col);
|
||||||
std::memmove(buf + 4, buf + 3, (_snake_size - 3) * sizeof(Vector2i*));
|
buf.insert(buf.begin() + 3, Vector2i { ROW, COL, '@' });
|
||||||
buf[3] = new Vector2i { ROW, COL, '@' };
|
m_score++;
|
||||||
_score++;
|
|
||||||
_snake_size++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool segment_overlap(Vector2i** buf) {
|
bool SnakeGame::segment_overlap() {
|
||||||
for(int i : std::ranges::views::iota(3, _snake_size)) {
|
for(int i : std::ranges::views::iota(3, (int)buf.size())) {
|
||||||
if(buf[i] &&
|
if( buf[i].y == buf[HEAD].y &&
|
||||||
buf[i]->y == buf[HEAD]->y &&
|
buf[i].x == buf[HEAD].x)
|
||||||
buf[i]->x == buf[HEAD]->x)
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-23
@@ -1,41 +1,25 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iostream>
|
|
||||||
#include "element.hpp"
|
#include "element.hpp"
|
||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
#include "globals.hpp"
|
|
||||||
#include "input.hpp"
|
#include "input.hpp"
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
std::srand(std::time(0));
|
std::srand(std::time(0));
|
||||||
|
SnakeGame engine;
|
||||||
Window win;
|
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, '*' };
|
std::thread input_thread([&] { get_input(engine.m_dir, engine.running ); } );
|
||||||
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(buf[HEAD]->m_dir, running ); } );
|
while (engine.exit_summary()) {
|
||||||
|
engine.on_fruit_eaten(win.board);
|
||||||
while (running) {
|
engine.determine_index_zero_pos();
|
||||||
on_fruit_eaten(win.board, buf);
|
engine.move_tail_indicies();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
win.clear_display();
|
win.clear_display();
|
||||||
win.update_display(buf);
|
win.update_display(engine.buf);
|
||||||
win.draw_display(200);
|
win.draw_display(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
input_thread.join();
|
input_thread.join();
|
||||||
for(auto& p : buf) delete p;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -4,6 +4,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
void Window::clear_display() {
|
void Window::clear_display() {
|
||||||
for(int i : std::ranges::views::iota(0, ROW)) {
|
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
|
std::this_thread::sleep_for(std::chrono::milliseconds((int) (milliseconds))); // 1000 / fps; 200ms = 5fps
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::update_display(Vector2i** buf) {
|
void Window::update_display(std::vector<Vector2i> &buf) {
|
||||||
for(int i : std::ranges::views::iota(0, ROW * COL)) {
|
for(int i : std::ranges::views::iota(0, (int)buf.size())) {
|
||||||
if(buf[i] == nullptr || i == 1 || buf[i]->y > ROW - 1 || buf[i]->x > COL - 1) continue;
|
// if(i == 1 || buf[i]->y > ROW - 1 || buf[i]->x > COL - 1) continue;
|
||||||
board[buf[i]->y][buf[i]->x].id = buf[i]->id;
|
if(i == 1) continue;
|
||||||
|
board[buf[i].y][buf[i].x].id = buf[i].id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user