JakubDryka
JakubDryka

Reputation: 3

C++ Accessing if statements if they are inside for loop

Im writing snake in c++, and i came across some problems. My printBoard method just prints the map for the game. It has access to array where the clean map is sitting. But the most important part is that it checks if coordinates of current field are the same as Food coordinats or one of snake's body coordinates. Obviously if they arent it just prints clean field. And here goes the question, can i somehow connect if statement from inside of my last loop to if and else outside. now its saying there is no previous if statement?

void Board::printBoard(Player player1)
{
    system("cls");
    for(unsigned int i=0; i< BOARD_HEIGHT ; i++)
    {
        for(unsigned int j=0; j< BOARD_WIDTH; j++)
        {
            for(unsigned int z=0; z< player1._snakeBody.size(); z++)
            {
                if(j == player1._snakeBody.at(z).first && i == player1._snakeBody.at(z).second)
                {
                    std::cout<< "S";
                }
            }
            if(j ==_foodXcord && i == _foodYcord)
            {
                std::cout<< "X";
            }
            else
            {
                std::cout << this->_board[i][j];
            }
        }
        std::cout << std::endl;
    }
}

this what i have here isnt right because it prints the blank field even if SnakeBody is found on it.

Upvotes: 0

Views: 61

Answers (3)

Jarod42
Jarod42

Reputation: 217085

Another alternative is to use intermediate buffer:

void Board::printBoard(Player player1)
{
    auto screen = this->_board; // assuming no C-array but std::vector or std::array

    for (auto pos : player1._snakeBody) {
        screen[pos.first][p.second] = 'S';
    }
    if (0 <= _foodYcord && _foodYcord < BOARD_HEIGHT
       && 0 <= _foodXcord && _foodXcord < BOARD_WIDTH) {
        screen[_foodYcord][_foodXcord] = 'X';
    }
    system("cls");
    for (unsigned int y = 0; y != BOARD_HEIGHT; ++y) {
        for (unsigned int x = 0; x != BOARD_WIDTH; ++x) {
            std::cout << screen[y][x];
        }
        std::cout << std::endl;
    }
}

Upvotes: 0

cigien
cigien

Reputation: 60208

If you just replace the loop with an appropriate algorithm, then you can use an if-else statement quite easily:

for(unsigned int i=0; i< BOARD_HEIGHT ; i++)
    {
        for(unsigned int j=0; j< BOARD_WIDTH; j++)
        {
            if (std::any_of(std::begin(player1._snakeBody), std::end(player1._snakeBody),
                            [&](auto snake) { return snake == {j, i};
                })
            {
                std::cout<< "S";
            }
            else if(j ==_foodXcord && i == _foodYcord)
            {
                std::cout<< "X";
            }
            else
            {
                std::cout << this->_board[i][j];
            }
        }
     }

This avoids having to use a bool flag, which you would need with a for loop. This also has the advantage of breaking as soon as the body is found at a position (which you could have done with a break statement in your original code as well).

Upvotes: 1

Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33864

Simplest solution is to just keep a track of if you have printed or not:

for(unsigned int j=0; j< BOARD_WIDTH; j++) {
    bool havePrinted = false;
    for(unsigned int z=0; z< player1._snakeBody.size(); z++) {
        if(j == player1._snakeBody.at(z).first && i == player1._snakeBody.at(z).second) {
            havePrinted = true;
            std::cout<< "S";
        }
    }
    if(j ==_foodXcord && i == _foodYcord && !havePrinted) {
        std::cout<< "X";
        havePrinted = true;
    }
    if (!havePrinted) {
        std::cout << this->_board[i][j];
    }
}

More complex solutions might involve reconsidering your data structures such that when you look up what is at a position on the board, you know what to print.

Upvotes: 0

Related Questions