---
# System prepended metadata

title: праки nti

---

правки nti
=====

> Добавить в api про Producer Consumer accumulator Receiver Transmitter
> `accumulator.failed`
`accumulator.charge`
`accumulator.capacity`
`accumulator.empty`
`accumulator.full`



> все данные есть library/monitor/challengemonitorruntime.cpp

> добавить в API аппарата или Редактирование сценария типа “Симуляция”:

Скрипт проверки очень схож со скриптами которые пишут в качестве решения.
Структура программы так-же состоит из setup() и loop(), и есть доступ ко всему API аппарата `spacecraft` и характеристикам аппарата, в независимости от наличия сенсоров.

`spacecraft.motion.angular_velocity`
`spacecraft.motion.position`
`spacecraft.motion.linear_velocity`
`spacecraft.motion.orientation`
`spacecraft.motion.location`

`spacecraft.thermodynamics.temperature`

`spacecraft.electrics.accumulator_charge`
`spacecraft.electrics.accumulator_capacity`
`spacecraft.electrics.power_production`
`spacecraft.electrics.power_consumption`
`spacecraft.electrics.power_balance`



Помимо этого есть объект `runtime` который имеет методы:

`add_score(name, amount)` добавляет турнирные баллы. 2 поля, первое - внутреннее уникальное имя части, второе, кол-во баллов для добавления

