---
metadata:
  - name: generator
    content: Diplodoc Platform v5.48.2
alternate:
  - https://admin.contest.yandex.ru/docs/en/examples/interactive.md
  - https://admin.contest.yandex.ru/docs/ru/examples/interactive.md
---
> **Documentation Index:** Fetch the complete configuration index at https://admin.contest.yandex.ru/docs/ru/llms.txt

# Создать интерактивную задачу

В рамках интерактивной задачи участнику нужно реализовать код, который будет взаимодействовать с определенной программой (интерактором), и на основе данных от интерактора решить поставленную задачу.

Примеры таких задач: игра в шахматы или шашки, игра в крестики-нолики, игра <q>больше-меньше</q>.

<!-- source: ru/_includes/reusables/id-reusables/problem-set.md -->
Вы можете добавлять готовые наборы задач в соревнование. Подробнее см. в разделе [Настройки набора задач](https://admin.contest.yandex.ru/docs/ru/problem-set/settings.md#set-operations).
<!-- endsource: ru/_includes/reusables/id-reusables/problem-set.md -->

## 1. Создайте задачу {#create-task}

1. На вкладке [Задачи](https://admin.contest.yandex.ru/problems/) нажмите кнопку **Создать задачу**.
2. Придумайте название. Оно будет отображаться в интерфейсе участника.
3. Нажмите **Создать**. Откроется страница настроек задачи.
4. Для более быстрого поиска задачи вы можете указать короткое название&nbsp;— оно не отображается для участников.
5. Вы можете добавить перевод полного названия на английском языке.
6. В поле **Тип задачи** выберите `INTERACTIVE_PROBLEM`.
7. Настройте основные параметры таким же образом, как при настройке [задачи на программирование](https://admin.contest.yandex.ru/docs/ru/examples/programming.md).
8. В разделе **Настройки интерактора** выберите **Тип интерактора**: `TESTLIB_EXITCODE` или `EJUDGE_EXITCODE`. Эта настройка определяет, какие `exitcode` к какому вердикту посылки приводят. Поведение системы при различных `exitcode` аналогично чекерам.

## 2. Добавьте интерактор {#add-interactor}

Воспользуйтесь одним из вариантов:

{% list tabs %}

- Скомпилировать интерактор

    Когда есть исходный файл интерактора, и его необходимо скомпилировать, нажмите кнопку **Скомпилировать интерактор**. В открывшемся модальном окне необходимо выполнить следующие шаги:

    1. Выберите файл исходного кода из файлов задачи или загрузите его с устройства.
    2. Выберите **Компилятор**.
    3. Выберите тип интерактора: **TESTLIB_EXITCODE** или **EJUDGE_EXITCODE**.

    После выбора всех параметров нажмите кнопку **Компилировать**. Дождитесь завершения процесса компиляции.

    **Если компиляция завершилась с ошибкой**, то никакие настройки задачи не изменяются.

    **Если компиляция прошла успешно**, то автоматически устанавливаются следующие параметры:

    - **Тип интерактора** — устанавливается выбранный в модальном окне тип.
    - **Окружение** — устанавливается выбранное значение из поля **Компилятор**.
    - В разделе **Файлы интерактора** появляется скомпилированный исполняемый файл.

- Загрузить скомпилированный файл интерактора

    Если вместо исходников интерактора есть готовый исполняемый файл, или интерактор не требует компиляции (например, для языка Python), то выполните следующие шаги:

    1. В поле **Тип интерактора** выберите соответствующий тип: **TESTLIB_EXITCODE** или **EJUDGE_EXITCODE**.
    2. В поле **Окружение** выберите подходящий компилятор.
    3. В разделе **Файлы интерактора** добавьте необходимые файлы:
        - Первым добавьте исполняемый файл интерактора.
        - При необходимости добавьте дополнительные файлы, необходимые для работы интерактора.
    4. Нажмите кнопку **Сохранить** в правом нижнем углу.

{% endlist %}

#### Взаимодействие интерактора с файлом теста

В интерактивной задаче интерактор имеет доступ к файлу теста (например, `tests/01`). Название файла передается в первом аргументе запуска интерактора.

#### Взаимодействие интерактора с решением участника

Через потоки **stdin** и **stdout** интерактор взаимодействует с решением участника:
    
- вывод интерактора в **stdout** передается в **stdin** (`input.txt`) решения участника;
- вывод решения участника, отправленный в **stdout** (или `output.txt`), попадает на **stdin** интерактора.
    
Решение участника взаимодействует со стандартными потоками ввода и вывода (и/или с файлами `input.txt` и `output.txt` в зависимости от настроек задачи, так же как в [задаче на программирование](https://admin.contest.yandex.ru/docs/ru/examples/programming.md)).
    
Начинать взаимодействие между интерактором и решением участника может как интерактор, так и решение участника.
    
Завершение работы интерактора и решения участника должно происходить синхронизированно. Обе программы должны ожидать данные на потоке ввода до выполнения определенных условий и затем завершать выполнение по управляющему сигналу от одной из программ. Например, возможны такие варианты:
    
- интерактор специальной командой сообщает решению участника, что решение пришло к заключительному результату;
- решение участника самостоятельно <q>понимает</q>, что задача решена, и после отправки заключительного результата (сообщения в интерактор) завершает свое выполнение.

#### Взаимодействие интерактора с чекером

Интерактор взаимодействует с чекером посредством файла, передаваемого во втором аргументе при запуске интерактора. После завершения работы интерактора и решения участника чекер будет читать значение, записанное в этот файл, и проверять его на соответствие файлу ответа (например, `tests/01.a`).
    
Подробнее о работе [чекера](https://admin.contest.yandex.ru/docs/ru/problem/checkers.md).

## Пример. Задача <q>Угадайка</q> {#example-task}

Задача: определить загаданное число в ограниченном числовом интервале, используя количество попыток меньше определенного.

Решение участника должно предлагать число интерактору и получать от него ответ (`less`/`more`/`success` в зависимости от того, угадала программа загаданное число или предложила большее или меньшее значение). Интерактор будет считать количество попыток и передавать его чекеру перед завершением работы.

Интерактор реализован для `exitcode` типа `TESTLIB_EXITCODE`.

Тестовые данные для примера:

- `tests/01` содержит загаданное число&nbsp;— 15;
- `tests/01.a` содержит максимально допустимое количество попыток&nbsp;— 50.


{% note warning %}

Файл чекера должен содержать переносы строк только вида ``\n`` (<q>Unix-переносы</q>). Если переносы будут другого вида (например, `\r\n`&nbsp;— <q>Windows-переносы</q>), система не сможет запустить файл.

{% endnote %}

{% cut "Пример кода интерактора" %}


```python
#!/usr/local/bin/python3.7
import sys

class Verdict:
    OK = 0
    WA = 1
    PE = 2
    FAIL = 10

def calculate(attempt, answer):
    if attempt < answer:
        result = 'more'
    elif attempt > answer:
        result = 'less'
    else:
        result = 'success'

    return result

try:
    with open(sys.argv[1], "r") as input_file:
        answer = input_file.readline().strip()

    with open(sys.argv[2], "w") as output_file:
        tries = 0

        while True:
            tries += 1

            try:
                attempt = input().strip()
            except EOFError:
                print("EOF from participant", file=sys.stderr)
                sys.exit(Verdict.PE)

            if not attempt.isdigit():
                print("Invalid attempt: %s" % attempt, file=sys.stderr)
                sys.exit(Verdict.PE)

            result = calculate(attempt, answer)

            print(result, flush=True)
        
            if result == 'success':
                print(tries, file=output_file)

                print("Found number: %s" % attempt, file=sys.stderr)
                sys.exit(Verdict.OK)
except Exception:
    sys.exit(Verdict.FAIL)
```


{% endcut %}

{% cut "Код чекера" %}


```python
#!/usr/local/bin/python3.7
import sys

class Verdict:
    OK = 0
    WA = 1
    PE = 2
    FAIL = 10

try:
    with open(sys.argv[2], "r") as output_file:
        tries = int(output_file.read())

    with open(sys.argv[3], "r") as answer_file:
        max_tries = int(answer_file.read())

    if tries > max_tries:
        print("Limit exceeded: used %s attempts, max = %s" % (tries, max_tries), file=sys.stderr)
        sys.exit(Verdict.WA)

    print("Used %s attempts of %s" % (tries, max_tries), file=sys.stderr)
    sys.exit(Verdict.OK)
except Exception:
    sys.exit(Verdict.FAIL)
```


{% endcut %}

{% cut "Пример решения участника" %}


```python
import random
import sys

max = 100
min = 0

while True:
    attemptNumber = int((max - min) / 2) + min

    print(attemptNumber, flush=True)

    readInput = input()

    if readInput == 'less':
        max = attemptNumber
    elif readInput == 'more':
        min = attemptNumber
    else:
        sys.exit(0)
```


{% endcut %}

{% cut "Пример решения участника на JavaScript" %}


```javascript
let max = 100;
let min = 0;

let attemptNumber = parseInt((max - min) / 2);

console.log(attemptNumber);

nextInt = (response) => {
    if (response.indexOf('less') > -1) {
        max = attemptNumber     
    } else if (response.indexOf('more') > -1) {
        min = attemptNumber;
    } else {
        process.exit(0);
    }
    attemptNumber = parseInt((max - min) / 2 + min);

    return attemptNumber;
};

process.stdin.on('data', response => {
    attemptResponse = response.toString();
    attempt = nextInt(attemptResponse);
    console.log(attempt);
});
```


{% endcut %}



<!-- source: ru/_includes/reusables/support-button.md -->
<a href="../../troubleshooting">
  <span class="button">Написать в службу поддержки</span>
</a>



<!-- endsource: ru/_includes/reusables/support-button.md -->

