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
4.2 KiB

  1. #include "Snake.h"
  2. #include <iostream>
  3. using namespace std;
  4. Snake::Snake(int headY, int headX)
  5. :direction{LEFT}
  6. {
  7. snake.push_back(Point{headY, headX, '>'}); //add the head of the snake
  8. for(int i=1; i<=3; i++)
  9. snake.push_back(Point{headY, headX+i, BODY});
  10. }
  11. Snake::~Snake(){}
  12. bool Snake::isBitten(void){
  13. Point head = *snake.begin();
  14. list<Point>::iterator body_part = snake.begin();
  15. body_part++;
  16. while(body_part != snake.end()){
  17. if(body_part->getX() == head.getX() && body_part->getY() == head.getY())
  18. return true;
  19. body_part++;
  20. }
  21. return false;
  22. }
  23. bool Snake::hasBitSnack(int snackY, int snackX){
  24. return snake.begin()->getY() == snackY
  25. && snake.begin()->getX() == snackX;
  26. }
  27. bool Snake::hasCrashedWall(void){
  28. Point &head = *snake.begin();
  29. return (head.getY() < GAME_TOP_WALL_Y) ||
  30. (head.getY() > GAME_BOTTOM_WALL_Y) ||
  31. (head.getX() < GAME_LEFT_WALL_X) ||
  32. (head.getX() > GAME_RIGHT_WALL_X);
  33. }
  34. int Snake::getSize(void){
  35. return snake.size();
  36. }
  37. void Snake::incSize(void){
  38. auto tail = snake.end();
  39. //since list::end() returns one element past the actual last one we will decrease by one the tail iterator
  40. tail--; //now we actually pointing to the tail
  41. int tailX = tail->getX();
  42. int tailY = tail->getY();
  43. //now we must determine the direction which is easy by just fiding the coordinates of the previous to tail element
  44. auto prev = --tail;
  45. int prevX = prev->getX();
  46. int prevY = prev->getY();
  47. if(prevY == tailY){
  48. //if the 2 part are on the same 'height'
  49. if (prevX < tailX) //if the tail continues to the left:
  50. snake.push_back(Point{tailY, tailX + 1, BODY}); // add one part to the right of the tail
  51. else if(prevX > tailX) //if the tail continues to the right:
  52. snake.push_back(Point{tailY, tailX - 1, BODY}); // add one part to the left of the tail
  53. }else{
  54. if (prevY < tailY) //if the tail continues to the upper side:
  55. snake.push_back(Point{tailY + 1, tailX, BODY}); // add one part facing down
  56. else if (prevY > tailY) //if the tail continues to the lower side:
  57. snake.push_back(Point{tailY - 1, tailX, BODY}); // add one part facing up
  58. }
  59. }
  60. void Snake::updateHead(void){
  61. auto head = snake.begin();
  62. switch (this->direction)
  63. {
  64. case UP:
  65. head->moveUp();
  66. break;
  67. case DOWN:
  68. head->moveDown();
  69. break;
  70. case LEFT:
  71. head->moveLeft();
  72. break;
  73. case RIGHT:
  74. head->moveRight();
  75. break;
  76. }
  77. }
  78. void Snake::printSnake(void){
  79. //We print each element of the snake-list
  80. for(auto bodyPart : snake){
  81. bodyPart.printImg();
  82. }
  83. refreshScreen(); //finally call the previously implemented function at Graphics.cpp
  84. //to update the screen so the changes become noticed
  85. }
  86. void Snake::move(void){
  87. //now delete the tail print since teh snake moves forward
  88. auto tail = snake.end();
  89. tail--;
  90. printChar(tail->getY(), tail->getX(), ' ');
  91. //and now we have to update all the other nodes of the body
  92. auto bodyP1 = tail;
  93. auto bodyP2 = --tail;
  94. while(bodyP2 != snake.begin()){
  95. *bodyP1 = *bodyP2;
  96. bodyP1--;
  97. bodyP2--;
  98. }
  99. //update the previous to head node
  100. auto headPrev = snake.begin();
  101. headPrev++;
  102. *headPrev = *snake.begin();
  103. headPrev->setImg(BODY);
  104. //based on direction, update the head
  105. this->updateHead();
  106. this->printSnake(); // print the snake and update the screen
  107. }
  108. //Move Functions:
  109. //For the move functions we must change
  110. void Snake::moveUp(void){
  111. snake.begin()->setImg('v');
  112. this->direction = UP;
  113. this->move();
  114. }
  115. void Snake::moveDown(void){
  116. snake.begin()->setImg('^');
  117. this->direction = DOWN;
  118. this->move();
  119. }
  120. void Snake::moveLeft(void){
  121. snake.begin()->setImg('>');
  122. this->direction = LEFT;
  123. this->move();
  124. }
  125. void Snake::moveRight(void){
  126. snake.begin()->setImg('<');
  127. this->direction = RIGHT;
  128. this->move();
  129. }