Я думаю, вам нужно 2 массива.
Один содержит позиции всех свободных пикселей, а другой - карта свободных пикселей будет содержать расположение каждого пикселя в массиве свободных пикселей, если он свободен.
Всякий раз, когда вы занимает новый пиксель , вы удаляете его из массива свободных пикселей. Если это был последний элемент, вы просто уменьшаете счетчик для свободных пикселей. Если это не последний пиксель массива свободных пикселей, вы «поменяете» его последним пикселем свободного массива первым.
Поскольку массив свободных пикселей и карта свободных пикселей связаны друг с другом, занятие нового пикселя занимает только O (1) обновлений структур; То же самое относится и к моменту освобождения пикселя.
Теперь выбрать произвольный свободный пиксель для еды действительно просто, это операция O (1) - просто выберите число от 0
до n_free_pixels - 1
и выберите ith
пиксель из массива свободных пикселей.
Для этого подхода вам потребуется около 4-8 байт дополнительной памяти на пиксель; если, скажем, 320x200 достаточно, то 4 байта на пиксель для 256k (у обоих массивов будут шорты без знака). НО, если вы положите еду в сетку и посчитаете, что положение сетки непригодно, если змея занимает какую-либо ее часть, тогда вы можете получить намного меньше.
Рассмотрим карту 2х2 для простоты. В начале все пиксели свободны, поэтому содержимое карты будет
Free pixel map Free pixel list
+-----+-----+
|0 |1 | | 0 | 1 | 2 | 3
| 0 | 1 |
| | |
+-----+-----+ n_free = 4
|2 |3 |
| 2 | 3 |
| | |
+-----+-----+
Затем вы хотите выбрать один пиксель, который должен занимать, и выбрать число от 0 до n_free - 1. В этом случае 1. Теперь вы берете позицию пикселя из списка свободных пикселей по индексу 1 (который также равен 1). ..
Free pixel map Free pixel list
+-----+-----+
|0 |1 | | 0 | 1 | 2 | 3
| 0 | 1 | ^
| | |
+-----+-----+ n_free = 4
|2 |3 |
| 2 | 3 |
| | |
+-----+-----+
Мы помечаем этот пиксель как зарезервированный на карте свободных пикселей
Free pixel map Free pixel list
+-----+-----+
|0 |1 | | 0 | 1 | 2 | 3
| 0 | # |
| | |
+-----+-----+ n_free = 4
|2 |3 |
| 2 | 3 |
| | |
+-----+-----+
Поскольку позиция в свободном списке была не последней, мы поменяемся местами
последний элемент (пиксель 3) в эту позицию, и обновите свободную карту, чтобы указывать на этот индекс, и, наконец, уменьшить n_free
на единицу:
Free pixel map Free pixel list
+-----+-----+
|0 |1 | | 0 | 3 | 2
| 0 | # | ^
| | |
+-----+-----+ n_free = 3
|2 |3 |
| 2 | 1 |
| | ^ |
+-----+-----+
Если пиксель 1
впоследствии высвобождается , мы можем добавить его в позицию n_free
свободного списка и изменить карту так, чтобы она указывала на этот элемент, и, наконец, увеличить n_free
; новое состояние будет
Free pixel map Free pixel list
+-----+-----+
|0 |1 | | 0 | 3 | 2 | 1
| 0 | 3 | ^
| | |
+-----+-----+ n_free = 4
|2 |3 |
| 2 | 1 |
| | |
+-----+-----+