title: How to make the snake bite?
body: <p>I'm trying to make a snake game in C++ with SFML.
  Here is my code below. The problem is that I don't know how I could possibly make the snake bite himself : each snake block takes the position of the last one, resulting in a perfectly straight snake. So it's more of an algorithm problem.
  Thanks for your advices :) 
  BTW Didn't put hashtages and &lt; in the include because the editor takes them away :/
  BTW2: Looked for similar responses but none of them were with my approach or were in another language.
  Here you go:</p>
  
  <pre><code>#include &lt;SFML/Window.hpp&gt;
  #include &lt;SFML/Graphics.hpp&gt;
  #include &lt;SFML/System.hpp&gt;
  #include &lt;SFML/Audio.hpp&gt;
  #include &lt;deque&gt;
  
  void selfIncrement();
  
  sf::Event event;
  sf::Clock clockSnake;
  sf::Time elapse;
  
  enum Direction { Up, Down, Left, Right};
  
  int dir = Up;
  
  int n = 1;
  
  class SnakeBlock
  {
  public:
  
  SnakeBlock * next;
  sf::Texture texture;
  sf::Sprite snakeblock;
  int lastX, lastY;
  };
  
  std::deque&lt;SnakeBlock&gt; Snake;
  
  int main()
  {
  elapse = clockSnake.getElapsedTime();
  
  sf::Music epicMusic;
  epicMusic.openFromFile("epicmusic.wav");
  epicMusic.play();
  
  SnakeBlock snakeHead;
  snakeHead.texture.loadFromFile("spritesheetsnake.png", sf::IntRect(0,0,20,22));
  snakeHead.snakeblock.setTexture(snakeHead.texture);
  SnakeBlock snakeBody1;
  snakeBody1.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  SnakeBlock snakeBody2;
  snakeBody2.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  
  Snake.push_front(snakeHead);
  Snake.push_front(snakeBody1);
  Snake.push_front(snakeBody2);
  Snake[2].snakeblock.setPosition(500,350);
  Snake[1].snakeblock.setPosition(475, 338);
  Snake[0].snakeblock.setPosition(450, 316);
  
  sf::RenderWindow window(sf::VideoMode(1028,768), "SFML Snake");
  window.setFramerateLimit(60);
  while(window.isOpen())
  {
      while(window.pollEvent(event))
      {
          switch(event.type)
          {
              case sf::Event::Closed:
              epicMusic.stop();
              window.close();
              break;
  
              default:
              break;
          }
  
      }
  
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
      {
              dir = Left;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
      {
              dir = Right;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
      {
              dir = Down;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
      {
              dir = Up;
      }
      if(dir == Up)
      {
  
          Snake[0].snakeblock.move(0,-2);
          Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x, Snake[n-1].snakeblock.getPosition().y+20);
      }
      if(dir == Down)
      {
          Snake[0].snakeblock.move(0,2);
          Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x, Snake[n-1].snakeblock.getPosition().y-20);
      }
      if(dir == Left)
      {
          Snake[0].snakeblock.move(-2,0);
          Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x+20, Snake[n-1].snakeblock.getPosition().y);
      }
      if(dir == Right)
      {
          Snake[0].snakeblock.move(2,0);
          Snake[n].snakeblock.setPosition(Snake[n-1].snakeblock.getPosition().x-20, Snake[n-1].snakeblock.getPosition().y);
      }
      window.clear(sf::Color::Red);
      n++;
      if( n &gt; 2)
      {
          n = 1;
      }
      //selfIncrement();
      for(unsigned int m = 0; m &lt; Snake.size(); m++)
      {
          window.draw(Snake[m].snakeblock);
      }
  
      window.display();
  }
  return 0;
  
  }
  
  /*void selfIncrement()
  {
  elapse = clockSnake.getElapsedTime();
  if(elapse.asSeconds() &gt; 0.10)
  {
      n++;
      clockSnake.restart();
  }
  if(n &gt; Snake.size())
  {
      n = 1;
  }
  }
  */
  </code></pre>
  
  <p>NEW CODE using new principle::</p>
  
  <pre><code>#include &lt;SFML/Window.hpp&gt;
  #include &lt;SFML/Graphics.hpp&gt;
  #include &lt;SFML/System.hpp&gt;
  #include &lt;SFML/Audio.hpp&gt;
  #include &lt;deque&gt;
  
  void advanceStep();
  
  sf::Event event;
  sf::Clock clockSnake;
  sf::Time elapse;
  
  enum Direction { Up, Down, Left, Right};
  
  sf::Vector2i direction;
  int dir = Up;
  
  int n = 1;
  
  class SnakeBlock
  {
  public:
  
  sf::Texture texture;
  sf::Sprite snakeblock;
  int dir = 0;
  int lastX, lastY;
  };
  
  SnakeBlock element;
  std::deque&lt;SnakeBlock&gt; Snake;
  
  int main()
  {
  elapse = clockSnake.getElapsedTime();
  
  sf::Music epicMusic;
  epicMusic.openFromFile("epicmusic.wav");
  epicMusic.play();
  
  SnakeBlock snakeHead;
  snakeHead.texture.loadFromFile("spritesheetsnake.png", sf::IntRect(0,0,20,22));
  snakeHead.snakeblock.setTexture(snakeHead.texture);
  SnakeBlock snakeBody1;
  snakeBody1.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  SnakeBlock snakeBody2;
  snakeBody2.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  
  Snake.push_front(snakeHead);
  Snake.push_front(snakeBody1);
  Snake.push_front(snakeBody2);
  Snake[2].snakeblock.setPosition(500,350);
  Snake[1].snakeblock.setPosition(475, 338);
  Snake[0].snakeblock.setPosition(450, 316);
  
  sf::RenderWindow window(sf::VideoMode(1028,768), "SFML Snake");
  window.setFramerateLimit(10);
  while(window.isOpen())
  {
      while(window.pollEvent(event))
      {
          switch(event.type)
          {
              case sf::Event::Closed:
              epicMusic.stop();
              window.close();
              break;
  
              default:
              break;
          }
  
      }
  
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
      {
              dir = Left;
              direction.x = -1;
              direction.y = 0;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
      {
              dir = Right;
              direction.x = 1;
              direction.y = 0;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
      {
              dir = Down;
              direction.x = 0;
              direction.y = -1;
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
      {
              dir = Up;
              direction.x = 0;
              direction.y = 1;
      }
      if(dir == Up)
      {
  
          Snake[0].snakeblock.move(0,-2);
          Snake[1].snakeblock.setPosition(Snake[0].snakeblock.getPosition().x, Snake[0].snakeblock.getPosition().y+20);
          Snake[2].snakeblock.setPosition(Snake[1].snakeblock.getPosition().x, Snake[1].snakeblock.getPosition().y+20);
      }
      if(dir == Down)
      {
          Snake[0].snakeblock.move(0,2);
          Snake[1].snakeblock.setPosition(Snake[0].snakeblock.getPosition().x, Snake[0].snakeblock.getPosition().y-20);
          Snake[2].snakeblock.setPosition(Snake[1].snakeblock.getPosition().x, Snake[1].snakeblock.getPosition().y-20);
      }
      if(dir == Left)
      {
          Snake[0].snakeblock.move(-2,0);
          Snake[1].snakeblock.setPosition(Snake[0].snakeblock.getPosition().x+20, Snake[0].snakeblock.getPosition().y);
          Snake[2].snakeblock.setPosition(Snake[1].snakeblock.getPosition().x+20, Snake[1].snakeblock.getPosition().y);
      }
      if(dir == Right)
      {
          Snake[0].snakeblock.move(2,0);
          Snake[1].snakeblock.setPosition(Snake[0].snakeblock.getPosition().x-20, Snake[0].snakeblock.getPosition().y);
          Snake[2].snakeblock.setPosition(Snake[1].snakeblock.getPosition().x-20, Snake[1].snakeblock.getPosition().y);
      }
      window.clear(sf::Color::Red);
      advanceStep();
      for(unsigned int m = 0; m &lt; Snake.size(); m++)
      {
          window.draw(Snake[m].snakeblock);
      }
      window.display();
  }
  return 0;
  
  }
  
  void advanceStep()
  {
  sf::Vector2f headpos(Snake[0].snakeblock.getPosition());
  
  headpos.x += 22 * direction.x;
  headpos.y += 22 * direction.y;
  
  Snake[0].snakeblock.setPosition(headpos);
  
  Snake.pop_back();
  Snake.push_front(Snake[0]);
  }
  </code></pre>
  
  <p>NEW CODE TAKING IN ACCOUNT EVERYTHING YOU ALL SAID, but now the snake just disappear, probably because of the pop_back..</p>
  
  <pre><code>#include &lt;SFML/Window.hpp&gt;
  #include &lt;SFML/Graphics.hpp&gt;
  #include &lt;SFML/System.hpp&gt;
  #include &lt;SFML/Audio.hpp&gt;
  #include &lt;deque&gt;
  
  void advanceStep();
  
  sf::Event event;
  sf::Clock clockSnake;
  sf::Time elapse;
  
  enum Direction { Up, Down, Left, Right};
  
  sf::Vector2i direction(0, 0);
  int dir = Up;
  
  
  class SnakeBlock
  {
  public:
  
  sf::Texture texture;
  sf::Sprite snakeblock;
  int dir;
  };
  
  std::deque&lt;SnakeBlock&gt; Snake;
  
  int main()
  {
  elapse = clockSnake.getElapsedTime();
  
  sf::Music epicMusic;
  epicMusic.openFromFile("epicmusic.wav");
  epicMusic.play();
  
  SnakeBlock snakeHead;
  snakeHead.texture.loadFromFile("spritesheetsnake.png", sf::IntRect(0,0,20,22));
  snakeHead.snakeblock.setTexture(snakeHead.texture);
  SnakeBlock snakeBody1;
  snakeBody1.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  SnakeBlock snakeBody2;
  snakeBody2.snakeblock.setTexture(*(snakeHead.snakeblock.getTexture()));
  
  Snake.push_back(snakeHead);
  Snake.push_back(snakeBody1);
  Snake.push_back(snakeBody2);
  
  Snake[2].snakeblock.setPosition(500,350);
  Snake[1].snakeblock.setPosition(475, 338);
  Snake[0].snakeblock.setPosition(450, 316);
  
  sf::RenderWindow window(sf::VideoMode(1028,768), "SFML Snake");
  window.setFramerateLimit(1);
  while(window.isOpen())
  {
      while(window.pollEvent(event))
      {
          switch(event.type)
          {
              case sf::Event::Closed:
              epicMusic.stop();
              window.close();
              break;
  
              default:
              break;
          }
  
      }
  
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
      {
              direction.x = -1;
              for(int i = 1; i &lt; Snake.size(); i++)
              {
                  Snake[i].snakeblock.setPosition(Snake[i+1].snakeblock.getPosition().x-20, Snake[i+1].snakeblock.getPosition().y);
              }
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
      {
              direction.x = 1;
              for(int j = 1; j &lt; Snake.size(); j++)
              {
                  Snake[j].snakeblock.setPosition(Snake[j+1].snakeblock.getPosition().x+20, Snake[j+1].snakeblock.getPosition().y);
              }
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
      {
              direction.y = -1;
              for(int l = 1; l &lt; Snake.size(); l++)
              {
                  Snake[l].snakeblock.setPosition(Snake[l+1].snakeblock.getPosition().x, Snake[l+1].snakeblock.getPosition().y-22);
              }
      }
      if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
      {
              direction.y = 1;
              for(int o = 1; o &lt; Snake.size(); o++)
              {
                  Snake[o].snakeblock.setPosition(Snake[o+1].snakeblock.getPosition().x, Snake[o+1].snakeblock.getPosition().y+22);
              }
      }
      window.clear(sf::Color::Red);
      advanceStep();
      for(unsigned int m = 1; m &lt; Snake.size(); m++)
      {
          window.draw(Snake[m].snakeblock);
      }
      window.display();
  }
  return 0;
  
  }
  
  void advanceStep()
  {
  sf::Vector2f headpos;
  headpos.x = Snake[0].snakeblock.getPosition().x;
  headpos.y = Snake[0].snakeblock.getPosition().y;
  
  headpos.x += 22 * direction.x;
  headpos.y += 22 * direction.y;
  
  SnakeBlock element;
  element.snakeblock.setPosition(headpos);
  
  Snake.pop_back();
  Snake.push_front(element);
  }
  </code></pre>