C ++ Получение соседей ячейки в сетке, -1x, выбрасывающий нулевое исключение при проверке, если! = NULL

HashMap<String, String> meMap=new HashMap<String, String>();
meMap.put("Color1","Red");
meMap.put("Color2","Blue");
meMap.put("Color3","Green");
meMap.put("Color4","White");
Iterator iterator = meMap.keySet().iterator();
while( iterator. hasNext() ){
    Toast.makeText(getBaseContext(), meMap.get(iterator.next().toString()), 
    Toast.LENGTH_SHORT).show();
}
1
задан Anthony 18 March 2019 в 23:59
поделиться

2 ответа

tiles[x][y+1], если y является максимальным допустимым значением, не будет NULL, кроме как по милости. Это выходит за пределы, и как только вы выходите за пределы, все ставки прекращаются. Вы вызвали неопределенное поведение , и почти все может произойти. Даже то, что вы ожидали.

То же самое относится к сообщенному месту крушения, tiles[x - 1][y - 1].

Правка: опущено решение. Не полезно.

Единственный способ, кроме взятия и сброса всего сайта с орбиты, состоит в том, чтобы проверить индекс, чтобы убедиться, что он не пробивает границы массива перед использованием индекса в массиве. Возможно, вам понадобится функция, чтобы справиться с этим.

void assign_if(Type & neighbour, int x, int y)
{
    if(x >= 0 && x < width && y >= 0 && y < height)
    neighbour = tiles[x][y];
}

и назовите его

assign_if(neighbours[0], x, y+1);

и позже

assign_if(neighbours[0], x-1, y-1);

Редактировать: украсть это у Боба для полноты

Невозможно вернуть сырой массив из функции. Массив выходит из области видимости и указатель на него становится недействительным. Либо передайте массив в качестве другого параметра, либо используйте std::array или std::vector , оба из которых могут быть возвращены. Благодаря Copy Elision умный компилятор, вероятно, уменьшит затраты на копирование.

Пример:

std::array<Tile::Type, 8> TileManager::GetNeighbours(int x, int y)
{
    std::array<Tile::Type, 8> neighbours;
    ...
    return neighbours;
}

Редактировать по оригинальному постеру. Вот мое решение:

std::array<Tile::Type, 8> TileManager::GetNeighbours(int c, int r)
{
    std::array<Tile::Type, 8> neighbours;

    const int y[] = { -1, -1, -1,  1, 1, 1,  0, 0 };// 8 shifts to neighbors
    const int x[] = { -1,  0,  1, -1, 0, 1, -1, 1 };// used in functions 

    for (int i = 0; i < 8; ++i)// visit the 8 spaces around it
        if (inField(r + y[i], c + x[i]))
            neighbours[i] = tiles[r + y[i]][c + x[i]];
        else
            neighbours[i] = Tile::Type::Void;

    return neighbours;
}

bool TileManager::inField(int r, int c)
{
    if (r < 0 || r >= 25) return false;
    if (c < 0 || c >= 25) return false;
    return true;
}

Редактировать: Caveat

Этот ответ напрямую связан с решением поставленной задачи. Смотрите ответ Kaz для описания более практичного решения, которое торгует немного памяти, чтобы полностью исключить необходимость тестирования и генерации массива neighbours.

0
ответ дан user4581301 18 March 2019 в 23:59
поделиться

Более «практичный» способ (более короткий код, который избегает условных проверок) - создать массив плиток, чтобы он содержал дополнительную «границу» плиток вокруг допустимой области. Если какая-либо позиция плитки находится в допустимой области, то она действительна и такова.

Вы можете иметь специальный тип для плиток границы, которые есть только у них, и просто включить эти плитки в список «соседей». Если в вашем мире есть стены, то граница может состоять из материала стен.

Излишне говорить, что вы никогда не должны запрашивать список соседей плитки границы. Это обеспечивается логикой, такой как недопущение того, чтобы плитка границы была допустимой позицией для чего-либо.

Эта плитка находится в допустимой области внутри границы "- это условие, которое легче проверить, в меньшем количестве мест, и ваша программа может быть структурирована так, что эта проверка на самом деле является просто съемным утверждением (проверка для ситуация, которая не должна возникать, если программа правильная, а не проверка на ожидаемую ситуацию).

В C и C ++ мы можем сместить указатели так, чтобы позиция [0][0] оставалась углом допустимая область, но координаты за пределами [-1][-1] являются действительными индексами, как и [w][h].

Во-первых, массив столбцов выделяется на два элемента больше, чем необходимо, и указатель увеличивается на 1. Затем столбцам выделяется на два элемента больше, и каждый указатель увеличивается на единицу перед назначением в основной массив.

При освобождении массивов с помощью delete [] необходимо помнить, чтобы уменьшить каждый указатель на один.

0
ответ дан Kaz 18 March 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: