50 | љ | TODOљ |
љ | 50 | В симуляции используется один вспомогательный класс, Vector, упрощающий работу с углами. Его методы:љ |
љ | 51 | a. `initialize(x=0, y=0)`, создает радиус-вектор с координатами `x`, `y`.љ |
љ | 52 | a. `is_null()`, возвращает `True`, если данный вектор -- нулевой.љ |
љ | 53 | a. `rotation()`, возвращает угол, на который повернут вектор относительно оси Ox против часовой стрелке, в радианах. (То же самое, что угол в тригонометрической окружности). При попытке получить поворот нулевого вектора возбуждается исключение.љ |
љ | 54 | a. `length()`, возвращает длину вектора.љ |
љ | 55 | a. `set_rotation(angle)`, возвращает новый вектор, для которого `rotation()` возвратит `angle`. Например, `vector.set_rotation(0)` возвращает вектор, лежащий на оси Ox.љ |
љ | 56 | a. `set_length(length)`, возвращает новый вектор длины `length`, коллинеарный данному. При передаче отрицательной длины возвращается противоположно направленный вектор, по модулю равный `-length`.љ |
љ | 57 | a. `change_rotation(angle)`, то же самое, что `vector.set_rotation(vector.rotation() + angle)`.љ |
љ | 58 | a. `change_length(length)`, то же самое, что `vector.set_length(vector.length() + length)`.љ |
љ | 59 | љ |
љ | 60 | Код, управляющий танком (контроллер) представляет из себя класс, наследуемый от класса `TankController`. В случае программного управления этот класс определяется явно и отдельно для каждого ИИ, а в случае ручного используется один и тот же подкласс, определенный изначально и связанный с органами управления.љ |
љ | 61 | љ |
љ | 62 | Когда в симуляции происходит какое-то событие, она вызывает соответствующий метод контроллера, который и должен обработать это событие.љ |
љ | 63 | љ |
љ | 64 | === Шаг симуляции: событие on_tick ===љ |
љ | 65 | љ |
љ | 66 | Унаследованный класс должен определить как минимум один метод, который является главным для процесса управления -- метод {{on_tick(tank, other_tanks, bullets)}}. Этот метод будет регулярно вызываться симуляцией, и каждый раз в него будут передаваться аргументы, содержащие снимок той информации, которая была доступна танку на момент начала шага симуляции.љ |
љ | 67 | љ |
љ | 68 | 1. `tank`: объект класса `Tank`, описывающий собственно танк, к которому относится этот контроллер.љ |
љ | 69 | Его свойства:љ |
љ | 70 | a. `strength`: Integer, текущий запас прочности танка.љ |
љ | 71 | a. `position`: Vector, положение танка в мире.љ |
љ | 72 | a. `velocity`: Vector, скорость и направление движения танка.љ |
љ | 73 | a. `base_rotation`: Integer, угол поворота платформы относительно мировой системы отсчета. При движении танка вперед совпадает с `velocity.rotation()`; иначе эти два числа отличаются на ?.љ |
љ | 74 | a. `turret_rotation`: Integer, угол поворота башни относительно платформы.љ |
љ | 75 | Его методы, управляющие поведением:љ |
љ | 76 | a. `rotate_base(angle)`: поворачивает платформу танка. Перед расчетами `angle` сравнивается по модулю с максимальной скоростью поворота и, если необходимо, уменьшается до нее.љ |
љ | 77 | a. `rotate_turret(angle)`: поворачивает башню танка относительно платформы. Параметр `angle` обрабатывается аналогично методу `rotate_base`.љ |
љ | 78 | a. `accelerate(speed_delta)`: изменяет скорость танка. Перед всеми расчетами `speed_delta` сравнивается по модулю с максимальным ускорением и, если необходимо, уменьшается. Если параметр `speed_delta` превышает по модулю скорость и имеет противоположный знак (например, `speed_delta` = 10, а танк движется назад со скоростью 5), то скорость будет уменьшена до нуля.љ |
љ | 79 | a. `fire()`: производит выстрел.љ |
љ | 80 | 1. `other_tanks`: массив объектов `TankSnapshot`, унаследованных от `ObjectSnapshot`; содержит информацию о всех видимых танках.љ |
љ | 81 | Свойства базового класса `ObjectSnapshot`:љ |
љ | 82 | a. `handle`: идентификатор объекта, не имеющий смысла для контроллера. Гарантируется, что пока объект не выйдет из области видимости, его идентификатор не изменится.љ |
љ | 83 | a. `position`: Vector, положение объекта в мире.љ |
љ | 84 | a. `velocity`: Vector, скорость и направление движения объекта.љ |
љ | 85 | Свойства класса `TankSnapshot`:љ |
љ | 86 | a. `strength`: Integer, текущий запас прочности танка.љ |
љ | 87 | 2. `bullets`: массив объектов `BulletSnapshot`, унаследованных от `ObjectSnapshot`; содержит информацию о видимых пулях.љ |
љ | 88 | љ |
љ | 89 | === Рождение и смерть: события on_spawn и on_death ===љ |
љ | 90 | љ |
љ | 91 | Симуляция может проходить в несколько этапов (раундов), при этом у контроллера должна быть возможность адаптироваться к конкретному набору противников, поэтому в случае такого проведения симуляции контроллер будет создан перед началом первого этапа и уничтожен после окончания последнего. Для того, чтобы контроллер мог определить границы этапа, в начале этапа будет вызван его метод `on_spawn()`, а в конце -- `on_death()`. Все остальные обработчики событий будут вызываться только между этими двумя.љ |
љ | 92 | љ |
љ | 93 | === Повреждение: событие on_hit ===љ |
љ | 94 | љ |
љ | 95 | При попадании снаряда в танк уменьшается его прочность и после этого вызывается обработчик события `on_hit(bullet)`. Этот метод будет вызван перед началом следующего шага симуляции и, соответственно, до вызова метода `on_tick`.љ |
љ | 96 | љ |
љ | 97 | Параметр `bullet` является объектом класса `BulletSnapshot`, с семантикой, соответствующей описанной для события `on_tick`; в т.ч. если этот снаряд был видимым для танка до удара, то его свойство `handle` будет соответствовать полученному в событии `on_tick`.љ |
љ | 98 | љ |
љ | 99 | Если это повреждение оказалось для танка фатальным, то вместо метода `on_tick` на этом шаге будет вызван метод `on_death`.љ |
љ | 100 | љ |
љ | 101 | === Столкновение: событие on_collision ===љ |
љ | 102 | љ |
љ | 103 | При столкновении с другим танком (как описано в условиях симуляции) для того танка, скорость которого была уменьшена, будет вызван обработчик события `on_collision(tank)`; параметр `tank` является объектом класса `TankSnapshot`, аналогично параметру `bullet` для события `on_hit`.љ |