Reputation: 3
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
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
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
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