Как стать автором
Обновить

Теория квантовых состояний: из жизни в код

Время на прочтение5 мин
Количество просмотров2.9K

Привет, ребята!

Расскажу вам о моём вИдении правильного программирования любых систем.

Кратко о себе: программист самоучка, примерно с 1992 года, начинал с ассемблера, крякая через HIEW (Огромное СПАСИБО автору этого замечательного дизассемблера) всякие DOS-игрухи-проги, и прогая всё, что в голову взбредёт - от игр до вирей (домашних и добрых).

*Фотку взял с wiki
*Фотку взял с wiki

И, понятное дело, я жёстко помешан на производительности / скорости выполнения программ, особенно учитывая тот факт, что первый комп у меня - ИСКРА-1030М (CPU 8086 / HDD 10 MB / FDD 5.25 / RAM 1 MB / CGA / DOS 6.22), примерно как на фото.

К написанию статьи подтолкнул пост о циклических переборах в играх для определения видимости других игроков.

В комментарии к нему, я отметил изначально "тяжёлый" подход, который перебирал значения координат всех игроков на карте, хоть и каталогизируя их с помощью какой-то
R*-tree - штуковины.

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

На примере данной задачи, постараюсь объяснить Вам, как я использую свою "Теорию квантовых состояний".

Такое название я решил использовать в своих мыслях, то есть в общении с самим собой, не найдя иного подходящего названия в интернете.
Вы тоже, читатели, можете использовать это словосочетание в обиходе :)

Идея состоит в осознании того факта, что всё в мире есть глобальная статика, имеющая своё постоянно изменяющееся внутреннее состояние. Некая модульность, состоящая то из планет, то из людей, то из квантов.

Проплывающую мимо Земли планету / звезду / Луну / спутник, мы воспринимаем как целый статичный объект, вИдя его своими глазами с поверхности Земли, хотя внутри этого объекта постоянно происходят изменения на разных уровнях восприятия сенсорными системами различных систем анализа / диагностики / наблюдения, многие из которых недоступны для восприятия человеческим глазом на большом расстоянии без вспомогательных механизмов.

Проходящий мимо нас человек или проезжающий автомобиль воспринимаются нами как статичные объекты, внутри которых постоянно происходят изменения, такие как движения жидкостей внутри сосудов/патрубков, молекул, атомов, электронов, квантов и т.п.

Таким образом, всё во вселенной представлено относительно статичными макро-объектами по отношению к сторонним наблюдателям соответствующего макро-масштаба, с учётом расстояния удалённости и технического оснащения систем восприятия у этих наблюдателей.

И, в то же время, эти объекты состоят из микро-объектов изменяющих своё состояние для одних наблюдателей, оставаясь неизменными для других.

Быть может игра слов в моём тексте окажется сложной для восприятия кому-либо из читателей, но я именно так понимаю эту предметную область в рамках моего прежнего жизненного опыта, как излагаю.

Предположим теперь, что все модули в правильном (по моему мнению) программном коде, живут своей жизньюимея исключительно и только своё изменяющееся состояниестатус которого доступен для внешних наблюдателей через API-интерфейс, в виде, например, передачи параметров в функцию, то есть через механизм вроде телескопа для человеческого глаза, для наблюдения завихрений в кольцах Сатурна (я слабоват в астрономии, если что, могу ошибаться, но смысл должен быть понятен).

Вероятно, что кто-то из читателей готов отметить существование таких ассоциаций, как объектно-ориентированное программирование, классы, структуры и т.п., и что моё заумное название моего супер-заумного подхода является обычным и давно известным фактом, с чем я изначально соглашаюсь, но с оговоркой: это всё механизмы реализации, а моя задача - настроить читателя на понимание того, как воспринимать архитектуру предстоящего строительства чего-либо: в контексте данной истории - программных продуктов.

Таким образом, вместо переборки в цикле координат всех игроков, для сопоставления с областью видимости каждого наблюдателя, я предпочитаю применить свою "Теорию квантовых состояний": пусть игрок, положение которого меняются в рамках систем координат игрового мира, будет являться частью элемента карты которая и так прорисовывается, независимо от необходимости трассировки игроков от наблюдателя.

То есть:
смена координат игрока - это внутренние изменения объекта, в то время как для наблюдателя - это статичный объект, в рамках одного прорисованного кадра.

Реализация

Допустим, что 2D-карта игрового мира, имеет размерность 100 * 100 клеток, где на описание каждой из которых, отводится один байт, со значением от 0 (пустая клетка) до 255, что является восемью битами данных.

Вариантов текстур = 15 штук, значения от 1 до 15,
если указан 0 (ноль), то нет текстуры для прорисовки.
Расход на всё = 4 бита.

Количество одновременных игроков = 15, значения ID от 1 до 15,
если указан 0 (ноль), то на этой клетке карты нет игрока для прорисовки.
Расход на всё = 4 бита.

Итого: мы получаем 8 бит = 1 байт, в котором содержатся тип текстуры + ID игрока, доступные для рендера в этих координатах.

Здесь я не углубляюсь в рассмотрение варианта когда несколько игроков находятся в одинаковых координатах — этот момент легко масштабируется простейшим добавлением соответствующих данных.

Код на Golang, без проверки на граничные значения и т.п.:

var (
// Слепок карты
gameMap = [100 * 100]byte

// ID игрока
playerID byte

// ID текстуры
textureID byte

// Итоговый байт для клетки карты
readyCell byte

// Координаты игрока и клетки, для наглядности этого примера
x, y int = 5, 7

// Смещение на клетку в массиве карты
mapOffset int                                    
)

func f () {
// Задаём ID игрока: playerID = 3 = 0000 0011
playerID = 3

// Указываем ID текстуры:  textureID = 4 = 0000 0100
textureID = 4

// Начинаем собирать итоговый байт: readyCell = 3 = 0000 0011
readyCell = playerID

// Сдвигаем ID игрока в 4 верхних бита: readyCell = 48 = 0011 0000
readyCell <<= 4

// Помещаем значение текстуры в итоговый байт: readyCell = 52 = 0011 0100
readyCell |= textureID

// Вычисляем клетку для вставки итогового значения,
// здесь 100 = размерность карты по координате х, от 0 до 99
mapOffset = x * 100 + y

// Помещаем итоговое значение в нужную ячейку
gameMap[mapOffset] = readyCell

// Здесь условная "бизнес-нагрузка"
....

// Прорисовка итоговой картинки в Z-буффер
renderFuncZ()
}

А теперь представьте, насколько мощнее окажется такое решение задачи если мы добавим вторую карту, где по схожим координатам будет указан номер спрайта изображения прорисовываемого игрока, означающий, например, положения бега / взмаха рукой / уровень здоровья и прочие состояния объекта!

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

Сейчас я готовлю к релизу язык программирования, который конструирую согласно "Теории квантовых состояний".

Будет здОрово, если кому-то поможет этот пост на практике, став частью эволюции инженерии!

P.S.: Ответить на коммент получается только один раз в день. Если что срочно нужно подсказать, пишите в л.с, пожалуйста.

Сергей Попов (Socket Language)

Теги:
Хабы:
Всего голосов 28: ↑13 и ↓15-2
Комментарии4

Публикации

Истории

Работа

Go разработчик
125 вакансий
Data Scientist
60 вакансий

Ближайшие события