![](https://i.imgur.com/4Bhgzq7.png)

Подсказка: части следуют в порядке добавления. Для правильной номерации можно добавить 0 баллов в функции setup в нужном порядке

`add_log_entry(log)` добавляет строчку в лог, полезно при отладке или для отображения более полной картины

![](https://i.imgur.com/aBpmo9x.png)

`add_achievement(achievement)` добавляет достижение, они могут обозначать важные этапы решения задачи

![](https://i.imgur.com/2liXVhe.png)

## Примеры Скриптов

Проверяет стабилизацию в чекпоинтах
```
'use strict';

let first_checkpoint = false;
let second_checkpoint = false;

function radians(angle) {
    return angle * Math.PI / 180;
}

function setup() {
    runtime.add_score("default", 0.0);
    runtime.add_score("v", 0.0);
}
var end_speed = 0.2;
function loop() {
    let spacecraft = world.spacecrafts[0];

    if (!spacecraft.active) {
        return;
    }

    let flight_time = world.flight_time;

    // let angular_velocity = spacecraft.motion.angular_velocity;
    let angular_velocity = [spacecraft.devices[1].functions[0].angular_velocity,
                            spacecraft.devices[1].functions[1].angular_velocity,
                            spacecraft.devices[1].functions[2].angular_velocity];

    if (!first_checkpoint) {
        if (flight_time >= 660.0) {
            let maximum = Math.max(Math.abs(angular_velocity[0]),
                                   Math.abs(angular_velocity[1]));

            if (maximum <= radians(1.0)) {
                runtime.add_score("default", 1.0);

                if (maximum <= radians(0.1)) {
                    runtime.add_score("default", 1.0);

                    if (maximum <= radians(0.01)) {
                        runtime.add_score("default", 3.0);
                    }
                }
            }
            
            let vel_2 = Math.abs(angular_velocity[2] - end_speed);
            if (vel_2 <= radians(1.0)) {
                runtime.add_score("v", 2.0);

                if (vel_2 <= radians(0.1)) {
                    runtime.add_score("v", 2.0);

                    if (vel_2 <= radians(0.01)) {
                        runtime.add_score("v", 6.0);
                    }
                }
            }

            first_checkpoint = true;
        }
    }

    if (!second_checkpoint) {
        if (flight_time >= 3600.0) {
            let maximum = Math.max(Math.abs(angular_velocity[0]),
                                   Math.abs(angular_velocity[1]));

            if (maximum <= radians(1.0)) {
                runtime.add_score("default", 1.0);

                if (maximum <= radians(0.1)) {
                    runtime.add_score("default", 1.0);

                    if (maximum <= radians(0.01)) {
                        runtime.add_score("default", 3.0);
                    }
                }
            }

            let vel_2 = Math.abs(angular_velocity[2] - end_speed);
            if (vel_2 <= radians(1.0)) {
                runtime.add_score("v", 2.0);

                if (vel_2 <= radians(0.1)) {
                    runtime.add_score("v", 2.0);

                    if (vel_2 <= radians(0.01)) {
                        runtime.add_score("v", 6.0);
                    }
                }
            }

            second_checkpoint = true;
        }
    }
}

```

Работа с Producer, Consumer, Receiver, Transmitter
```
'use strict';

let MAX_HEIGHT = 3000000.0;

let PACKET_SIZE = 100;

let MAX_CHUNK_SIZE = Math.round(3600 * runtime.tick);

let PREAMBLE = [0xde, 0xad, 0xbe, 0xef];

let produced_storage = new Map();

let produced_index = -1;

let consumed_queue = [];

let score = 0.0;

function radians(angle) {
    return angle * Math.PI / 180;
}

function make_coords(latitude, longitude) {
    return {latitude: radians(latitude), longitude: radians(longitude)};
}

function calculate_elevation(station_location, spacecraft_location) {
    let height = spacecraft_location[2];
    let radius = world.environment.earth.radius;
    let coords_1 = make_coords(station_location[0], station_location[1]);
    let coords_2 = make_coords(spacecraft_location[0], spacecraft_location[1]);
    let cos_angle = Math.cos(coords_1.latitude) * Math.cos(coords_2.latitude);
    cos_angle *= Math.cos(coords_1.longitude - coords_2.longitude);
    cos_angle += Math.sin(coords_1.latitude) * Math.sin(coords_2.latitude);
    let sin_angle = Math.sqrt(1.0 - cos_angle * cos_angle);
    let x = radius * sin_angle;
    let y = radius * (1.0 - cos_angle) + height;
    return [Math.atan2(y, x) - Math.acos(cos_angle), Math.sqrt(x * x + y * y)];
}

function check_visibility(station_location, spacecraft_location) {
    let height = spacecraft_location[2];
    if (height > MAX_HEIGHT) {
        return false;
    }

    let elevation = calculate_elevation(station_location,spacecraft_location);
    if (elevation[0] < Math.PI / 9) {
        return false;
    }

    return true;
}

function setup() {
    runtime.add_score("default", 0.0);
}

function loop() {
    let produced_packet = null;

    let flight_time = world.flight_time;
    if (Math.floor(flight_time) > produced_index) {
        produced_index = Math.floor(flight_time);

        produced_packet = new Uint8Array(PACKET_SIZE);
        produced_packet.set(PREAMBLE, 0);
        produced_packet.set([(produced_index >> 0) & 0xff,
                             (produced_index >> 8) & 0xff,
                             (produced_index >> 16) & 0xff,
                             (produced_index >> 24) & 0xff], 4);
        produced_packet.set(runtime.random(92), 8);

        produced_storage.set(produced_index, Array.from(produced_packet));
    }

    let chunk_in_flight = null;

    let spacecraft = world.spacecrafts[0];
    if (spacecraft.active) {
        let producer = spacecraft.devices[1].functions[0];
        if (producer.active && (produced_packet !== null)) {
            producer.push_queue(0, produced_packet);
        }

        let transmitter = spacecraft.devices[0].functions[0];
        if (transmitter.active) {
            chunk_in_flight = transmitter.pull_queue(0, MAX_CHUNK_SIZE);
        }
    }

    if (chunk_in_flight !== null) {
        for (let i = 0; i < chunk_in_flight.length; i++) {
            let rolls = runtime.random(8);
            for (let j = 0; j < 8; j++) {
                if (rolls[j] < 3) {
                    chunk_in_flight[i] ^= 1 << j;
                }
            }
        }
    }

    let consumed_chunk = null;

    let station = world.stations[0];
    if (station.active) {
        let visible = false;
        if (spacecraft.active) {
            visible = check_visibility(station.motion.location,
                                       spacecraft.motion.location);
        }

        let receiver = station.devices[0].functions[0];
        if (receiver.active && visible && (chunk_in_flight !== null)) {
            receiver.push_queue(0, chunk_in_flight);
        }

        let consumer = station.devices[1].functions[0];
        if (consumer.active) {
            consumed_chunk = consumer.pull_queue(0, MAX_CHUNK_SIZE);
        }
    }

    if (consumed_chunk !== null) {
        consumed_queue.push(...consumed_chunk);
        while (consumed_queue.length >= PACKET_SIZE) {
            if ((consumed_queue[0] != PREAMBLE[0]) ||
                (consumed_queue[1] != PREAMBLE[1]) ||
                (consumed_queue[2] != PREAMBLE[2]) ||
                (consumed_queue[3] != PREAMBLE[3])) {
                consumed_queue.shift();
                continue;
            }

            let consumed_index = (consumed_queue[4] << 0) +
                                 (consumed_queue[5] << 8) +
                                 (consumed_queue[6] << 16) +
                                 (consumed_queue[7] << 24);
            if (!produced_storage.has(consumed_index)) {
                consumed_queue.splice(0, 4);
                continue;
            }

            let produced_content = produced_storage.get(consumed_index);
            let consumed_content = consumed_queue.slice(0, PACKET_SIZE);

            if (consumed_content.toString() != produced_content.toString()) {
                consumed_queue.splice(0, 4);
                continue;
            }

            score += 0.00048828125;
            if (score <= 30.0) {
                runtime.add_score("default", 0.00048828125);
            }

            produced_storage.delete(consumed_index);
            consumed_queue.splice(0, PACKET_SIZE);
        }
    }
}

```

