Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfc381bd9b | ||
|
|
7ef5407684 | ||
|
|
d7faaaeaeb | ||
|
|
3d6a6142bd | ||
|
|
820c4b6dc4 | ||
|
|
4a2c46af9e | ||
|
|
700a48798e | ||
|
|
ff22fff701 | ||
|
|
8d4b3990d1 | ||
|
|
59c68b7bd3 | ||
|
|
9eb93dc691 | ||
|
|
7a79d4ac1a | ||
|
|
4f17b0c1e2 | ||
|
|
435f7d1a49 | ||
|
|
c5bb6e34b3 | ||
|
|
1160f3d147 | ||
|
|
e437b7b35f | ||
|
|
e87094ce13 | ||
|
|
183be3c24a | ||
|
|
1af33ba5a4 | ||
|
|
2c38da4b79 | ||
|
|
ab16f18137 | ||
|
|
02ff154b81 | ||
|
|
f9d0e9fb01 | ||
|
|
6c6605fcb5 | ||
|
|
baf2e21358 | ||
|
|
74cb3971cc | ||
|
|
959e539d4b | ||
|
|
99bcdbaf46 | ||
|
|
94006faff6 | ||
|
|
74a5d9738a | ||
|
|
7a6df4fbe5 | ||
|
|
1f3954ac79 | ||
|
|
abef01d7b8 | ||
|
|
119c1422c0 | ||
|
|
0d47de8a7a | ||
|
|
626d7261d4 | ||
|
|
9d3f6b3308 | ||
|
|
e36ab27f2b | ||
|
|
4bab69a3a8 | ||
|
|
cfa0e52705 | ||
|
|
b0393c65f2 | ||
|
|
96e5eb9930 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
BasedOnStyle: Google
|
||||||
|
Standard: Latest
|
||||||
|
UseTab: Always
|
||||||
|
TabWidth: 8
|
||||||
|
IndentWidth: 8
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
BreakAfterReturnType: TopLevel
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
ReflowComments: Always
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
IndentAccessModifiers: false # Indent access specifiers by one level
|
||||||
|
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
|
||||||
+5
-15
@@ -1,23 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
project(snake)
|
|
||||||
set(CMAKE_C_STANDARD 23)
|
set(CMAKE_C_STANDARD 23)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
include_directories(include)
|
project(snake LANGUAGES C)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/main.cpp
|
src/main.c
|
||||||
src/snake.cpp
|
src/engine.c
|
||||||
src/input.cpp
|
|
||||||
src/window.cpp
|
|
||||||
src/point.cpp
|
|
||||||
src/fruit.cpp
|
|
||||||
|
|
||||||
)
|
)
|
||||||
add_executable(snake ${SOURCES})
|
add_executable(snake ${SOURCES})
|
||||||
|
|
||||||
find_package(Curses REQUIRED)
|
target_include_directories(snake PRIVATE include)
|
||||||
include_directories(${CURSES_INCLUDE_DIR})
|
|
||||||
target_link_libraries(snake ${CURSES_LIBRARIES})
|
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
build/compile_commands.json
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef ENGINE_HPP
|
||||||
|
#define ENGINE_HPP
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#define ROW 15
|
||||||
|
#define COL 21
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
LEFT,
|
||||||
|
RIGHT
|
||||||
|
} Direction;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
} vec2;
|
||||||
|
|
||||||
|
int
|
||||||
|
equals(vec2* a, vec2* b);
|
||||||
|
|
||||||
|
void
|
||||||
|
set(vec2* vec2, int _x, int _y);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char view[ROW][COL];
|
||||||
|
int m_score, tail_size;
|
||||||
|
vec2 head, fruit, prev_head;
|
||||||
|
vec2 tail[(ROW * COL) - 1];
|
||||||
|
Direction dir;
|
||||||
|
|
||||||
|
} Engine;
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_init(Engine* engine);
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_display(Engine* engine);
|
||||||
|
|
||||||
|
int
|
||||||
|
process_input(Direction* dir);
|
||||||
|
|
||||||
|
int
|
||||||
|
is_open(char* status, size_t len, Engine* engine);
|
||||||
|
|
||||||
|
void
|
||||||
|
eat(Engine* engine);
|
||||||
|
|
||||||
|
void
|
||||||
|
move(Engine *engine);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#ifndef FRUIT_HPP
|
|
||||||
#define FRUIT_HPP
|
|
||||||
|
|
||||||
#include "point.hpp"
|
|
||||||
|
|
||||||
struct Fruit {
|
|
||||||
Fruit();
|
|
||||||
Point m_point;
|
|
||||||
void reset(std::array<std::array<char, COL>, ROW> &board, int row, int col, int &score);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FRUIT_HPP
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef GLOBALS_HPP
|
|
||||||
#define GLOBALS_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
constexpr uint16_t ROW = 11;
|
|
||||||
constexpr uint16_t COL = 11;
|
|
||||||
constexpr uint16_t FPS = 5;
|
|
||||||
|
|
||||||
#endif // GLOBALS_HPP
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef INPUT_HPP
|
|
||||||
#define INPUT_HPP
|
|
||||||
|
|
||||||
struct Input {
|
|
||||||
int m_current_key = 0;
|
|
||||||
char m_getch = ' ';
|
|
||||||
void get_input(int &d, bool &c, bool &r);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // INPUT_HPP
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef POINT_HPP
|
|
||||||
#define POINT_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <string>
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
struct Point {
|
|
||||||
int m_row;
|
|
||||||
int m_col;
|
|
||||||
int m_direction;
|
|
||||||
Point() {}
|
|
||||||
Point(int x, int y) : m_row(x), m_col(y) {}
|
|
||||||
Point(int x, int y, int dir) : m_row(x), m_col(y), m_direction(dir) {}
|
|
||||||
|
|
||||||
std::string to_string() const;
|
|
||||||
void clear(std::array<std::array<char, COL>, ROW> &arr) const;
|
|
||||||
void set_new_point(int x, int y, int dir);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // POINT_HPP
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#ifndef SNAKE_HPP
|
|
||||||
#define SNAKE_HPP
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "point.hpp"
|
|
||||||
|
|
||||||
struct Head {
|
|
||||||
Head();
|
|
||||||
Head(int default_direction, int row, int col);
|
|
||||||
Point m_head;
|
|
||||||
Point m_previous_head;
|
|
||||||
void get_new_point(int direction);
|
|
||||||
void get_previous_point();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Tail {
|
|
||||||
Tail(int follow_direction, int row, int col);
|
|
||||||
Point m_tail_pos;
|
|
||||||
Point m_previous_tail_pos;
|
|
||||||
std::vector<Point> m_move_history;
|
|
||||||
void get_previous_point();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Body {
|
|
||||||
std::vector<Tail> m_body;
|
|
||||||
void clear(std::array<std::array<char, COL>, ROW> &arr);
|
|
||||||
void draw(std::array<std::array<char, COL>, ROW> &arr);
|
|
||||||
void move(Head &head);
|
|
||||||
void get_new_points(Head &head);
|
|
||||||
void collision(Head &head, bool &running);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#ifndef WINDOW_HPP
|
|
||||||
#define WINDOW_HPP
|
|
||||||
#include <array>
|
|
||||||
#include "globals.hpp"
|
|
||||||
#include "fruit.hpp"
|
|
||||||
#include "snake.hpp"
|
|
||||||
|
|
||||||
struct Window {
|
|
||||||
Window();
|
|
||||||
std::array<std::array<char, COL>, ROW> m_board;
|
|
||||||
int m_score;
|
|
||||||
int m_reset;
|
|
||||||
int m_previous_reset;
|
|
||||||
|
|
||||||
void draw_window();
|
|
||||||
void tick(double frames_per_second);
|
|
||||||
void kill(bool &running);
|
|
||||||
void update_score(Fruit &fruit, Body &body);
|
|
||||||
void update_display(int fps);
|
|
||||||
void check_exit(bool &running, Body &body, bool &collision);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WINDOW_HPP
|
|
||||||
+169
@@ -0,0 +1,169 @@
|
|||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
set(vec2* vec2, int _x, int _y)
|
||||||
|
{
|
||||||
|
vec2->x = _x;
|
||||||
|
vec2->y = _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
equals(vec2* a, vec2* b)
|
||||||
|
{
|
||||||
|
return (a->x == b->x && a->y == b->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_init(Engine* engine)
|
||||||
|
{
|
||||||
|
srand(time(0));
|
||||||
|
set(&engine->head, COL / 2, ROW / 2);
|
||||||
|
set(&engine->prev_head, engine->head.x, engine->head.y);
|
||||||
|
set(&engine->fruit, rand() % COL, rand() % ROW);
|
||||||
|
|
||||||
|
engine->dir = RIGHT;
|
||||||
|
engine->m_score = 0;
|
||||||
|
engine->tail_size = 0;
|
||||||
|
memset(engine->view, '.', sizeof(engine->view));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
engine_display(Engine* engine)
|
||||||
|
{
|
||||||
|
engine->view[engine->fruit.y][engine->fruit.x] = 'o';
|
||||||
|
if (engine->tail_size != 0)
|
||||||
|
{
|
||||||
|
for (char i = 0; i < engine->tail_size; i++)
|
||||||
|
{
|
||||||
|
if (engine->tail[i].x < COL && engine->tail[i].y < ROW)
|
||||||
|
{
|
||||||
|
engine->view[engine->tail[i].y]
|
||||||
|
[engine->tail[i].x] = '~';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write(1, "\033[H\033[J", sizeof("\033[H\033[J") - 1);
|
||||||
|
char str[(COL * 2 + 2) * ROW] = { 0 };
|
||||||
|
char* ptr = str;
|
||||||
|
for (char i = 0; i < ROW; i++)
|
||||||
|
{
|
||||||
|
for (char j = 0; j < COL; j++)
|
||||||
|
{
|
||||||
|
memcpy(ptr, " ", 1);
|
||||||
|
ptr++;
|
||||||
|
memcpy(ptr, &engine->view[i][j], 1);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
memcpy(ptr, "\r\n", 2);
|
||||||
|
ptr += 2;
|
||||||
|
}
|
||||||
|
write(1, str, ptr - str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
process_input(Direction* dir)
|
||||||
|
{
|
||||||
|
unsigned char ch;
|
||||||
|
if (read(1, &ch, 1) > 0)
|
||||||
|
{
|
||||||
|
if (ch == 'q') return 0;
|
||||||
|
if (ch == 'w')
|
||||||
|
if (*dir != DOWN) *dir = UP;
|
||||||
|
if (ch == 's')
|
||||||
|
if (*dir != UP) *dir = DOWN;
|
||||||
|
if (ch == 'd')
|
||||||
|
if (*dir != LEFT) *dir = RIGHT;
|
||||||
|
if (ch == 'a')
|
||||||
|
if (*dir != RIGHT) *dir = LEFT;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
is_open(char* status, size_t len, Engine* engine)
|
||||||
|
{
|
||||||
|
if (engine->tail_size >= (ROW * COL) - 1)
|
||||||
|
{
|
||||||
|
snprintf(status, len,
|
||||||
|
"You filled the whole board and won! "
|
||||||
|
"Score: %d",
|
||||||
|
engine->m_score);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < engine->tail_size; i++)
|
||||||
|
{
|
||||||
|
if (equals(&engine->tail[i], &engine->head))
|
||||||
|
{
|
||||||
|
snprintf(status, len,
|
||||||
|
"You collided with yourself and died! "
|
||||||
|
"Score: %d",
|
||||||
|
engine->m_score);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
move(Engine* engine)
|
||||||
|
{
|
||||||
|
set(&engine->prev_head, engine->head.x, engine->head.y);
|
||||||
|
|
||||||
|
if (engine->dir == LEFT)
|
||||||
|
engine->head.x = (engine->head.x + COL - 1) % COL;
|
||||||
|
else if (engine->dir == RIGHT)
|
||||||
|
engine->head.x = (engine->head.x + 1) % COL;
|
||||||
|
else if (engine->dir == UP)
|
||||||
|
engine->head.y = (engine->head.y + ROW - 1) % ROW;
|
||||||
|
else if (engine->dir == DOWN)
|
||||||
|
engine->head.y = (engine->head.y + 1) % ROW;
|
||||||
|
engine->view[engine->prev_head.y][engine->prev_head.x] = '.';
|
||||||
|
engine->view[engine->head.y][engine->head.x] = '*';
|
||||||
|
|
||||||
|
if (engine->tail_size == 0) return;
|
||||||
|
|
||||||
|
vec2 old_tail = engine->tail[engine->tail_size - 1];
|
||||||
|
memmove(&engine->tail[1], &engine->tail[0],
|
||||||
|
sizeof(vec2) * (engine->tail_size - 1));
|
||||||
|
|
||||||
|
engine->view[old_tail.y][old_tail.x] = '.';
|
||||||
|
set(&engine->tail[0], engine->prev_head.x, engine->prev_head.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eat(Engine* engine)
|
||||||
|
{
|
||||||
|
vec2 new_pos;
|
||||||
|
set(&new_pos, 0, 0);
|
||||||
|
int collision = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
collision = 0;
|
||||||
|
set(&new_pos, (rand() % COL), (rand() % ROW));
|
||||||
|
if (equals(&new_pos, &engine->head))
|
||||||
|
{
|
||||||
|
collision = 1;
|
||||||
|
}
|
||||||
|
if (engine->tail_size > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < engine->tail_size; i++)
|
||||||
|
{
|
||||||
|
if (equals(&new_pos, &engine->tail[i]))
|
||||||
|
{
|
||||||
|
collision = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (collision);
|
||||||
|
engine->fruit = new_pos;
|
||||||
|
set(&engine->tail[engine->tail_size], engine->prev_head.x,
|
||||||
|
engine->prev_head.y);
|
||||||
|
engine->tail_size++;
|
||||||
|
engine->m_score++;
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#include <cstdlib>
|
|
||||||
#include <ctime>
|
|
||||||
#include "fruit.hpp"
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
Fruit::Fruit() {
|
|
||||||
std::srand(std::time(0));
|
|
||||||
m_point.m_row = (rand() % 9);
|
|
||||||
m_point.m_col = (rand() % 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fruit::reset(std::array<std::array<char, COL>, ROW> &board, int row, int col, int &score) {
|
|
||||||
if(m_point.m_row == row && m_point.m_col == col) {
|
|
||||||
m_point.clear(board);
|
|
||||||
m_point.m_row = (rand() % 9);
|
|
||||||
m_point.m_col = (rand() % 9);
|
|
||||||
score++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#include "input.hpp"
|
|
||||||
#include <ncurses.h>
|
|
||||||
|
|
||||||
void Input::get_input(int &d, bool &c, bool &r) {
|
|
||||||
bool running = true;
|
|
||||||
while(running && !(c)) {
|
|
||||||
initscr();
|
|
||||||
cbreak();
|
|
||||||
noecho();
|
|
||||||
|
|
||||||
m_getch = getch();
|
|
||||||
endwin();
|
|
||||||
if(m_current_key != 1 && (m_getch == 'a' || m_getch == 'D')) {
|
|
||||||
d = m_current_key = -1;
|
|
||||||
} else if(m_current_key != - 1 && (m_getch == 'd' || m_getch == 'C')) {
|
|
||||||
d = m_current_key = 1;
|
|
||||||
m_current_key = 1;
|
|
||||||
} else if(m_current_key != -2 && (m_getch == 's' || m_getch == 'B')) {
|
|
||||||
d = m_current_key = 2;
|
|
||||||
} else if(m_current_key != 2 && (m_getch == 'w' || m_getch == 'A')) {
|
|
||||||
d = m_current_key = -2;
|
|
||||||
} else if(m_getch == 'q') {
|
|
||||||
r = running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
Engine engine;
|
||||||
|
engine_init(&engine);
|
||||||
|
char status[64] = { 0 };
|
||||||
|
static struct termios oldt, newt;
|
||||||
|
struct timespec req;
|
||||||
|
|
||||||
|
tcgetattr(STDIN_FILENO, &oldt);
|
||||||
|
newt = oldt;
|
||||||
|
newt.c_lflag &= ~(ICANON | ECHO);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||||
|
req.tv_nsec = 1.5e8;
|
||||||
|
req.tv_sec = 0;
|
||||||
|
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
|
||||||
|
|
||||||
|
while (is_open(status, 64, &engine) && process_input(&engine.dir))
|
||||||
|
{
|
||||||
|
if (equals(&engine.fruit, &engine.head))
|
||||||
|
{
|
||||||
|
eat(&engine);
|
||||||
|
}
|
||||||
|
move(&engine);
|
||||||
|
engine_display(&engine);
|
||||||
|
nanosleep(&req, NULL);
|
||||||
|
}
|
||||||
|
write(1, status, sizeof(status));
|
||||||
|
write(1, "\033[?25h", 6);
|
||||||
|
tcsetattr(0, TCSANOW, &oldt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#include <thread>
|
|
||||||
#include "point.hpp"
|
|
||||||
#include "fruit.hpp"
|
|
||||||
#include "snake.hpp"
|
|
||||||
#include "window.hpp"
|
|
||||||
#include "globals.hpp"
|
|
||||||
#include "input.hpp"
|
|
||||||
|
|
||||||
int main () {
|
|
||||||
Window window;
|
|
||||||
Input input;
|
|
||||||
Fruit fruit;
|
|
||||||
Body body;
|
|
||||||
Head head;
|
|
||||||
bool running = true;
|
|
||||||
bool collision = false;
|
|
||||||
std::thread input_thread(
|
|
||||||
&Input::get_input, &input,
|
|
||||||
std::ref(head.m_head.m_direction),
|
|
||||||
std::ref(collision),
|
|
||||||
std::ref(running));
|
|
||||||
|
|
||||||
while (running) {
|
|
||||||
body.collision(head, collision);
|
|
||||||
window.update_score(fruit, body);
|
|
||||||
window.check_exit(running, body, collision);
|
|
||||||
head.get_new_point(head.m_head.m_direction);
|
|
||||||
body.get_new_points(head);
|
|
||||||
head.get_previous_point();
|
|
||||||
|
|
||||||
fruit.reset(window.m_board, head.m_head.m_row, head.m_head.m_col, window.m_score);
|
|
||||||
window.m_board[head.m_head.m_row][head.m_head.m_col] = '*';
|
|
||||||
window.m_board[fruit.m_point.m_row][fruit.m_point.m_col] = 'X';
|
|
||||||
body.draw(window.m_board);
|
|
||||||
window.update_display(FPS);
|
|
||||||
body.clear(window.m_board);
|
|
||||||
head.m_head.clear(window.m_board);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_thread.join();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#include <string>
|
|
||||||
#include "point.hpp"
|
|
||||||
|
|
||||||
std::string Point::to_string() const {
|
|
||||||
return "(" + std::to_string(m_row) + ", " + std::to_string(m_col) + "), " + std::to_string(m_direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Point::clear(std::array<std::array<char, COL>, ROW> &arr) const {
|
|
||||||
arr[m_row][m_col] = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
void Point::set_new_point(int row, int col, int dir) {
|
|
||||||
m_row = row;
|
|
||||||
m_col = col;
|
|
||||||
m_direction = dir;
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
#include "snake.hpp"
|
|
||||||
|
|
||||||
Head::Head() {
|
|
||||||
m_head = Point { 5, 5, 2 };
|
|
||||||
m_previous_head.set_new_point(m_previous_head.m_row = 0, m_previous_head.m_col = 0, m_previous_head.m_direction = 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Head::Head(int default_direction, int row, int col) {
|
|
||||||
m_head = Point { row, col, default_direction };
|
|
||||||
m_previous_head.set_new_point(m_previous_head.m_row = 0, m_previous_head.m_col = 0, m_previous_head.m_direction = 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Head::get_new_point(int direction) {
|
|
||||||
if (direction == -1) {
|
|
||||||
if (m_head.m_col <= 0) m_head.m_col = COL - 1;
|
|
||||||
else m_head.m_col--;
|
|
||||||
} else if (direction == 1) {
|
|
||||||
if (m_head.m_col >= COL - 1) m_head.m_col = 0;
|
|
||||||
else m_head.m_col++;
|
|
||||||
} else if (direction == -2) {
|
|
||||||
if (m_head.m_row <= 0) m_head.m_row = ROW - 1;
|
|
||||||
else m_head.m_row--;
|
|
||||||
} else if (direction == 2) {
|
|
||||||
if (m_head.m_row >= ROW - 1) m_head.m_row = 0;
|
|
||||||
else m_head.m_row++;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Head::get_previous_point() {
|
|
||||||
m_previous_head.m_row = m_head.m_row;
|
|
||||||
m_previous_head.m_col = m_head.m_col;
|
|
||||||
m_previous_head.m_direction = m_head.m_direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tail::Tail(int follow_direction, int row, int col) {
|
|
||||||
m_tail_pos = Point { row, col, follow_direction };
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tail::get_previous_point() {
|
|
||||||
m_tail_pos.m_row = m_previous_tail_pos.m_row;
|
|
||||||
m_tail_pos.m_col = m_previous_tail_pos.m_col;
|
|
||||||
m_tail_pos.m_direction = m_previous_tail_pos.m_direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Body::collision(Head &head, bool &collision) {
|
|
||||||
for(int i = 0; i < m_body.size(); i++) {
|
|
||||||
if(m_body.at(i).m_tail_pos.m_row == head.m_head.m_row) {
|
|
||||||
if(m_body.at(i).m_tail_pos.m_col == head.m_head.m_col) {
|
|
||||||
collision = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Body::clear(std::array<std::array<char, COL>, ROW> &arr) {
|
|
||||||
for(int i = 0; i < m_body.size(); i++) {
|
|
||||||
m_body.at(i).m_tail_pos.clear(arr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Body::draw(std::array<std::array<char, COL>, ROW> &arr) {
|
|
||||||
for(int i = 0; i < m_body.size(); i++) {
|
|
||||||
if(i < m_body.size()) {
|
|
||||||
arr[m_body.at(i).m_tail_pos.m_row][m_body.at(i).m_tail_pos.m_col] = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Body::move(Head &head) {
|
|
||||||
for (int i = 0; i < m_body.size(); i++) {
|
|
||||||
if(i == 0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Body::get_new_points(Head &head) {
|
|
||||||
for (int i = 0; i < m_body.size(); i++) {
|
|
||||||
if(i == 0) {
|
|
||||||
m_body.at(i).m_previous_tail_pos.set_new_point(
|
|
||||||
head.m_previous_head.m_row,
|
|
||||||
head.m_previous_head.m_col,
|
|
||||||
head.m_previous_head.m_direction);
|
|
||||||
} else {
|
|
||||||
m_body.at(i).m_previous_tail_pos.set_new_point(
|
|
||||||
m_body.at(i - 1).m_tail_pos.m_row,
|
|
||||||
m_body.at(i - 1).m_tail_pos.m_col,
|
|
||||||
m_body.at(i - 1).m_tail_pos.m_direction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < m_body.size(); i++) {
|
|
||||||
m_body.at(i).get_previous_point();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#include "window.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <chrono>
|
|
||||||
#include <string>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
Window::Window() {
|
|
||||||
for(std::array<char, COL> &row : m_board) {
|
|
||||||
row.fill('.');
|
|
||||||
}
|
|
||||||
m_score = 0;
|
|
||||||
m_reset = 0;
|
|
||||||
m_previous_reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::check_exit(bool &running, Body &body, bool &collision) {
|
|
||||||
if(body.m_body.size() >= (ROW * COL)) {
|
|
||||||
std::cout << "You win! Score: " + std::to_string(body.m_body.size()) << std::endl;
|
|
||||||
kill(running);
|
|
||||||
} else if(collision) {
|
|
||||||
std::cout << "You died! Score: " + std::to_string(body.m_body.size()) << std::endl;
|
|
||||||
kill(running);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::update_score(Fruit &fruit, Body &body) {
|
|
||||||
if(m_score >= 1) {
|
|
||||||
m_score = 0;
|
|
||||||
body.m_body.push_back(Tail{2, 0, 0});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::kill(bool &running) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::update_display(int fps) {
|
|
||||||
std::cout<<"\033[H" << std::flush;
|
|
||||||
draw_window();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds((int) (200))); // 1000 / fps; 200ms = 5fps
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user