Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.14 KB | None | 0 0
  1. #include <vector>
  2.  
  3. using namespace std;
  4.  
  5. class Direction {
  6. public:
  7.     int value;
  8.     Direction() = default;
  9.     Direction(int _value) {
  10.         value = _value % 4;
  11.         if (value < 0) value += 4;
  12.     }
  13.    
  14.     Direction next() {return value + 1;}
  15.     Direction prev() {return value - 1;}
  16.    
  17.     bool operator==(const Direction& d) const {return d.value == value;}
  18.     bool operator!=(const Direction& d) const {return !(d == *this);}
  19. };
  20.  
  21. class Cell {
  22.     int x, y;
  23. public:
  24.     Cell() = default;
  25.     Cell(int _x, int _y) :
  26.         x(_x), y(_y) {}
  27.        
  28.     Cell move(Direction dir) {
  29.         if (dir.value == 0) x++;
  30.         if (dir.value == 1) y++;
  31.         if (dir.value == 2) x--;
  32.         if (dir.value == 3) y--;
  33.     }
  34.    
  35.     bool operator==(Cell a) {return a.x == x && a.y == y;}
  36.    
  37.     bool in(Cell& a, Cell& b) const {
  38.         if (a == *this || b == *this) return true;
  39.         if (a.x == b.x)
  40.             if ((a.y - y) != (b.y - y)) return true;
  41.         if (a.y == b.y)
  42.             if ((a.x - x) != (b.x - x)) return true;
  43.        
  44.         return false;
  45.     }
  46.    
  47.     Direction directionTo(Cell c) {
  48.         if (!isLine(*this, c)) return 0;
  49.         if (x == c.x)
  50.             if (c.x > x) return 0;
  51.             else return 2;
  52.         else
  53.             if (c.y > y) return 1;
  54.             else return 3;
  55.     }
  56.    
  57.     static bool isLine(Cell a, Cell b) {
  58.         return a.x == b.x || a.y == b.y;
  59.     }
  60.    
  61.     static bool orderedIntersect(Cell a, Cell b, Cell c, Cell d) {
  62.         return min(a.x, b.x) <= min(c.x, d.x) &&
  63.                max(a.x, b.x) >= max(c.x, d.x) &&
  64.                min(a.y, b.y) >= min(c.y, d.y) &&
  65.                max(a.y, b.y) <= max(c.y, d.y);
  66.     }
  67.    
  68.     static bool intersect(Cell a, Cell b, Cell c, Cell d) {
  69.         if (!isLine(a, b) || !isLine(c, d)) return false;
  70.         if (orderedIntersect(a, b, c, d)) return true;
  71.         if (orderedIntersect(c, d, a, b)) return true;
  72.         return false;
  73.     }
  74. };
  75.  
  76. class Snake {
  77.     vector<Cell> pos;
  78.     Direction last;
  79.     Direction head;
  80.     bool alive;
  81.    
  82.     Snake():
  83.         last(1), head(1) {
  84.         pos.emplace_back(0, 0);
  85.         alive = true;
  86.     }
  87.    
  88.     Snake(vector<Cell> _pos) {
  89.         alive = true;
  90.        
  91.         if (_pos.size() == 0) {
  92.             death();
  93.             return;
  94.         }
  95.         for (int i = 0; i < _pos.size() - 1; i++)
  96.             for (int j = 0; j < i - 1; j++)
  97.                 if (Cell::intersect(pos[i], pos[i + 1], pos[j], pos[j + 1])) {
  98.                     death();
  99.                     return;
  100.                 }
  101.  
  102.         pos.push_back(_pos.front());
  103.         last = Direction(1);
  104.        
  105.         for (auto& c : _pos) {
  106.             if (!Cell::isLine(c, pos.back())) {
  107.                 death();
  108.                 return;
  109.             }
  110.             if (pos.size() >= 2 && pos.back().in(c, pos[pos.size() - 2])) pos.pop_back();
  111.             pos.push_back(c);
  112.         }
  113.        
  114.         last = pos[pos.size() - 2].directionTo(pos.back());
  115.         head = last;
  116.     }
  117.    
  118.     void move() {
  119.         if (!isAlive()) return;
  120.         if (last != head) {
  121.             pos.push_back(pos.back());
  122.             last = head;
  123.         }
  124.         Cell b = pos.back();
  125.         b.move(head);
  126.        
  127.         if (into(b)) death();
  128.         else pos.push_back(b);
  129.     }
  130.    
  131.     bool into(const Cell& c) {
  132.         if (!isAlive()) return false;
  133.        
  134.         for (int i = 0; i < pos.size() - 1; ++i)
  135.             if (c.in(pos[i], pos[i + 1])) return true;
  136.        
  137.         return false;
  138.     }
  139.    
  140.     void death() {
  141.         if (!isAlive()) return;
  142.         pos.clear();
  143.         alive = false;
  144.     }
  145.    
  146.     void turn_left() {head = last.next();}
  147.     void turn_right() {head = last.prev();}
  148.     void turn_forward() {head = last;}
  149.    
  150.     bool isAlive() {
  151.         return alive;
  152.     }
  153. };
  154.  
  155. int main() {
  156.    
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement