Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <random>
- #include <array>
- #include <vector>
- struct Input {
- bool w_pressed{};
- bool s_pressed{};
- bool a_pressed{};
- bool d_pressed{};
- };
- template<class T>
- struct Point {
- Point() = default;
- Point(T x_, T y_) : x(x_), y(y_) {}
- T x{};
- T y{};
- };
- enum class Cell {
- Empty,
- Snake,
- Food
- };
- template<std::size_t W, std::size_t H>
- class Field {
- public:
- std::array<std::array<Cell, H>, W> cells;
- };
- template<std::size_t W, std::size_t H>
- class Game {
- public:
- Game() : direction{Left}, skore{0} {}
- void step(Input const& input) {
- std::uniform_int_distribution<> spawn_food_probability(0, 10);
- if (spawn_food_probability(prng) == 0) {
- spawn_food();
- }
- if (input.w_pressed && direction != Down) { direction = Up; }
- else if (input.s_pressed && direction != Up) { direction = Down; }
- else if (input.a_pressed && direction != Right) { direction = Left; }
- else if (input.d_pressed && direction != Left) { direction = Right; }
- switch (direction) {
- case Up: go_up(); break;
- case Down: go_down(); break;
- case Left: go_left(); break;
- case Right: go_right(); break;
- }
- }
- unsigned score() const {
- return skore;
- }
- private:
- void go_up() {
- auto point = snake.front();
- --point.y;
- move_to(point);
- }
- void go_down() {
- auto point = snake.front();
- ++point.y;
- move_to(point);
- }
- void go_left() {
- auto point = snake.front();
- --point.x;
- move_to(point);
- }
- void go_right() {
- auto point = snake.front();
- ++point.x;
- move_to(point);
- }
- void move_to(Point<std::size_t> point) {
- auto cell = field.cells[point.x][point.y];
- if (cell == Cell::Snake) {
- throw std::runtime_error{"Game over, sucker!"};
- } else if (cell == Cell::Food) {
- ++skore;
- }
- snake.insert(std::begin(snake), point);
- snake.pop_back();
- }
- void spawn_food(unsigned attempts = 0) {
- if (attempts == 5) return;
- std::uniform_int_distribution<std::size_t> xr(0, W);
- std::uniform_int_distribution<std::size_t> yr(0, H);
- auto x = xr(prng);
- auto y = yr(prng);
- if (field.cells[x][y] != Cell::Empty) spawn_food(attempts + 1);
- field.cells[x][y] = Cell::Food;
- }
- Field<W, H> field;
- std::vector<Point<std::size_t>> snake;
- enum {Up, Down, Left, Right} direction;
- unsigned skore;
- std::mt19937 prng;
- };
- int main() {
- Game<10, 10> game;
- Input input;
- for (;;) {
- game.step(input);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment