Simple Console Snake game C++Sprite animation handlerSnake console gameSnake-like console gameSnake game for Windows consoleSimple console snake game in PythonSimple console Snake game following GRASPSimple Snake GameConsole Based Snake GameSnake game for Windows text consoleConsole snake game in C#

How to make healing in an exploration game interesting

What is Thermal Runaway Protection?

What is a good source for large tables on the properties of water?

Co-worker team leader wants to inject his friend's awful software into our development. What should I say to our common boss?

Why do Australian milk farmers need to protest supermarkets' milk price?

Making a sword in the stone, in a medieval world without magic

An Accountant Seeks the Help of a Mathematician

Why are the outputs of printf and std::cout different

How to answer questions about my characters?

Brexit - No Deal Rejection

Is having access to past exams cheating and, if yes, could it be proven just by a good grade?

Sword in the Stone story where the sword was held in place by electromagnets

Employee lack of ownership

Does this AnyDice function accurately calculate the number of ogres you make unconcious with three 4th-level castings of Sleep?

Ban on all campaign finance?

Identifying the interval from A♭ to D♯

Instead of Universal Basic Income, why not Universal Basic NEEDS?

Check this translation of Amores 1.3.26

Do I need life insurance if I can cover my own funeral costs?

Provisioning profile doesn't include the application-identifier and keychain-access-groups entitlements

How to deal with a cynical class?

Informing my boss about remarks from a nasty colleague

SQL Server Primary Login Restrictions

Bastion server: use TCP forwarding VS placing private key on server



Simple Console Snake game C++


Sprite animation handlerSnake console gameSnake-like console gameSnake game for Windows consoleSimple console snake game in PythonSimple console Snake game following GRASPSimple Snake GameConsole Based Snake GameSnake game for Windows text consoleConsole snake game in C#













3












$begingroup$


I recently started learning C++ and have made a very simple Console-based Snake Game, I would like to have some feedback on improvements.



You might notice the obvious delay in clearing and printing of the screen, as I did not use system("cls") since it was stated as 'evil' and 'bad'.
I printed a bunch of newlines instead as suggested in a forum that I had read.

(Didn't use NCurses since it was an overkill for my simple snake game)



#include <iostream>
#include <string>
#include <limits>
#include <conio.h>

#include <thread>
#include <chrono>

enum Direction2D
UNDEFINED = 0,
LEFT,
RIGHT,
UP,
DOWN
;

bool IsOppositeOf(const Direction2D& first, const Direction2D& second)
// Feedback for a more elegant approach, thanks.
bool isOpposite = false;
if (first == LEFT && second == RIGHT)
isOpposite = true;

else if (first == RIGHT && second == LEFT)
isOpposite = true;

else if (first == UP && second == DOWN)
isOpposite = true;

else if (first == DOWN && second == UP)
isOpposite = true;


return isOpposite;


struct Vector2D

int x;
int y;
;

// Since we are printing downwards, 'up' would technically be down.
Vector2D const Up = 0, -1 ;
Vector2D const Down = 0, 1 ;

Vector2D const Left = -1, 0 ;
Vector2D const Right = 1, 0 ;

Vector2D const Zero = 0, 0 ;

#pragma region Vector2D_Operators

bool operator ==(const Vector2D& first, const Vector2D& second)
return (first.x == second.x) && (first.y == second.y);


Vector2D operator +(const Vector2D& first, const Vector2D& second)
return (first.x + second.x), (first.y + second.y) ;


Vector2D operator -(const Vector2D& first, const Vector2D& second)
return (first.x - second.x), (first.y - second.y) ;


#pragma endregion

bool gameOver;

int playerScore;

int width;
int height;

Vector2D snakeHeadPosition;
Vector2D currentFruitPosition;

Direction2D currentSnakeMovingDirection;

// I'm assuming the length of the tail doesn't go beyond 256.
// Accepting feedback on how I could do this more elegantly.
Vector2D tailPositions[256];

int tailLength;

#pragma region Util

void ClearCinInput()
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');


template <typename T>
void RequestForValidInputValue(T &receivingArg, std::string errorMsg)
// Ask for input while the input is not of the correct type.
while (!(std::cin >> receivingArg))
std::cout << errorMsg << std::endl;
ClearCinInput();



#pragma region Request_For_YesNo

void PrintRespectiveYesNoTextByFirstRun(bool firstRun)
if (firstRun)
std::cout << "(Y/N)" << std::endl;

else
std::cout << "Please input either 'Y' or 'N'." << std::endl;



bool CheckIfValidYesNoInput(std::string input) input == "N");


bool AskUserForYesNo()
std::string userInput = "";

bool loopFirstRun = true;

// Ask for input again while the input was not a confirmation.
do
PrintRespectiveYesNoTextByFirstRun(loopFirstRun);

RequestForValidInputValue(userInput, "ERROR: Please input 'Y' or 'N' ");
loopFirstRun = false;
while (!CheckIfValidYesNoInput(userInput));

return userInput == "Y";


#pragma endregion

void ClearScreen()
// SLOW
std::cout << std::string(100, 'n');


void PlaceFruitRandomlyInPlayingField()
currentFruitPosition = rand() % width, rand() % height ;


#pragma endregion

void HandleFruitEating()
++tailLength;
++playerScore;
PlaceFruitRandomlyInPlayingField();


bool SnakeEatingFruit()
return snakeHeadPosition == currentFruitPosition;


bool SnakeHeadTouchedTail()
bool touchedTail = false;

for (int i = 0; i < tailLength; ++i)
if (tailPositions[i] == snakeHeadPosition)
touchedTail = true;
break;


return touchedTail;


bool SnakeHeadTouchedBorder() x < 0

void UpdateSnakePositionByCurrentMoveDirection()
switch (currentSnakeMovingDirection)
case LEFT:
snakeHeadPosition = snakeHeadPosition + Left;
break;
case RIGHT:
snakeHeadPosition = snakeHeadPosition + Right;
break;
case UP:
snakeHeadPosition = snakeHeadPosition + Up;
break;
case DOWN:
snakeHeadPosition = snakeHeadPosition + Down;
break;
default:
break;



void UpdateSnakeTailPositions()
Vector2D prevPosition = tailPositions[0];
Vector2D temp;
tailPositions[0] = snakeHeadPosition;

for (int i = 1; i < tailLength; ++i)
temp = tailPositions[i];
tailPositions[i] = prevPosition;
prevPosition = temp;



