You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.9 KiB

  1. #include "Snake.h"
  2. #include <iostream>
  3. Snake::Snake(uint32_t headY, uint32_t headX)
  4. :direction_{LEFT}
  5. {
  6. snake_.push_back(Point{headY, headX, '>'});
  7. for (uint32_t i = 1; i <= SNAKE_DEFAULT_SIZE - 1; i++) {
  8. snake_.push_back(Point{headY, headX + i, SNAKE_BODY_CHAR});
  9. }
  10. }
  11. bool Snake::isBitten() const {
  12. const Point& head = snake_.front();
  13. for (const Point& part : snake_) {
  14. if (part.getX() == head.getX() && part.getY() == head.getY()) {
  15. return true;
  16. }
  17. }
  18. return false;
  19. }
  20. bool Snake::hasBitSnack(uint32_t snackY, uint32_t snackX) const {
  21. return snake_.front().getY() == snackY && snake_.front().getX() == snackX;
  22. }
  23. bool Snake::hasCrashedWall() const {
  24. const Point& head = snake_.front();
  25. return (head.getY() < GAME_TOP_WALL_Y) ||
  26. (head.getY() > GAME_BOTTOM_WALL_Y) ||
  27. (head.getX() < GAME_LEFT_WALL_X) ||
  28. (head.getX() > GAME_RIGHT_WALL_X);
  29. }
  30. uint32_t Snake::getSize() const {
  31. return snake_.size();
  32. }
  33. void Snake::incSize(){
  34. const auto tail = std::prev(snake_.end());
  35. const uint32_t tailX = tail->getX();
  36. const uint32_t tailY = tail->getY();
  37. const auto prev = std::prev(tail);
  38. const uint32_t prevX = prev->getX();
  39. const uint32_t prevY = prev->getY();
  40. if (prevY == tailY){
  41. // if the two last parts are on the same 'height' (horizontal tail direction)
  42. if (prevX < tailX) {
  43. // if the tail continues to the left:
  44. // add one part to the right of the tail
  45. snake_.push_back(Point{tailY, tailX + 1, SNAKE_BODY_CHAR});
  46. }
  47. else {
  48. // if the tail continues to the right:
  49. // add one part to the left of the tail
  50. snake_.push_back(Point{tailY, tailX - 1, SNAKE_BODY_CHAR});
  51. }
  52. }
  53. else {
  54. // if the two last parts are on the same 'width' (vertical tail direction)
  55. if (prevY < tailY) {
  56. // if the tail continues to the upper side:
  57. // add one part facing down
  58. snake_.push_back(Point{tailY + 1, tailX, SNAKE_BODY_CHAR});
  59. }
  60. else {
  61. // if the tail continues to the lower side:
  62. // add one part facing up
  63. snake_.push_back(Point{tailY - 1, tailX, SNAKE_BODY_CHAR});
  64. }
  65. }
  66. }
  67. void Snake::updateHead(){
  68. switch (direction_) {
  69. case UP:
  70. snake_.front().moveUp();
  71. break;
  72. case DOWN:
  73. snake_.front().moveDown();
  74. break;
  75. case LEFT:
  76. snake_.front().moveLeft();
  77. break;
  78. case RIGHT:
  79. snake_.front().moveRight();
  80. break;
  81. }
  82. }
  83. void Snake::printSnake() const {
  84. //We print each element of the snake-list
  85. for (const Point& part : snake_){
  86. part.print();
  87. }
  88. Graphics::get().refreshScreen();
  89. }
  90. void Snake::move(){
  91. // updates the tail by clearing it since
  92. // the snake moved forward (overwrites with ' ')
  93. snake_.back().clear();
  94. // iterate through the snake step by step
  95. // using iterators so that we can get prev
  96. // and iterate from back to front as we want to
  97. // update each element with the value of the next
  98. // and would otherwise overwrite the next before
  99. // and not updating first as head is handled separately
  100. for (auto it = std::prev(snake_.end()); it != snake_.begin(); it--) {
  101. const auto prev = std::prev(it);
  102. it->setPoint(prev->getY(), prev->getX());
  103. }
  104. // update the head depending on movement
  105. updateHead();
  106. // print the updated snake
  107. printSnake();
  108. }
  109. void Snake::moveUp(){
  110. snake_.front().setImg('v');
  111. direction_ = UP;
  112. move();
  113. }
  114. void Snake::moveDown(){
  115. snake_.front().setImg('^');
  116. direction_ = DOWN;
  117. move();
  118. }
  119. void Snake::moveLeft(){
  120. snake_.front().setImg('>');
  121. direction_ = LEFT;
  122. move();
  123. }
  124. void Snake::moveRight(){
  125. snake_.front().setImg('<');
  126. direction_ = RIGHT;
  127. move();
  128. }