Skip to content

Commit

Permalink
Merge pull request #12 from drawpitech/nibbler
Browse files Browse the repository at this point in the history
Nibbler
  • Loading branch information
drawbu authored Apr 7, 2024
2 parents c470aa4 + fe366f2 commit a125621
Show file tree
Hide file tree
Showing 18 changed files with 486 additions and 3 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_subdirectory(Arcade)

# ↓ Games
add_subdirectory(Games/snake)
add_subdirectory(Games/nibbler)

# ↓ Renderer
add_subdirectory(Renderer/NCurses)
Expand Down
2 changes: 2 additions & 0 deletions Games/nibbler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set(TARGET nibbler)
include(${CMAKE_SOURCE_DIR}/CMakeCommonLib.cmake)
43 changes: 43 additions & 0 deletions Games/nibbler/Fruit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
** EPITECH PROJECT, 2024
** Arcade
** File description:
** Fruit
*/

#include <ASS/Events.hpp>
#include <ASS/IGame.hpp>
#include <ASS/ISprite.hpp>
#include <ASS/Vector2.hpp>

#include "Nibbler.hpp"

Fruit::Fruit(ass::IEngine &engine) : _sprite(engine.create_sprite())
{
_sprite->set_asset({
.sprite =
{
.height = 1,
.width = 1,
.chars = {{'x'}},
.char_colors = {{ass::xterm_color_t(ass::TermColor::Red)}},
},
.path = "assets/nibbler/fruit.png",
});
_sprite->move({9, 8});
}

void Fruit::move(pos_t pos)
{
_sprite->move(pos);
}

pos_t Fruit::position()
{
return _sprite->position();
}

void Fruit::draw(ass::IEngine &engine)
{
engine.draw_sprite(*_sprite);
}
73 changes: 73 additions & 0 deletions Games/nibbler/Map.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
** EPITECH PROJECT, 2024
** Arcade
** File description:
** Map
*/

#include <iostream>
#include "Nibbler.hpp"

Map::Map(ass::IEngine &engine) : _sprite(engine.create_sprite())
{
// init map
for (const auto &line : MAP) {
std::vector<MapPart> v;

for (char tile : line) {
switch (tile) {
case ' ':
v.push_back(MapPart::Void);
break;
case 'O':
v.push_back(MapPart::Wall);
break;
default:
throw std::runtime_error("Invalid tile in map");
}
}

_map.push_back(v);
}

// init sprite
_sprite->set_asset({
.sprite =
{
.height = 1,
.width = 1,
.chars = {{L'\x2588'}}, // L'\x2588' L'█'
.char_colors = {{ass::xterm_color_t(ass::TermColor::White)}},
},
.path = "assets/nibbler/wall.png",
});
}

Map::~Map() = default;

Map::MapPart Map::get_tile(pos_t pos) const
{
auto x = static_cast<size_t>(pos.x);
auto y = static_cast<size_t>(pos.y);

if (x < 0 || y < 0)
throw std::runtime_error("Invalid position");
if (y >= _map.size() || x >= _map.at(y).size())
throw std::runtime_error("Invalid position");
return _map.at(y).at(x);
}

void Map::draw(ass::IEngine &engine)
{
for (size_t y = 0; y < _map.size(); y++) {
for (size_t x = 0; x < _map.at(y).size(); x++) {
if (_map.at(y).at(x) != Map::MapPart::Wall)
continue;
_sprite->move({
.x = static_cast<float>(x),
.y = static_cast<float>(y),
});
engine.draw_sprite(*_sprite);
}
}
}
83 changes: 83 additions & 0 deletions Games/nibbler/Nibbler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
** EPITECH PROJECT, 2024
** Arcade
** File description:
** Snake
*/

#include "Nibbler.hpp"

#include <ASS/Events.hpp>
#include <ASS/IGame.hpp>
#include <ASS/ISprite.hpp>
#include <ASS/Vector2.hpp>
#include <ctime>

extern "C" std::unique_ptr<ass::IGame> uwu_goofy_ahhh_game_entrypoint()
{
return std::make_unique<Nibbler>();
}