void UpdateGameLogic()

#pragma region Handling_Inputs

void MoveSnakeIfValid(Direction2D newDirection)
if (tailLength > 0)
// To prevent suicidal acts by moving backwards into a tail.
if (!IsOppositeOf(newDirection, currentSnakeMovingDirection))
currentSnakeMovingDirection = newDirection;


else
currentSnakeMovingDirection = newDirection;



void MoveSnakeByUserInput(char inputValue)
Direction2D newMoveDirection;
switch (inputValue)
case 'a':
newMoveDirection = LEFT;
break;
case 'd':
newMoveDirection = RIGHT;
break;
case 'w':
newMoveDirection = UP;
break;
case 's':
newMoveDirection = DOWN;
break;
default:
newMoveDirection = UNDEFINED;
break;


if (newMoveDirection != UNDEFINED)
MoveSnakeIfValid(newMoveDirection);



bool GetKeyPressInputIfExists(char &keyPressValue)
if (_kbhit())
keyPressValue = _getch();
return true;

else
return false;



#pragma endregion

void HandleInput()
char keyPressValue;
if (GetKeyPressInputIfExists(keyPressValue))
MoveSnakeByUserInput(keyPressValue);



#pragma region Drawing_PlayField

bool PrintTailOnPositionIfNeeded(Vector2D position)
bool tailPrinted = false;
for (int i = 0; i < tailLength; ++i)
if (position == tailPositions[i])
std::cout << "o";
tailPrinted = true;
break;


return tailPrinted;


void PrintFruitOrSnakeOrEmptyByPosition(Vector2D position)
if (snakeHeadPosition == position)
std::cout << "O";

else if (currentFruitPosition == position)
std::cout << "X";

else if (!PrintTailOnPositionIfNeeded(position))
std::cout << " ";



void DrawHorizontalBorderByWidth()
for (int i = 0; i < width + 2; ++i)
std::cout << "#";

std::cout << std::endl;


void DrawMiddleSection()
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
if (j == 0)
std::cout << "#";


PrintFruitOrSnakeOrEmptyByPosition( j, i );

if (j == width - 1)
std::cout << "#";


std::cout << std::endl;



#pragma endregion

void DrawPlayingField()
// system("cls");
ClearScreen();

// Top
DrawHorizontalBorderByWidth();

DrawMiddleSection();
// Bottom
DrawHorizontalBorderByWidth();


void UpdateGame()
DrawPlayingField();
HandleInput();
UpdateGameLogic();


#pragma region Request_PlayField_Width_And_Height_From_User

#pragma region Request_For_Valid_Play_Field_Size

bool PlayingFieldSizeIsValid()
return (width >= 10) && (height >= 10);


void RequestForValidPlayingFieldSize()
bool loopFirstRun = true;

// Keep asking for width and height while the given playing field is not of valid size.
do
if (!loopFirstRun)
std::cout << "The width and height of the playing field must be at least 10 or more!";


std::cout << "Enter the gamearea's width: " << std::endl;
RequestForValidInputValue(width, "ERROR: width must be an integer!");
std::cout << "Enter the gamearea's height: " << std::endl;
RequestForValidInputValue(height, "ERROR: Height must be an integer!");

loopFirstRun = false;
while (!PlayingFieldSizeIsValid());


#pragma endregion

void RequestForPlayingFieldSize()
bool confirmed = false;
do
RequestForValidPlayingFieldSize();

std::cout << "Your game area will be (" << width << ", " << height << "), Confirm?" << std::endl;
confirmed = AskUserForYesNo();

while (!confirmed);


#pragma endregion

void ClearAndInitalizeVariables()
tailLength = 0;
playerScore = 0;
gameOver = false;
currentSnakeMovingDirection = UNDEFINED;


void InitializeGame()
ClearScreen();
ClearAndInitalizeVariables();

RequestForPlayingFieldSize();
// Start in the center
snakeHeadPosition = (width / 2), (height / 2) ;
tailPositions[0] = snakeHeadPosition;

PlaceFruitRandomlyInPlayingField();


int main()
// Play the game while the user wants to play again.
do
InitializeGame();

while (!gameOver)
UpdateGame();
std::this_thread::sleep_for(std::chrono::milliseconds(400));


std::cout << "GAMEOVER, Your Score: " << playerScore << std::endl;

std::cout << "Play again? ";

while (AskUserForYesNo());

return 0;



Also, would anyone give me any directions on how to properly overload and make a += operator for Vector2D?

Currently I'm doing addition as Vector1 = Vector1 + Vector2, as I tried to do a += operator but the implementation I did had issues.










share|improve this question









$endgroup$




