Guest User

Untitled

a guest
Dec 10th, 2012
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.79 KB | None | 0 0
  1. #include <random>
  2. #include <array>
  3. #include <vector>
  4.  
  5. struct Input {
  6.     bool w_pressed{};
  7.     bool s_pressed{};
  8.     bool a_pressed{};
  9.     bool d_pressed{};
  10. };
  11.  
  12. template<class T>
  13. struct Point {
  14.     Point() = default;
  15.     Point(T x_, T y_) : x(x_), y(y_) {}
  16.  
  17.     T x{};
  18.     T y{};
  19. };
  20.  
  21. enum class Cell {
  22.     Empty,
  23.     Snake,
  24.     Food
  25. };
  26.  
  27. template<std::size_t W, std::size_t H>
  28. class Field {
  29. public:
  30.     std::array<std::array<Cell, H>, W> cells;
  31. };
  32.  
  33. template<std::size_t W, std::size_t H>
  34. class Game {
  35. public:
  36.     Game() : direction{Left}, skore{0} {}
  37.  
  38.     void step(Input const& input) {
  39.         std::uniform_int_distribution<> spawn_food_probability(0, 10);
  40.         if (spawn_food_probability(prng) == 0) {
  41.             spawn_food();
  42.         }
  43.  
  44.         if (input.w_pressed && direction != Down)  { direction = Up; }
  45.         else if (input.s_pressed && direction != Up)    { direction = Down; }
  46.         else if (input.a_pressed && direction != Right) { direction = Left; }
  47.         else if (input.d_pressed && direction != Left)  { direction = Right; }
  48.  
  49.         switch (direction) {
  50.             case Up: go_up(); break;
  51.             case Down: go_down(); break;
  52.             case Left: go_left(); break;
  53.             case Right: go_right(); break;
  54.         }
  55.     }
  56.  
  57.     unsigned score() const {
  58.         return skore;
  59.     }
  60.  
  61. private:
  62.     void go_up() {
  63.         auto point = snake.front();
  64.         --point.y;
  65.         move_to(point);
  66.     }
  67.  
  68.     void go_down() {
  69.         auto point = snake.front();
  70.         ++point.y;
  71.         move_to(point);
  72.     }
  73.  
  74.     void go_left() {
  75.         auto point = snake.front();
  76.         --point.x;
  77.         move_to(point);
  78.     }
  79.  
  80.     void go_right() {
  81.         auto point = snake.front();
  82.         ++point.x;
  83.         move_to(point);
  84.     }
  85.  
  86.     void move_to(Point<std::size_t> point) {
  87.         auto cell = field.cells[point.x][point.y];
  88.         if (cell == Cell::Snake) {
  89.             throw std::runtime_error{"Game over, sucker!"};
  90.         } else if (cell == Cell::Food) {
  91.             ++skore;
  92.         }
  93.  
  94.         snake.insert(std::begin(snake), point);
  95.         snake.pop_back();
  96.     }
  97.  
  98.     void spawn_food(unsigned attempts = 0) {
  99.         if (attempts == 5) return;
  100.  
  101.         std::uniform_int_distribution<std::size_t> xr(0, W);
  102.         std::uniform_int_distribution<std::size_t> yr(0, H);
  103.         auto x = xr(prng);
  104.         auto y = yr(prng);
  105.  
  106.         if (field.cells[x][y] != Cell::Empty) spawn_food(attempts + 1);
  107.         field.cells[x][y] = Cell::Food;
  108.     }
  109.  
  110.     Field<W, H> field;
  111.     std::vector<Point<std::size_t>> snake;
  112.     enum {Up, Down, Left, Right} direction;
  113.     unsigned skore;
  114.     std::mt19937 prng;
  115. };
  116.  
  117. int main() {
  118.     Game<10, 10> game;
  119.     Input input;
  120.     for (;;) {
  121.         game.step(input);
  122.     }
  123. }
Advertisement
Add Comment
Please, Sign In to add comment