Я работаю над простой текстовой игрой Battle Ship на C ++. В настоящее время я пытаюсь заставить сетку / доску правильно отображаться в консоли. У меня было правильное форматирование, но я обнаружил, что элементы 2D-массива не будут правильными.
Ниже приведен пример. Я установил все элементы в 2D сетке на Z, но все они появляются как Y, по какой-то причине. Почему меняется переменная?
#include <iostream>
using namespace std;
enum Grid {X, Y, Z};
const int GRID_SIZE = 10;
Grid grid[GRID_SIZE][GRID_SIZE] = {Z};
void displayGrid();
int main()
{
displayGrid();
cin.get();
return 0;
}
void displayGrid()
{
// Display top column of the grid, containing numbers.
cout << "\t |";
for (int i = 0; i < GRID_SIZE; i++)
cout << i << "|";
cout << endl;
Grid gridContent;
for (int y = 0; y < GRID_SIZE; y++)
{
cout << "\t" << y << "|";
for (int x = 0; x < GRID_SIZE; x++)
{
gridContent = grid[y][x];
if (gridContent = X)
cout << "X|";
else if (gridContent = Y)
cout << "Y|";
else if (gridContent = Z)
cout << "Z|";
}
cout << "\n";
}
}
Первый:
Grid grid[GRID_SIZE][GRID_SIZE] = {Z}
инициализирует только первый элемент массива grid
с Z
(а остальные элементы до 0 см. агрегатная инициализация). Вам нужен вложенный цикл внутри main
который инициализирует все элементы к Z
, лайк
for(int i = 0; i < GRID_SIZE; ++i)
for(int j = 0; j < GRID_SIZE; ++j)
grid[i][j] = Z;
второй:
if (gridContent = X)
устанавливает gridContent
в X
(эта ошибка также происходит в другом if
с). Чтобы проверить на равенство, нужно использовать ==
вместо.
В третьих: Если вы действительно хотите понять, почему Y
отображался ранее, потому что условие в
if(gridContent = X)
оценивает false
, поскольку X
превращается в 0
, который затем присваивается gridContent
, Поэтому программа переходит в другой
if(gridContent = Y)
в котором он устанавливает gridContent
в Y
и поскольку последний не равен нулю, if
состояние оценивается в true
, Вы делаете это в цикле, поэтому вы в конечном итоге отображаете все элементы как Y
, Не совсем то, что вы хотели.
Лучшие практики
Один из способов избежать этих ошибок — собрать все предупреждения. Например, g++ -Wall -Wextra test.cpp
выплевывает
предупреждение: предложить круглые скобки вокруг присваивания, используемого в качестве значения истины [-Wparentheses]
if (gridContent = X)
и Clang ++ немного более полезен
предупреждение: использование результата присваивания в качестве условия
без скобок [-Wparentheses]
так что вы точно знаете, что что-то не так.
Другой подход заключается в том, чтобы всегда ставить Rvalue слева от теста на равенство, как
if(X == gridContent)
Вот X
это значение, и если по ошибке вы набираете =
вместо ==
то компилятор выдаст ошибку, такую как
ошибка: lvalue требуется как левый операнд присваивания
так как вы не можете присвоить значение.
Наконец, попробуйте использовать стандартные контейнеры вместо сырых массивов, например std::vector<>
.