Страницы

Поиск по вопросам

суббота, 27 апреля 2019 г.

System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта

Всем привет. Пишу игру "Сапёр", работающую из окна консоли. Возникает ошибка на участке кода:
field = new cell[ySize][]; for (int i = 0; i // расставим мины do { int row= rnd.Next(ySize); //координата мины по Y int col=rnd.Next(xSize); //координата мины по X
if (field[row][col].cheсkNearCell()!= (-1)) { field[row][col].setMine();
if (row != 0 && col != 0) field[row - 1][col - 1].newMineNear(); if (row != 0) field[row - 1][col].newMineNear(); if (row != 0 && col != xSize - 1) field[row-1][col + 1].newMineNear(); if (col != 0) field[row][col - 1].newMineNear(); if (col != xSize - 1) field[row][col + 1].newMineNear(); if (row != ySize - 1 && col != 0) field[row + 1][col-1].newMineNear(); if (row != ySize - 1) field[row + 1][col].newMineNear(); if ((row != ySize-1) && (col != xSize-1)) field[row + 1][col + 1].newMineNear(); n++; } } while (n != numberOfMines);
В этом участке кода должен заполняться массив, содержащий "клеточки" из которых состоит поле, и расставляются мины. Код компилируется, игра запускается, но выдаёт ошибку
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
Я подозреваю, что при заполнении массива массивов не вызывается конструктор класса. Вот код класса Cell:
class cell { private bool opend {get; set;} // - посещали ли мы клеточке private bool hasMine {get; set;} // - установлена ли в клеточке мина private bool hasFlag {get; set;} // - установлен ли в клеточке флаг private int minesNear {get; set;} // - мины рядом
private cell() { hasMine=false; opend=false; hasFlag=false; minesNear=0; }
//установить флаг public int setFlag() { if (hasMine==true) {hasFlag=true; return 1;} //1 - мина установлена успешно else return 0; }
//установка мины public void setMine() { hasMine=true; }
//добавление информации о мине поблизости public void newMineNear() { minesNear++; }
//проверка этой клетки на наличие мины public int checkThisCell() { if(hasMine==true) return 666; // 666 - означает наличие мины в данной клетке else if (opend==false) {opend=true; return minesNear;} else return -1; //-1 - означает что мы посещали эту клетку и нужно выбрать другую клетку }
//проверка соседней клетки на наличие мины public int cheсkNearCell() { if (hasMine==true || opend==true) return -1; // -1 - что нужно игнорировать эту клетку else return minesNear; }
//отрисовка клетки public void show() { if (hasFlag==true) Console.Write("F"); // - в клетке установлен флаг else if (opend==false) Console.Write("#"); // - клетка не открывалась ранее else if (minesNear==0) Console.Write(" "); // - рядом нет мин else Console.Write(minesNear); // - есть определённое количество мин } }


Ответ

Ответ @Surfin Bird верный, давайте я объясню, что происходит.
Вы объявили массив массивов. Для массива нужно выделять память при помощи new, но элементами вашего массива являются одномерные массивы! Под каждый из них тоже нужно выделять память. Получится такая картинка:
field ---> [ элемент 0 ][ элемент 1 ][ элемент 2 ][ элемент 3 ]... | | | | | | | | V V V V [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
Вы создали верхнюю строку, но не остальные.

Альтернативным решением могло быть выделение прямоугольного многомерного массива. В этом случае вы получаете сразу нужные элементы:
Cell[,] field; // ... field = new Cell[xSize][ySize];

Комментариев нет:

Отправить комментарий