Nibbler::Nibbler()
{
std::srand(std::time(nullptr));
}

Nibbler::~Nibbler() = default;

ass::RunStatus Nibbler::run(ass::IEngine &engine)
{
Player snake{engine};
Fruit fruit{engine};
Map map{engine};

while (true) {
// Move the snake
for (auto &event : engine.events()) {
if (event.state != ass::EventState::KeyPressed)
continue;
switch (event.key) {
case ass::EventKey::KeyQ:
return ass::RunStatus::Exit;
case ass::EventKey::KeyR:
return ass::RunStatus::Restart;
case ass::EventKey::KeyM:
return ass::RunStatus::ShowMenu;
case ass::EventKey::KeyN:
engine.next_renderer();
break;
case ass::EventKey::KeyUp:
snake.set_direction(Direction::Up, map);
break;
case ass::EventKey::KeyDown:
snake.set_direction(Direction::Down, map);
break;
case ass::EventKey::KeyLeft:
snake.set_direction(Direction::Left, map);
break;
case ass::EventKey::KeyRight:
snake.set_direction(Direction::Right, map);
break;
case ass::EventKey::KeySpace:
for (size_t i = 0; i < 3; i++)
snake.move(fruit, map);
break;
default:
break;
}
}
snake.move(fruit, map);

// Check if the player is dead
if (snake.is_dead(engine))
return ass::RunStatus::Exit;

// Redraw screen
engine.clear(ass::TermColor::Black);
fruit.draw(engine);
snake.draw(engine);
map.draw(engine);
engine.refresh();
engine.wait_frame(7 + snake.get_size() / 4);
}
}
114 changes: 114 additions & 0 deletions Games/nibbler/Nibbler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
** EPITECH PROJECT, 2024
** Arcade
** File description:
** Snake
*/

#pragma once

#include <ASS/IEngine.hpp>
#include <ASS/IGame.hpp>
#include <queue>

#include "ASS/ISprite.hpp"

class Nibbler : public ass::IGame
{
public:
Nibbler();
~Nibbler() override;

ass::RunStatus run(ass::IEngine &engine) final;
};

enum class Direction
{
Up,
Down,
Left,
Right,
};

using pos_t = ass::Vector2<float>;

class Fruit
{
public:
Fruit(ass::IEngine &engine);
~Fruit() = default;

void draw(ass::IEngine &engine);
void move(pos_t pos);
pos_t position();

private:
std::unique_ptr<ass::ISprite> _sprite;
};

class Map
{
public:
Map(ass::IEngine &engine);
~Map();

enum class MapPart : char
{
Void,
Wall,
};

MapPart get_tile(pos_t pos) const;
void draw(ass::IEngine &engine);

private:
std::vector<std::vector<MapPart>> _map;
std::unique_ptr<ass::ISprite> _sprite;
};

class Player
{
public:
Player(ass::IEngine &engine);
~Player() = default;

void draw(ass::IEngine &engine);
void move(Fruit &fruit, Map &map);
bool is_dead(ass::IEngine &engine);
void grow();
void set_direction(Direction direction, Map &map);

pos_t &get_head();
pos_t &get_tail();
size_t get_size() const;

private:
std::unique_ptr<ass::ISprite> _sprite;
Direction _current_direction;
Direction _last_direction;
std::vector<pos_t> _body;

bool is_safe(Direction dir, Map &map);
};

static const std::vector<std::string> MAP{
"OOOOOOOOOOOOOOOOOOO",
"O O",
"O OOO O OOO O OOO O",
"O O O O O O O O",
"O OOO O O O O OOO O",
"O O O O O O",
"O OOOOO O O OOOOO O",
"O O O O",
"O O OOOOO OOOOO O O",
"O O",
"O OOOOO OOO OOOOO O",
"O O O O",
"O OOO O OOO O OOO O",
"O O O O O O O O",
"O OOO O OOO O OOO O",
"O O O O O O",
"O OOOOO OOO OOOOO O",
"O O",
"OOOOOOOOOOOOOOOOOOO",
};
Loading

0 comments on commit a125621

Please sign in to comment.