bumped to the homepage by Community 1 hour ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.



















    3












    $begingroup$


    I recently started learning C++ and have made a very simple Console-based Snake Game, I would like to have some feedback on improvements.



    You might notice the obvious delay in clearing and printing of the screen, as I did not use system("cls") since it was stated as 'evil' and 'bad'.
    I printed a bunch of newlines instead as suggested in a forum that I had read.

    (Didn't use NCurses since it was an overkill for my simple snake game)



    #include <iostream>
    #include <string>
    #include <limits>
    #include <conio.h>

    #include <thread>
    #include <chrono>

    enum Direction2D
    UNDEFINED = 0,
    LEFT,
    RIGHT,
    UP,
    DOWN
    ;

    bool IsOppositeOf(const Direction2D& first, const Direction2D& second)
    // Feedback for a more elegant approach, thanks.
    bool isOpposite = false;
    if (first == LEFT && second == RIGHT)
    isOpposite = true;

    else if (first == RIGHT && second == LEFT)
    isOpposite = true;

    else if (first == UP && second == DOWN)
    isOpposite = true;

    else if (first == DOWN && second == UP)
    isOpposite = true;


    return isOpposite;


    struct Vector2D

    int x;
    int y;
    ;

    // Since we are printing downwards, 'up' would technically be down.
    Vector2D const Up = 0, -1 ;
    Vector2D const Down = 0, 1 ;

    Vector2D const Left = -1, 0 ;
    Vector2D const Right = 1, 0 ;

    Vector2D const Zero = 0, 0 ;

    #pragma region Vector2D_Operators

    bool operator ==(const Vector2D& first, const Vector2D& second)
    return (first.x == second.x) && (first.y == second.y);


    Vector2D operator +(const Vector2D& first, const Vector2D& second)
    return (first.x + second.x), (first.y + second.y) ;


    Vector2D operator -(const Vector2D& first, const Vector2D& second)
    return (first.x - second.x), (first.y - second.y) ;


    #pragma endregion

    bool gameOver;

    int playerScore;

    int width;
    int height;

    Vector2D snakeHeadPosition;
    Vector2D currentFruitPosition;

    Direction2D currentSnakeMovingDirection;

    // I'm assuming the length of the tail doesn't go beyond 256.
    // Accepting feedback on how I could do this more elegantly.
    Vector2D tailPositions[256];

    int tailLength;

    #pragma region Util

    void ClearCinInput()
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');


    template <typename T>
    void RequestForValidInputValue(T &receivingArg, std::string errorMsg)
    // Ask for input while the input is not of the correct type.
    while (!(std::cin >> receivingArg))
    std::cout << errorMsg << std::endl;
    ClearCinInput();



    #pragma region Request_For_YesNo

    void PrintRespectiveYesNoTextByFirstRun(bool firstRun)
    if (firstRun)
    std::cout << "(Y/N)" << std::endl;

    else
    std::cout << "Please input either 'Y' or 'N'." << std::endl;



    bool CheckIfValidYesNoInput(std::string input) input == "N");


    bool AskUserForYesNo()
    std::string userInput = "";

    bool loopFirstRun = true;

    // Ask for input again while the input was not a confirmation.
    do
    PrintRespectiveYesNoTextByFirstRun(loopFirstRun);

    RequestForValidInputValue(userInput, "ERROR: Please input 'Y' or 'N' ");
    loopFirstRun = false;
    while (!CheckIfValidYesNoInput(userInput));

    return userInput == "Y";


    #pragma endregion

    void ClearScreen()
    // SLOW
    std::cout << std::string(100, 'n');


    void PlaceFruitRandomlyInPlayingField()
    currentFruitPosition = rand() % width, rand() % height ;


    #pragma endregion

    void HandleFruitEating()
    ++tailLength;
    ++playerScore;
    PlaceFruitRandomlyInPlayingField();


    bool SnakeEatingFruit()
    return snakeHeadPosition == currentFruitPosition;


    bool SnakeHeadTouchedTail()
    bool touchedTail = false;

    for (int i = 0; i < tailLength; ++i)
    if (tailPositions[i] == snakeHeadPosition)
    touchedTail = true;
    break;


    return touchedTail;


    bool SnakeHeadTouchedBorder() x < 0

    void UpdateSnakePositionByCurrentMoveDirection()
    switch (currentSnakeMovingDirection)
    case LEFT:
    snakeHeadPosition = snakeHeadPosition + Left;
    break;
    case RIGHT:
    snakeHeadPosition = snakeHeadPosition + Right;
    break;
    case UP:
    snakeHeadPosition = snakeHeadPosition + Up;
    break;
    case DOWN:
    snakeHeadPosition = snakeHeadPosition + Down;
    break;
    default:
    break;



    void UpdateSnakeTailPositions()
    Vector2D prevPosition = tailPositions[0];
    Vector2D temp;
    tailPositions[0] = snakeHeadPosition;

    for (int i = 1; i < tailLength; ++i)
    temp = tailPositions[i];
    tailPositions[i] = prevPosition;
    prevPosition = temp;



    void UpdateGameLogic()

    #pragma region Handling_Inputs

    void MoveSnakeIfValid(Direction2D newDirection)
    if (tailLength > 0)
    // To prevent suicidal acts by moving backwards into a tail.
    if (!IsOppositeOf(newDirection, currentSnakeMovingDirection))
    currentSnakeMovingDirection = newDirection;


    else
    currentSnakeMovingDirection = newDirection;



    void MoveSnakeByUserInput(char inputValue)
    Direction2D newMoveDirection;
    switch (inputValue)
    case 'a':
    newMoveDirection = LEFT;
    break;
    case 'd':
    newMoveDirection = RIGHT;
    break;
    case 'w':
    newMoveDirection = UP;
    break;
    case 's':
    newMoveDirection = DOWN;
    break;
    default:
    newMoveDirection = UNDEFINED;
    break;


    if (newMoveDirection != UNDEFINED)
    MoveSnakeIfValid(newMoveDirection);



    bool GetKeyPressInputIfExists(char &keyPressValue)
    if (_kbhit())
    keyPressValue = _getch();
    return true;

    else
    return false;



    #pragma endregion

    void HandleInput()
    char keyPressValue;
    if (GetKeyPressInputIfExists(keyPressValue))
    MoveSnakeByUserInput(keyPressValue);



    #pragma region Drawing_PlayField

    bool PrintTailOnPositionIfNeeded(Vector2D position)
    bool tailPrinted = false;
    for (int i = 0; i < tailLength; ++i)
    if (position == tailPositions[i])
    std::cout << "o";
    tailPrinted = true;
    break;


    return tailPrinted;


    void PrintFruitOrSnakeOrEmptyByPosition(Vector2D position)
    if (snakeHeadPosition == position)
    std::cout << "O";

    else if (currentFruitPosition == position)
    std::cout << "X";

    else if (!PrintTailOnPositionIfNeeded(position))
    std::cout << " ";



    void DrawHorizontalBorderByWidth()
    for (int i = 0; i < width + 2; ++i)
    std::cout << "#";

    std::cout << std::endl;


    void DrawMiddleSection()
    for (int i = 0; i < height; ++i)
    for (int j = 0; j < width; ++j)
    if (j == 0)
    std::cout << "#";


    PrintFruitOrSnakeOrEmptyByPosition( j, i );

    if (j == width - 1)
    std::cout << "#";


    std::cout << std::endl;



    #pragma endregion

    void DrawPlayingField()
    // system("cls");
    ClearScreen();

    // Top
    DrawHorizontalBorderByWidth();

    DrawMiddleSection();
    // Bottom
    DrawHorizontalBorderByWidth();


    void UpdateGame()
    DrawPlayingField();
    HandleInput();
    UpdateGameLogic();


    #pragma region Request_PlayField_Width_And_Height_From_User

    #pragma region Request_For_Valid_Play_Field_Size

    bool PlayingFieldSizeIsValid()
    return (width >= 10) && (height >= 10);


    void RequestForValidPlayingFieldSize()
    bool loopFirstRun = true;

    // Keep asking for width and height while the given playing field is not of valid size.
    do
    if (!loopFirstRun)
    std::cout << "The width and height of the playing field must be at least 10 or more!";


    std::cout << "Enter the gamearea's width: " << std::endl;
    RequestForValidInputValue(width, "ERROR: width must be an integer!");
    std::cout << "Enter the gamearea's height: " << std::endl;
    RequestForValidInputValue(height, "ERROR: Height must be an integer!");

    loopFirstRun = false;
    while (!PlayingFieldSizeIsValid());


    #pragma endregion

    void RequestForPlayingFieldSize()
    bool confirmed = false;
    do
    RequestForValidPlayingFieldSize();

    std::cout << "Your game area will be (" << width << ", " << height << "), Confirm?" << std::endl;
    confirmed = AskUserForYesNo();

    while (!confirmed);


    #pragma endregion

    void ClearAndInitalizeVariables()
    tailLength = 0;
    playerScore = 0;
    gameOver = false;
    currentSnakeMovingDirection = UNDEFINED;


    void InitializeGame()
    ClearScreen();
    ClearAndInitalizeVariables();

    RequestForPlayingFieldSize();
    // Start in the center
    snakeHeadPosition = (width / 2), (height / 2) ;
    tailPositions[0] = snakeHeadPosition;

    PlaceFruitRandomlyInPlayingField();


    int main()
    // Play the game while the user wants to play again.
    do
    InitializeGame();

    while (!gameOver)
    UpdateGame();
    std::this_thread::sleep_for(std::chrono::milliseconds(400));


    std::cout << "GAMEOVER, Your Score: " << playerScore << std::endl;

    std::cout << "Play again? ";

    while (AskUserForYesNo());

    return 0;



    Also, would anyone give me any directions on how to properly overload and make a += operator for Vector2D?

    Currently I'm doing addition as Vector1 = Vector1 + Vector2, as I tried to do a += operator but the implementation I did had issues.










    share|improve this question









    $endgroup$




    bumped to the homepage by Community 1 hour ago


    This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

















      3












      3








      3





      $begingroup$


      I recently started learning C++ and have made a very simple Console-based Snake Game, I would like to have some feedback on improvements.



      You might notice the obvious delay in clearing and printing of the screen, as I did not use system("cls") since it was stated as 'evil' and 'bad'.
      I printed a bunch of newlines instead as suggested in a forum that I had read.

      (Didn't use NCurses since it was an overkill for my simple snake game)



      #include <iostream>
      #include <string>
      #include <limits>
      #include <conio.h>

      #include <thread>
      #include <chrono>

      enum Direction2D
      UNDEFINED = 0,
      LEFT,
      RIGHT,
      UP,
      DOWN
      ;

      bool IsOppositeOf(const Direction2D& first, const Direction2D& second)
      // Feedback for a more elegant approach, thanks.
      bool isOpposite = false;
      if (first == LEFT && second == RIGHT)
      isOpposite = true;

      else if (first == RIGHT && second == LEFT)
      isOpposite = true;

      else if (first == UP && second == DOWN)
      isOpposite = true;

      else if (first == DOWN && second == UP)
      isOpposite = true;


      return isOpposite;


      struct Vector2D

      int x;
      int y;
      ;

      // Since we are printing downwards, 'up' would technically be down.
      Vector2D const Up = 0, -1 ;
      Vector2D const Down = 0, 1 ;

      Vector2D const Left = -1, 0 ;
      Vector2D const Right = 1, 0 ;

      Vector2D const Zero = 0, 0 ;

      #pragma region Vector2D_Operators

      bool operator ==(const Vector2D& first, const Vector2D& second)
      return (first.x == second.x) && (first.y == second.y);


      Vector2D operator +(const Vector2D& first, const Vector2D& second)
      return (first.x + second.x), (first.y + second.y) ;


      Vector2D operator -(const Vector2D& first, const Vector2D& second)
      return (first.x - second.x), (first.y - second.y) ;


      #pragma endregion

      bool gameOver;

      int playerScore;

      int width;
      int height;

      Vector2D snakeHeadPosition;
      Vector2D currentFruitPosition;

      Direction2D currentSnakeMovingDirection;

      // I'm assuming the length of the tail doesn't go beyond 256.
      // Accepting feedback on how I could do this more elegantly.
      Vector2D tailPositions[256];

      int tailLength;

      #pragma region Util

      void ClearCinInput()
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');


      template <typename T>
      void RequestForValidInputValue(T &receivingArg, std::string errorMsg)
      // Ask for input while the input is not of the correct type.
      while (!(std::cin >> receivingArg))
      std::cout << errorMsg << std::endl;
      ClearCinInput();



      #pragma region Request_For_YesNo

      void PrintRespectiveYesNoTextByFirstRun(bool firstRun)
      if (firstRun)
      std::cout << "(Y/N)" << std::endl;

      else
      std::cout << "Please input either 'Y' or 'N'." << std::endl;



      bool CheckIfValidYesNoInput(std::string input) input == "N");


      bool AskUserForYesNo()
      std::string userInput = "";

      bool loopFirstRun = true;

      // Ask for input again while the input was not a confirmation.
      do
      PrintRespectiveYesNoTextByFirstRun(loopFirstRun);

      RequestForValidInputValue(userInput, "ERROR: Please input 'Y' or 'N' ");
      loopFirstRun = false;
      while (!CheckIfValidYesNoInput(userInput));

      return userInput == "Y";


      #pragma endregion

      void ClearScreen()
      // SLOW
      std::cout << std::string(100, 'n');


      void PlaceFruitRandomlyInPlayingField()
      currentFruitPosition = rand() % width, rand() % height ;


      #pragma endregion

      void HandleFruitEating()
      ++tailLength;
      ++playerScore;
      PlaceFruitRandomlyInPlayingField();


      bool SnakeEatingFruit()
      return snakeHeadPosition == currentFruitPosition;


      bool SnakeHeadTouchedTail()
      bool touchedTail = false;

      for (int i = 0; i < tailLength; ++i)
      if (tailPositions[i] == snakeHeadPosition)
      touchedTail = true;
      break;


      return touchedTail;


      bool SnakeHeadTouchedBorder() x < 0

      void UpdateSnakePositionByCurrentMoveDirection()
      switch (currentSnakeMovingDirection)
      case LEFT:
      snakeHeadPosition = snakeHeadPosition + Left;
      break;
      case RIGHT:
      snakeHeadPosition = snakeHeadPosition + Right;
      break;
      case UP:
      snakeHeadPosition = snakeHeadPosition + Up;
      break;
      case DOWN:
      snakeHeadPosition = snakeHeadPosition + Down;
      break;
      default:
      break;



      void UpdateSnakeTailPositions()
      Vector2D prevPosition = tailPositions[0];
      Vector2D temp;
      tailPositions[0] = snakeHeadPosition;

      for (int i = 1; i < tailLength; ++i)
      temp = tailPositions[i];
      tailPositions[i] = prevPosition;
      prevPosition = temp;



      void UpdateGameLogic()

      #pragma region Handling_Inputs

      void MoveSnakeIfValid(Direction2D newDirection)
      if (tailLength > 0)
      // To prevent suicidal acts by moving backwards into a tail.
      if (!IsOppositeOf(newDirection, currentSnakeMovingDirection))
      currentSnakeMovingDirection = newDirection;


      else
      currentSnakeMovingDirection = newDirection;



      void MoveSnakeByUserInput(char inputValue)
      Direction2D newMoveDirection;
      switch (inputValue)
      case 'a':
      newMoveDirection = LEFT;
      break;
      case 'd':
      newMoveDirection = RIGHT;
      break;
      case 'w':
      newMoveDirection = UP;
      break;
      case 's':
      newMoveDirection = DOWN;
      break;
      default:
      newMoveDirection = UNDEFINED;
      break;


      if (newMoveDirection != UNDEFINED)
      MoveSnakeIfValid(newMoveDirection);



      bool GetKeyPressInputIfExists(char &keyPressValue)
      if (_kbhit())
      keyPressValue = _getch();
      return true;

      else
      return false;



      #pragma endregion

      void HandleInput()
      char keyPressValue;
      if (GetKeyPressInputIfExists(keyPressValue))
      MoveSnakeByUserInput(keyPressValue);



      #pragma region Drawing_PlayField

      bool PrintTailOnPositionIfNeeded(Vector2D position)
      bool tailPrinted = false;
      for (int i = 0; i < tailLength; ++i)
      if (position == tailPositions[i])
      std::cout << "o";
      tailPrinted = true;
      break;


      return tailPrinted;


      void PrintFruitOrSnakeOrEmptyByPosition(Vector2D position)
      if (snakeHeadPosition == position)
      std::cout << "O";

      else if (currentFruitPosition == position)
      std::cout << "X";

      else if (!PrintTailOnPositionIfNeeded(position))
      std::cout << " ";



      void DrawHorizontalBorderByWidth()
      for (int i = 0; i < width + 2; ++i)
      std::cout << "#";

      std::cout << std::endl;


      void DrawMiddleSection()
      for (int i = 0; i < height; ++i)
      for (int j = 0; j < width; ++j)
      if (j == 0)
      std::cout << "#";


      PrintFruitOrSnakeOrEmptyByPosition( j, i );

      if (j == width - 1)
      std::cout << "#";


      std::cout << std::endl;



      #pragma endregion

      void DrawPlayingField()
      // system("cls");
      ClearScreen();

      // Top
      DrawHorizontalBorderByWidth();

      DrawMiddleSection();
      // Bottom
      DrawHorizontalBorderByWidth();


      void UpdateGame()
      DrawPlayingField();
      HandleInput();
      UpdateGameLogic();


      #pragma region Request_PlayField_Width_And_Height_From_User

      #pragma region Request_For_Valid_Play_Field_Size

      bool PlayingFieldSizeIsValid()
      return (width >= 10) && (height >= 10);


      void RequestForValidPlayingFieldSize()
      bool loopFirstRun = true;

      // Keep asking for width and height while the given playing field is not of valid size.
      do
      if (!loopFirstRun)
      std::cout << "The width and height of the playing field must be at least 10 or more!";


      std::cout << "Enter the gamearea's width: " << std::endl;
      RequestForValidInputValue(width, "ERROR: width must be an integer!");
      std::cout << "Enter the gamearea's height: " << std::endl;
      RequestForValidInputValue(height, "ERROR: Height must be an integer!");

      loopFirstRun = false;
      while (!PlayingFieldSizeIsValid());


      #pragma endregion

      void RequestForPlayingFieldSize()
      bool confirmed = false;
      do
      RequestForValidPlayingFieldSize();

      std::cout << "Your game area will be (" << width << ", " << height << "), Confirm?" << std::endl;
      confirmed = AskUserForYesNo();

      while (!confirmed);


      #pragma endregion

      void ClearAndInitalizeVariables()
      tailLength = 0;
      playerScore = 0;
      gameOver = false;
      currentSnakeMovingDirection = UNDEFINED;


      void InitializeGame()
      ClearScreen();
      ClearAndInitalizeVariables();

      RequestForPlayingFieldSize();
      // Start in the center
      snakeHeadPosition = (width / 2), (height / 2) ;
      tailPositions[0] = snakeHeadPosition;

      PlaceFruitRandomlyInPlayingField();


      int main()
      // Play the game while the user wants to play again.
      do
      InitializeGame();

      while (!gameOver)
      UpdateGame();
      std::this_thread::sleep_for(std::chrono::milliseconds(400));


      std::cout << "GAMEOVER, Your Score: " << playerScore << std::endl;

      std::cout << "Play again? ";

      while (AskUserForYesNo());

      return 0;



      Also, would anyone give me any directions on how to properly overload and make a += operator for Vector2D?

      Currently I'm doing addition as Vector1 = Vector1 + Vector2, as I tried to do a += operator but the implementation I did had issues.










      share|improve this question









      $endgroup$




      I recently started learning C++ and have made a very simple Console-based Snake Game, I would like to have some feedback on improvements.



      You might notice the obvious delay in clearing and printing of the screen, as I did not use system("cls") since it was stated as 'evil' and 'bad'.
      I printed a bunch of newlines instead as suggested in a forum that I had read.

      (Didn't use NCurses since it was an overkill for my simple snake game)



      #include <iostream>
      #include <string>
      #include <limits>
      #include <conio.h>

      #include <thread>
      #include <chrono>

      enum Direction2D
      UNDEFINED = 0,
      LEFT,
      RIGHT,
      UP,
      DOWN
      ;

      bool IsOppositeOf(const Direction2D& first, const Direction2D& second)
      // Feedback for a more elegant approach, thanks.
      bool isOpposite = false;
      if (first == LEFT && second == RIGHT)
      isOpposite = true;

      else if (first == RIGHT && second == LEFT)
      isOpposite = true;

      else if (first == UP && second == DOWN)
      isOpposite = true;

      else if (first == DOWN && second == UP)
      isOpposite = true;


      return isOpposite;


      struct Vector2D

      int x;
      int y;
      ;

      // Since we are printing downwards, 'up' would technically be down.
      Vector2D const Up = 0, -1 ;
      Vector2D const Down = 0, 1 ;

      Vector2D const Left = -1, 0 ;
      Vector2D const Right = 1, 0 ;

      Vector2D const Zero = 0, 0 ;

      #pragma region Vector2D_Operators

      bool operator ==(const Vector2D& first, const Vector2D& second)
      return (first.x == second.x) && (first.y == second.y);


      Vector2D operator +(const Vector2D& first, const Vector2D& second)
      return (first.x + second.x), (first.y + second.y) ;


      Vector2D operator -(const Vector2D& first, const Vector2D& second)
      return (first.x - second.x), (first.y - second.y) ;


      #pragma endregion

      bool gameOver;

      int playerScore;

      int width;
      int height;

      Vector2D snakeHeadPosition;
      Vector2D currentFruitPosition;

      Direction2D currentSnakeMovingDirection;

      // I'm assuming the length of the tail doesn't go beyond 256.
      // Accepting feedback on how I could do this more elegantly.
      Vector2D tailPositions[256];

      int tailLength;

      #pragma region Util

      void ClearCinInput()
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');


      template <typename T>
      void RequestForValidInputValue(T &receivingArg, std::string errorMsg)
      // Ask for input while the input is not of the correct type.
      while (!(std::cin >> receivingArg))
      std::cout << errorMsg << std::endl;
      ClearCinInput();



      #pragma region Request_For_YesNo

      void PrintRespectiveYesNoTextByFirstRun(bool firstRun)
      if (firstRun)
      std::cout << "(Y/N)" << std::endl;

      else
      std::cout << "Please input either 'Y' or 'N'." << std::endl;



      bool CheckIfValidYesNoInput(std::string input) input == "N");


      bool AskUserForYesNo()
      std::string userInput = "";

      bool loopFirstRun = true;

      // Ask for input again while the input was not a confirmation.
      do
      PrintRespectiveYesNoTextByFirstRun(loopFirstRun);

      RequestForValidInputValue(userInput, "ERROR: Please input 'Y' or 'N' ");
      loopFirstRun = false;
      while (!CheckIfValidYesNoInput(userInput));

      return userInput == "Y";


      #pragma endregion

      void ClearScreen()
      // SLOW
      std::cout << std::string(100, 'n');


      void PlaceFruitRandomlyInPlayingField()
      currentFruitPosition = rand() % width, rand() % height ;


      #pragma endregion

      void HandleFruitEating()
      ++tailLength;
      ++playerScore;
      PlaceFruitRandomlyInPlayingField();


      bool SnakeEatingFruit()
      return snakeHeadPosition == currentFruitPosition;


      bool SnakeHeadTouchedTail()
      bool touchedTail = false;

      for (int i = 0; i < tailLength; ++i)
      if (tailPositions[i] == snakeHeadPosition)
      touchedTail = true;
      break;


      return touchedTail;


      bool SnakeHeadTouchedBorder() x < 0

      void UpdateSnakePositionByCurrentMoveDirection()
      switch (currentSnakeMovingDirection)
      case LEFT:
      snakeHeadPosition = snakeHeadPosition + Left;
      break;
      case RIGHT:
      snakeHeadPosition = snakeHeadPosition + Right;
      break;
      case UP:
      snakeHeadPosition = snakeHeadPosition + Up;
      break;
      case DOWN:
      snakeHeadPosition = snakeHeadPosition + Down;
      break;
      default:
      break;



      void UpdateSnakeTailPositions()
      Vector2D prevPosition = tailPositions[0];
      Vector2D temp;
      tailPositions[0] = snakeHeadPosition;

      for (int i = 1; i < tailLength; ++i)
      temp = tailPositions[i];
      tailPositions[i] = prevPosition;
      prevPosition = temp;



      void UpdateGameLogic()

      #pragma region Handling_Inputs

      void MoveSnakeIfValid(Direction2D newDirection)
      if (tailLength > 0)
      // To prevent suicidal acts by moving backwards into a tail.
      if (!IsOppositeOf(newDirection, currentSnakeMovingDirection))
      currentSnakeMovingDirection = newDirection;


      else
      currentSnakeMovingDirection = newDirection;



      void MoveSnakeByUserInput(char inputValue)
      Direction2D newMoveDirection;
      switch (inputValue)
      case 'a':
      newMoveDirection = LEFT;
      break;
      case 'd':
      newMoveDirection = RIGHT;
      break;
      case 'w':
      newMoveDirection = UP;
      break;
      case 's':
      newMoveDirection = DOWN;
      break;
      default:
      newMoveDirection = UNDEFINED;
      break;


      if (newMoveDirection != UNDEFINED)
      MoveSnakeIfValid(newMoveDirection);



      bool GetKeyPressInputIfExists(char &keyPressValue)
      if (_kbhit())
      keyPressValue = _getch();
      return true;

      else
      return false;



      #pragma endregion

      void HandleInput()
      char keyPressValue;
      if (GetKeyPressInputIfExists(keyPressValue))
      MoveSnakeByUserInput(keyPressValue);



      #pragma region Drawing_PlayField

      bool PrintTailOnPositionIfNeeded(Vector2D position)
      bool tailPrinted = false;
      for (int i = 0; i < tailLength; ++i)
      if (position == tailPositions[i])
      std::cout << "o";
      tailPrinted = true;
      break;


      return tailPrinted;


      void PrintFruitOrSnakeOrEmptyByPosition(Vector2D position)
      if (snakeHeadPosition == position)
      std::cout << "O";

      else if (currentFruitPosition == position)
      std::cout << "X";

      else if (!PrintTailOnPositionIfNeeded(position))
      std::cout << " ";



      void DrawHorizontalBorderByWidth()
      for (int i = 0; i < width + 2; ++i)
      std::cout << "#";

      std::cout << std::endl;


      void DrawMiddleSection()
      for (int i = 0; i < height; ++i)
      for (int j = 0; j < width; ++j)
      if (j == 0)
      std::cout << "#";


      PrintFruitOrSnakeOrEmptyByPosition( j, i );

      if (j == width - 1)
      std::cout << "#";


      std::cout << std::endl;



      #pragma endregion

      void DrawPlayingField()
      // system("cls");
      ClearScreen();

      // Top
      DrawHorizontalBorderByWidth();

      DrawMiddleSection();
      // Bottom
      DrawHorizontalBorderByWidth();


      void UpdateGame()
      DrawPlayingField();
      HandleInput();
      UpdateGameLogic();


      #pragma region Request_PlayField_Width_And_Height_From_User

      #pragma region Request_For_Valid_Play_Field_Size

      bool PlayingFieldSizeIsValid()
      return (width >= 10) && (height >= 10);


      void RequestForValidPlayingFieldSize()
      bool loopFirstRun = true;

      // Keep asking for width and height while the given playing field is not of valid size.
      do
      if (!loopFirstRun)
      std::cout << "The width and height of the playing field must be at least 10 or more!";


      std::cout << "Enter the gamearea's width: " << std::endl;
      RequestForValidInputValue(width, "ERROR: width must be an integer!");
      std::cout << "Enter the gamearea's height: " << std::endl;
      RequestForValidInputValue(height, "ERROR: Height must be an integer!");

      loopFirstRun = false;
      while (!PlayingFieldSizeIsValid());


      #pragma endregion

      void RequestForPlayingFieldSize()
      bool confirmed = false;
      do
      RequestForValidPlayingFieldSize();

      std::cout << "Your game area will be (" << width << ", " << height << "), Confirm?" << std::endl;
      confirmed = AskUserForYesNo();

      while (!confirmed);


      #pragma endregion

      void ClearAndInitalizeVariables()
      tailLength = 0;
      playerScore = 0;
      gameOver = false;
      currentSnakeMovingDirection = UNDEFINED;


      void InitializeGame()
      ClearScreen();
      ClearAndInitalizeVariables();

      RequestForPlayingFieldSize();
      // Start in the center
      snakeHeadPosition = (width / 2), (height / 2) ;
      tailPositions[0] = snakeHeadPosition;

      PlaceFruitRandomlyInPlayingField();


      int main()
      // Play the game while the user wants to play again.
      do
      InitializeGame();

      while (!gameOver)
      UpdateGame();
      std::this_thread::sleep_for(std::chrono::milliseconds(400));


      std::cout << "GAMEOVER, Your Score: " << playerScore << std::endl;

      std::cout << "Play again? ";

      while (AskUserForYesNo());

      return 0;



      Also, would anyone give me any directions on how to properly overload and make a += operator for Vector2D?

      Currently I'm doing addition as Vector1 = Vector1 + Vector2, as I tried to do a += operator but the implementation I did had issues.







      c++ game console snake-game






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Feb 12 at 18:56









      KaynnKaynn

      1438




      1438





      bumped to the homepage by Community 1 hour ago


      This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







      bumped to the homepage by Community 1 hour ago


      This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.






















          1 Answer
          1






          active

          oldest

          votes


















          0












          $begingroup$

          Small Bug Fix



          Noticed a small bug in my game, where the fruit might have a chance to spawn inside the snake.

          Did a quick fix for it:



          Renamed PlaceFruitRandomlyInPlayingField into PlaceFruitInPlayingField, added and changed codes:



          bool ValidPositionForFruit(Vector2D position) 
          bool isValidPosForFruit = true;

          if (position == snakeHeadPosition)
          isValidPosForFruit = false;

          else if (PositionIsTouchingTail(position))
          isValidPosForFruit = false;


          return isValidPosForFruit;


          void PlaceFruitInPlayingField()
          // Change the fruit position while the fruit's current position is not valid.
          do
          currentFruitPosition = rand() % width, rand() % height ;
          while (!ValidPositionForFruit(currentFruitPosition));



          Finally, I renamed and refactored SnakeHeadTouchedTail into PositionIsTouchingTail(Vector2D) since my I do need to check if my new fruit's position would touch the head, and I didn't want to repeat myself:



          bool PositionIsTouchingTail(Vector2D position) 
          bool touchedTail = false;

          for (int i = 0; i < tailLength; ++i)
          if (tailPositions[i] == position)
          touchedTail = true;
          break;


          return touchedTail;



          And I placed inside the #pragma region Util since C++ is picky about function placements.

          (The region should be near the top)



          Also, in UpdateGameLogic() function, as you might have guessed, I'm doing PositionIsTouchingTail(snakeHeadPosition) instead of SnakeHeadTouchedTail() to check if the snake's head had touched the tail.






          share|improve this answer









          $endgroup$












            Your Answer





            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213324%2fsimple-console-snake-game-c%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0












            $begingroup$

            Small Bug Fix



            Noticed a small bug in my game, where the fruit might have a chance to spawn inside the snake.

            Did a quick fix for it:



            Renamed PlaceFruitRandomlyInPlayingField into PlaceFruitInPlayingField, added and changed codes:



            bool ValidPositionForFruit(Vector2D position) 
            bool isValidPosForFruit = true;

            if (position == snakeHeadPosition)
            isValidPosForFruit = false;

            else if (PositionIsTouchingTail(position))
            isValidPosForFruit = false;


            return isValidPosForFruit;


            void PlaceFruitInPlayingField()
            // Change the fruit position while the fruit's current position is not valid.
            do
            currentFruitPosition = rand() % width, rand() % height ;
            while (!ValidPositionForFruit(currentFruitPosition));



            Finally, I renamed and refactored SnakeHeadTouchedTail into PositionIsTouchingTail(Vector2D) since my I do need to check if my new fruit's position would touch the head, and I didn't want to repeat myself:



            bool PositionIsTouchingTail(Vector2D position) 
            bool touchedTail = false;

            for (int i = 0; i < tailLength; ++i)
            if (tailPositions[i] == position)
            touchedTail = true;
            break;


            return touchedTail;



            And I placed inside the #pragma region Util since C++ is picky about function placements.

            (The region should be near the top)



            Also, in UpdateGameLogic() function, as you might have guessed, I'm doing PositionIsTouchingTail(snakeHeadPosition) instead of SnakeHeadTouchedTail() to check if the snake's head had touched the tail.






            share|improve this answer









            $endgroup$

















              0












              $begingroup$

              Small Bug Fix



              Noticed a small bug in my game, where the fruit might have a chance to spawn inside the snake.

              Did a quick fix for it:



              Renamed PlaceFruitRandomlyInPlayingField into PlaceFruitInPlayingField, added and changed codes:



              bool ValidPositionForFruit(Vector2D position) 
              bool isValidPosForFruit = true;

              if (position == snakeHeadPosition)
              isValidPosForFruit = false;

              else if (PositionIsTouchingTail(position))
              isValidPosForFruit = false;


              return isValidPosForFruit;


              void PlaceFruitInPlayingField()
              // Change the fruit position while the fruit's current position is not valid.
              do
              currentFruitPosition = rand() % width, rand() % height ;
              while (!ValidPositionForFruit(currentFruitPosition));



              Finally, I renamed and refactored SnakeHeadTouchedTail into PositionIsTouchingTail(Vector2D) since my I do need to check if my new fruit's position would touch the head, and I didn't want to repeat myself:



              bool PositionIsTouchingTail(Vector2D position) 
              bool touchedTail = false;

              for (int i = 0; i < tailLength; ++i)
              if (tailPositions[i] == position)
              touchedTail = true;
              break;


              return touchedTail;



              And I placed inside the #pragma region Util since C++ is picky about function placements.

              (The region should be near the top)



              Also, in UpdateGameLogic() function, as you might have guessed, I'm doing PositionIsTouchingTail(snakeHeadPosition) instead of SnakeHeadTouchedTail() to check if the snake's head had touched the tail.






              share|improve this answer









              $endgroup$















                0












                0








                0





                $begingroup$

                Small Bug Fix



                Noticed a small bug in my game, where the fruit might have a chance to spawn inside the snake.

                Did a quick fix for it:



                Renamed PlaceFruitRandomlyInPlayingField into PlaceFruitInPlayingField, added and changed codes:



                bool ValidPositionForFruit(Vector2D position) 
                bool isValidPosForFruit = true;

                if (position == snakeHeadPosition)
                isValidPosForFruit = false;

                else if (PositionIsTouchingTail(position))
                isValidPosForFruit = false;


                return isValidPosForFruit;


                void PlaceFruitInPlayingField()
                // Change the fruit position while the fruit's current position is not valid.
                do
                currentFruitPosition = rand() % width, rand() % height ;
                while (!ValidPositionForFruit(currentFruitPosition));



                Finally, I renamed and refactored SnakeHeadTouchedTail into PositionIsTouchingTail(Vector2D) since my I do need to check if my new fruit's position would touch the head, and I didn't want to repeat myself:



                bool PositionIsTouchingTail(Vector2D position) 
                bool touchedTail = false;

                for (int i = 0; i < tailLength; ++i)
                if (tailPositions[i] == position)
                touchedTail = true;
                break;


                return touchedTail;



                And I placed inside the #pragma region Util since C++ is picky about function placements.

                (The region should be near the top)



                Also, in UpdateGameLogic() function, as you might have guessed, I'm doing PositionIsTouchingTail(snakeHeadPosition) instead of SnakeHeadTouchedTail() to check if the snake's head had touched the tail.






                share|improve this answer









                $endgroup$



                Small Bug Fix



                Noticed a small bug in my game, where the fruit might have a chance to spawn inside the snake.

                Did a quick fix for it:



                Renamed PlaceFruitRandomlyInPlayingField into PlaceFruitInPlayingField, added and changed codes:



                bool ValidPositionForFruit(Vector2D position) 
                bool isValidPosForFruit = true;

                if (position == snakeHeadPosition)
                isValidPosForFruit = false;

                else if (PositionIsTouchingTail(position))
                isValidPosForFruit = false;


                return isValidPosForFruit;


                void PlaceFruitInPlayingField()
                // Change the fruit position while the fruit's current position is not valid.
                do
                currentFruitPosition = rand() % width, rand() % height ;
                while (!ValidPositionForFruit(currentFruitPosition));



                Finally, I renamed and refactored SnakeHeadTouchedTail into PositionIsTouchingTail(Vector2D) since my I do need to check if my new fruit's position would touch the head, and I didn't want to repeat myself:



                bool PositionIsTouchingTail(Vector2D position) 
                bool touchedTail = false;

                for (int i = 0; i < tailLength; ++i)
                if (tailPositions[i] == position)
                touchedTail = true;
                break;


                return touchedTail;



                And I placed inside the #pragma region Util since C++ is picky about function placements.

                (The region should be near the top)



                Also, in UpdateGameLogic() function, as you might have guessed, I'm doing PositionIsTouchingTail(snakeHeadPosition) instead of SnakeHeadTouchedTail() to check if the snake's head had touched the tail.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Feb 12 at 19:26









                KaynnKaynn

                1438




                1438



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213324%2fsimple-console-snake-game-c%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    बाताम इन्हें भी देखें सन्दर्भ दिक्चालन सूची1°05′00″N 104°02′0″E / 1.08333°N 104.03333°E / 1.08333; 104.033331°05′00″N 104°02′0″E / 1.08333°N 104.03333°E / 1.08333; 104.03333

                    Why is the 'in' operator throwing an error with a string literal instead of logging false?Why can't I use switch statement on a String?Python join: why is it string.join(list) instead of list.join(string)?Multiline String Literal in C#Why does comparing strings using either '==' or 'is' sometimes produce a different result?How to initialize an array's length in javascript?How can I print literal curly-brace characters in python string and also use .format on it?Why does ++[[]][+[]]+[+[]] return the string “10”?Why is char[] preferred over String for passwords?Why does this code using random strings print “hello world”?jQuery.inArray(), how to use it right?

                    How can we generalize the fact of finite dimensional vector space to an infinte dimensional case?$k[x]$-module and cyclic module over a finite dimensional vector spaceSubspace of a finite dimensional space is finite dimensionalIf V is an infinite-dimensional vector space, and S is an infinite-dimensional subspace of V, must the dimension of V/S be finite? ExplainWhy is an infinite dimensional space so different than a finite dimensional one?base for finite dimensional vector space is not infinite dimensional vector space?Any finite-dimensional vector space is the dual space of anotherHaving Trouble Understanding Meaning Of A Finite-Dimensional Vector SpaceProve that “Every subspaces of a finite-dimensional vector space is finite-dimensional”Ring as a finite dimensional Vector space over a field KQuestion regarding basis and dimension