Русский
Интеграции
Powered By GitBook
Примеры задания ограничений
Задание ограничений — уникальная возможность TRIK Studio, предназначенная для автоматизированной проверки заданий. Этот инструмент имеет множество применений:
    самопроверка домашнего задания учениками,
    ускорение процесса проверки заданий учителем,
    проведение онлайн-соревнований с автоматической проверкой решений участников.
Язык ограничений в TRIK Studio — очень мощный инструмент, который позволяет проверить практически все аспекты выполнения программы и поведения робота, и может показаться сложным на первый взгляд. Однако не стоит расстраиваться — в данной статье мы разберем процесс создания задач с ограничениями, начиная от простых ограничений, которые покрывают большинство задач, и заканчивая сложными ограничениями, что может быть полезно для энтузиастов.

Ограничения на время исполнения программы и на зоны «Старт» и «Финиш»

Для тех, кто только начинает знакомиться с языком создания ограничений в TRIK Studio, мы предлагаем начать с простых ограничений на время исполнения программы, зону «Старт» и «Финиш». Для большинства робототехнических задач этого более чем достаточно.
1. Определите для задачи и модели мира следующие условия и параметры.
    Оптимальное время выполнения программы. Если программа будет выполняться больше этого времени, проверяющая система выдаст ошибку «Программа работала слишком долго».
    Зона «Старт». Зона, из которой робот должен начать выполнение программы, иначе проверяющая система выдаст ошибку.
    Зона «Финиш». Зона, в которую должен приехать робот по окончании выполнения программы, иначе проверяющая система выдаст ошибку.
2. Отредактируйте в xml-файле мира значение тега <regions>, добавив туда зоны «Старт» и «Финиш». Меняя значения x, y, width и height , вы можете редактировать местоположение и размер зон. Чтобы проверить положение зоны, загрузите файл в виртуальную модель мира и проверьте расположение зон. После этого, при необходимости, вы можете сделать зоны «Старт» и «Финиш» невидимыми, выставив атрибут visible="false".
1
<regions>
2
<region type="rectangle" visible="true" color="blue" text="Старт" x="-450" y="-400" width="150" height="150" id="start_zone"/>
3
<region type="rectangle" visible="true" color="green" text="Финиш" x="450" y="-400" width="150" height="150" id="finish_zone"/>
4
</regions>
Copied!
3. Скопируйте в xml-файл мира, для которого необходимы ограничения, шаблон блока <constraints>, приведенный ниже.
1
<constraints>
2
<!-- Ограничение на время выполнения программы -->
3
<timelimit value="300000"/>
4
5
<!-- Ограничение, которое проверится один раз перед началом программы -->
6
<constraint checkOnce="true" failMessage="Робот должен находиться в зоне старта перед запуском!">
7
<inside objectId="robot1" regionId="start_zone"/>
8
</constraint>
9
10
<!-- Событие, которое проверяет, что робот находится в зоне финиша по окончании выполнения программы -->
11
<event id="finish checker" settedUpInitially="true">
12
<condition>
13
<inside objectId="robot1" regionId="finish_zone"/>
14
</condition>
15
<trigger>
16
<success/>
17
</trigger>
18
</event>
19
</constraints>
Copied!
4. Заполните тег <timelimit value="300000">. Укажите оптимальное, на ваш взгляд, время выполнения программы. Обратите внимание, что время указывается в миллисекундах, т.е. 300000 мс = 5 минут, 120000 мс = 2 минуты и т.п.
5. Задание с ограничениями готово! Теперь вы умеете проверять стартовое и конечное положение робота, время исполнения программы.

Разбор примеров

Теперь давайте разберем применение данной техники для различных задач и рассмотрим варианты более детальных проверок.

Пример 1. Проезд из зоны «Старт» в зону «Финиш» с ограничением на зону для перемещений

Задача прохождения лабиринта. Стартовав в синем квадрате, необходимо проехать до зоны финиша. Для того чтобы проверять, что пользователь действительно проходит лабиринт, а не объезжает его, задано пространственное ограничение.
Синий квадрат - зона старта, красный квадрат - зона финиша, черный прямоугольник - поле, которое нельзя покидать роботу
Ниже приведен полный код для проверки этой задачи.
1
<?xml version='1.0' encoding='utf-8'?>
2
<root>
3
<!-- Описание мира -->
4
<world>
5
<trace/>
6
<walls>
7
<wall end="450:-400" id="" begin="-300:-400"/>
8
<wall end="-300:200" id="" begin="-300:-250"/>
9
<wall end="450:200" id="" begin="-300:200"/>
10
<wall end="450:200" id="" begin="450:-250"/>
11
<wall end="150:-100" id="" begin="150:-400"/>
12
<wall end="300:50" id="" begin="300:-250"/>
13
<wall end="450:-250" id="" begin="300:-250"/>
14
<wall end="-150:-250" id="" begin="-300:-250"/>
15
<wall end="0:-250" id="" begin="-150:-250"/>
16
<wall end="-150:-100" id="" begin="150:-100"/>
17
<wall end="150:50" id="" begin="-150:50"/>
18
<wall end="150:200" id="" begin="150:50"/>
19
</walls>
20
<colorFields/>
21
<!-- Задание регионов (зон) на карте мира -->
22
<regions>
23
<region type="rectangle" visible="true" color="blue" text="Старт" x="-450" y="-400" width="150" height="150" id="start_zone"/>
24
<region type="rectangle" visible="true" color="green" text="Финиш" x="450" y="-400" width="150" height="150" id="finish_zone"/>
25
26
<region id="warzone" type="rectangle" filled="false" color="black" visible="true" x="-450" y="-400" width="1050" height="600"/>
27
</regions>
28
</world>
29
<robots>
30
<robot id="trikKitRobot" direction="0" position="-401:-351">
31
<sensors>
32
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" port="M4###output###JM4$$D$$4###" position="75:25"/>
33
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" port="M3###output###JM3$$C$$3###" position="75:25"/>
34
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" port="M2###output###JM2$$B$$2###" position="75:25"/>
35
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" port="M1###output###JM1$$A$$1###" position="75:25"/>
36
</sensors>
37
<startPosition direction="0" x="-376" y="-326"/>
38
</robot>
39
</robots>
40
<!-- Описание ограничений -->
41
<constraints>
42
<!-- Ограничение на время 5 минут -->
43
<timelimit value="300000"/>
44
45
<constraint checkOnce="true" failMessage="Робот должен находиться в зоне старта перед запуском!">
46
<inside objectId="robot1" regionId="start_zone"/>
47
</constraint>
48
49
<!-- Ограничение, проверяющее, что робот находится в допустимой зоне -->
50
<constraint failMessage="Робот попытался объехать лабиринт!">
51
<inside objectId="robot1" regionId="warzone"/>
52
</constraint>
53
54
<!-- Событие, которое проверяет, что робот находится в зоне финиша по окончании выполнения программы -->
55
<event id="finish checker" settedUpInitially="true">
56
<condition>
57
<inside objectId="robot1" regionId="finish_zone"/>
58
</condition>
59
<trigger>
60
<success/>
61
</trigger>
62
</event>
63
</constraints>
64
</root>
Copied!
Рассмотрим подробнее, как происходит проверка.
1. Зададим ограничение на время прохождения задания. Это ограничение является обязательным. Время указывается в миллисекундах.
1
<timelimit value="300000"/>
Copied!
2. Зададим ограничение на зону, в которой должен находиться робот перед началом программы. По условию задачи это должен быть синий квадрат - зона старта. Это ограничение будет проверяться один раз, в начале программы, так как атрибут checkOnce равен true.
С помощью тега <inside> мы задаем пространственное ограничение. Он имеет два атрибута. В первом (objectId) указываем id объекта, местоположение которого мы хотим проверить, в нашем случае это робот. Во втором (regionId) указываем id региона, в котором должен находиться наш объект.
В случае, если условие, которое описано в <inside> не выполняется, то программа будет завершена с ошибкой. Для этого у тега <constraint> есть атрибут failMessage, который позволяет задать текст сообщения об ошибке.
1
<constraint checkOnce="true" failMessage="Робот должен находиться в зоне старта перед запуском!">
2
<inside objectId="robot1" regionId="start_zone"/>
3
</constraint>
Copied!
3. Для того, чтобы проверять, что пользователь действительно проходит лабиринт, а не объезжает его, давайте зададим еще одно пространственное ограничение.
Отредактируем в xml-файле мира значение тега <regions>, добавив туда регион с id = “warzone”.
1
<region id="warzone" type="rectangle" filled="false" color="black" visible="true" x="-450" y="-400" width="1050" height="600"/>
Copied!
Это ограничение будет проверяться во все время выполнения программы. В теге <inside> укажем id объекта и id региона, в нашем случае это робот и черный прямоугольник, ограничивающий лабиринт.
В случае, если робот в любой момент времени окажется вне указанного региона, программа будет завершена с ошибкой, текст которой указан в атрибуте failMessage.
1
<constraint failMessage="Робот попытался объехать лабиринт!">
2
<inside objectId="robot1" regionId="warzone"/>
3
</constraint>
Copied!
4. Теперь нам осталось проверить, что робот доезжает до зоны финиша.
Для этого давайте создадим событие, которое будет проверять находится робот в нужной зоне или нет. Атрибут settedUpInitially="true" означает, что событие будет запущено (взведено) сразу при старте программы.
В теге <condition> мы указываем какое именно условие необходимо проверить. В нашем случае условие аналогично описанным выше - мы проверяем, что робот находится в регионе с id = "finish". В случае, если это условие выполнится, то пользователю будет показано сообщение об успешном выполнении программы. Для этого в теге <trigger> мы пишем дочерний тег <success/>.
1
<event id="finish checker" settedUpInitially="true">
2
<!-- Условие -->
3
<condition>
4
<inside objectId="robot1" regionId="finish_zone"/>
5
</condition>
6
<!-- Триггер -->
7
<trigger>
8
<success/>
9
</trigger>
10
</event>
Copied!

Пример 2. Проезд из зоны «Старт» в зону «Финиш» с остановкой

Задача проехать вперед и остановиться в зоне финиша.
Эта задача немного отличается от Примера 1 тем, что добавляется еще одно условие для успешного завершения программы - роботу необходимо не просто оказаться в зоне финиша, но и остановиться.
Ниже приведен полный код для проверки этой задачи.
1
<?xml version='1.0' encoding='utf-8'?>
2
<root version="20190819">
3
<world>
4
<!-- Задание регионов (зон) на карте мира -->
5
<regions>
6
<region id="finish_zone" text="Finish" textX="0" width="200" height="150" color="green" x="320" y="-50" visible="true" type="rectangle" filled="true" textY="0"/>
7
<region id="start_zone" text="Start" textX="0" width="100" height="-100" color="#0000ff" x="-20" y="70" visible="true" type="rectangle" filled="true" textY="0"/>
8
9
<region type="rectangle" id="warzone" text="Поле, которое нельзя покидать" x="-20" y="-140" width="610" height="320" color="orange" visible="true"/>
10
</regions>
11
</world>
12
<robots>
13
<robot id="trikKitRobot" direction="0" position="0:0">
14
<sensors>
15
<sensor port="M3###output###М3###" direction="0" position="75:25" type="kitBase::robotModel::robotParts::Motor"/>
16
<sensor port="M4###output###М4###" direction="0" position="75:25" type="kitBase::robotModel::robotParts::Motor"/>
17
<sensor port="M1###output###М1###" direction="0" position="75:25" type="kitBase::robotModel::robotParts::Motor"/>
18
<sensor port="M2###output###М2###" direction="0" position="75:25" type="kitBase::robotModel::robotParts::Motor"/>
19
</sensors>
20
<startPosition id="{888338bf-3f53-44a4-ac0a-8aeea2d036b2}" y="25" direction="0" x="25"/>
21
<wheels left="M3###output###М3###" right="M4###output###М4###"/>
22
</robot>
23
</robots>
24
<settings realisticMotors="false" realisticSensors="false" realisticPhysics="false"/>
25
<!-- Задание ограничений -->
26
<constraints>
27
<!-- Ограничение на время -->
28
<timelimit value="10000"/>
29
30
<!-- Зональное ограничение на начало езды. Проверяется один раз в начале программы-->
31
<constraint checkOnce="true" failMessage="Робот должен находиться в синем квадрате перед запуском!">
32
<inside objectId="robot1" regionId="start_zone"/>
33
</constraint>
34
35
<!-- Робот находится в допустимой зоне-->
36
<constraint failMessage="Робот покинул допустимую зону!">
37
<inside objectId="robot1" regionId="warzone"/>
38
</constraint>
39
40
<!-- Событие, оповещающее об успешном выполнении программы (зона финиша + робот остановился) -->
41
<event id="finish checker" settedUpInitially="true">
42
<conditions glue="and">
43
<inside regionId="finish" objectId="robot1"/>
44
<equals>
45
<objectState object="robot1.M3.power"/>
46
<int value="0"/>
47
</equals>
48
<equals>
49
<objectState object="robot1.M4.power"/>
50
<int value="0"/>
51
</equals>
52
</conditions>
53
54
<trigger>
55
<success/>
56
</trigger>
57
</event>
58
</constraints>
59
</root>
Copied!
Теперь давайте рассмотрим подробнее как происходит проверка.
1. Зададим ограничение на время прохождения задания.
1
<timelimit value="10000"/>
Copied!
2. Зададим ограничение на начальное положение робота. Оно проверится один раз в начале программы.
1
<constraint checkOnce="true" failMessage="Робот должен находиться в синем квадрате перед запуском!">
2
<inside objectId="robot1" regionId="start_zone"/>
3
</constraint>
Copied!
3. Зададим ограничение на зону, которую робот не может покидать.
1
<constraint failMessage="Робот покинул допустимую зону!">
2
<inside objectId="robot1" regionId="warzone"/>
3
</constraint>
Copied!
4. А теперь создадим событие, которое будет проверять, что робот находится в финишной зоне и при этом он остановился в ней, а не проехал дальше.
Зональное ограничение задается с помощью тега <inside>. Для того, чтобы проверить, что робот остановился, нужно проверить, что мощность на обоих моторах равна нулю. Для этого используем тег <equals>. С помощью тега <objectState> укажем объект, значение которого мы хотим сравнить. В нашем случае это мощность на моторах, поэтому в атрибуте object пишем robot1.M3.power или robot1.M4.power, где M3 и M4 обозначают порты, к которым в текущей конфигурации подключены моторы. А значение, с которым нужно сравниться, записываем с помощью тега <int> и его атрибута value.
Таким образом, в этом событии проверяется три условия: робот находится в зоне финиша, мощность на моторе M3 равна нулю и мощность на моторе M4 также равна нулю. В случае выполнения этих условий пользователю будет показано сообщение об успешном выполнении программы.
1
<event id="finish checker" settedUpInitially="true">
2
<!-- Составное условие -->
3
<conditions glue="and">
4
<inside regionId="finish" objectId="robot1"/>
5
6
<equals>
7
<objectState object="robot1.M3.power"/>
8
<int value="0"/>
9
</equals>
10
11
<equals>
12
<objectState object="robot1.M4.power"/>
13
<int value="0"/>
14
</equals>
15
</conditions>
16
17
<trigger>
18
<success/>
19
</trigger>
20
</event>
Copied!

Пример 3. Проезд из зоны «Старт» в зону «Финиш» вдоль стены с проверкой датчиков

Стартовав в синем квадрате, необходимо проехать вдоль стены с помощью датчика расстояния ИК до красного квадрата.
Ниже приведен полный код для проверки этого задания.
1
<?xml version='1.0' encoding='utf-8'?>
2
<root version="20190819">
3
<world>
4
<walls>
5
<wall stroke-width="10" end="-110:50" stroke="#ff000000" begin="-200:50" stroke-style="none" fill="#ff000000" id="{f148f786-7d73-4c42-a3aa-c7a29892d3d7}"/>
6
<wall stroke-width="10" end="0:100" stroke="#ff000000" begin="-110:50" stroke-style="none" fill="#ff000000" id="{8f39faac-9392-4878-86e9-9fe5dbea0007}"/>
7
<wall stroke-width="10" end="250:110" stroke="#ff000000" begin="0:100" stroke-style="none" fill="#ff000000" id="{bf465864-fa2e-4b59-ac65-e27bd85300d5}"/>
8
<wall stroke-width="10" end="350:160" stroke="#ff000000" begin="250:110" stroke-style="none" fill="#ff000000" id="{ba5441dd-8dd8-4100-ad8b-66d634792e3f}"/>
9
<wall stroke-width="10" end="400:260" stroke="#ff000000" begin="350:160" stroke-style="none" fill="#ff000000" id="{ca85b1de-8e9c-49e9-8c40-c2c49f43dcaa}"/>
10
</walls>
11
<skittles/>
12
<balls/>
13
<colorFields/>
14
<images/>
15
<regions>
16
<region visible="true" type="rectangle" x="350" filled="true" y="50" width="150" height="200" id="good_zone3" color="#ffff00"/>
17
<region visible="true" type="rectangle" x="-250" filled="true" y="-50" width="150" textY="0" height="100" text="Start" id="start_zone" textX="0" color="#0000ff"/>
18
<region visible="true" type="rectangle" x="0" filled="true" y="0" width="400" height="150" id="good_zone2" color="#ffff00"/>
19
<region visible="true" type="rectangle" x="400" filled="true" y="150" width="100" textY="0" height="100" text="Finish" id="finish" textX="0" color="#ff0000"/>
20
<region visible="true" type="rectangle" x="-200" filled="true" y="-50" width="250" height="150" id="good_zone1" color="#ffff00"/>
21
</regions>
22
</world>
23
<robots>
24
<robot direction="0" position="-200:-25" id="trikKitRobot">
25
<sensors>
26
<sensor type="trik::robotModel::parts::TrikInfraredSensor" direction="69.6769" position="42:18" port="A1###input###А1###sensorA1"/>
27
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" position="75:25" port="M4###output###М4###"/>
28
<sensor type="kitBase::robotModel::robotParts::Motor" direction="0" position="75:25" port="M3###output###М3###"/>
29
<sensor type="" direction="0" position="0:0" port="A5###input###А5###sensorA5"/>
30
<sensor type="" direction="0" position="0:0" port="A6###input###А6###sensorA6"/>
31
</sensors>
32
<startPosition direction="0" x="-175" y="0" id="{84223544-d500-411a-9fdb-b382eb98d09f}"/>
33
<wheels right="M3###output###М3###" left="M4###output###М4###"/>
34
</robot>
35
</robots>
36
<settings realisticPhysics="false" realisticSensors="false" realisticMotors="false"/>
37
<constraints>
38
<!-- Лимит времени. Обязательное ограничение -->
39
<timelimit value="40000"/>
40
<!-- Проверка, что на порт А1 установлен датчик расстояния -->
41
<constraint checkOnce="true" failMessage="У робота должен быть установлен датчик расстояния на порт А1">
42
<equals>
43
<typeOf objectId="robot1.A1"/>
44
<string value="twoDModel::robotModel::parts::RangeSensor"/>
45
</equals>
46
</constraint>
47
<!-- Провека, что нет датчиков, кроме датчика расстояния-->
48
<constraint checkOnce="true" failMessage="У робота не должно быть датчиков, кроме датчика расстояния">
49
<conditions glue="and">
50
<equals>
51
<typeOf objectId="robot1.A2"/>
52
<string value="undefined"/>
53
</equals>
54
<equals>
55
<typeOf objectId="robot1.A3"/>
56
<string value="undefined"/>
57
</equals>
58
<equals>
59
<typeOf objectId="robot1.A4"/>
60
<string value="undefined"/>
61
</equals>
62
<equals>
63
<typeOf objectId="robot1.A5"/>
64
<string value="undefined"/>
65
</equals>
66
<equals>
67
<typeOf objectId="robot1.A6"/>
68
<string value="undefined"/>
69
</equals>
70
<equals>
71
<typeOf objectId="robot1.D1"/>
72
<string value="undefined"/>
73
</equals>
74
<equals>
75
<typeOf objectId="robot1.D2"/>
76
<string value="undefined"/>
77
</equals>
78
<equals>
79
<typeOf objectId="robot1.F1"/>
80
<string value="undefined"/>
81
</equals>
82
</conditions>
83
</constraint>
84
85
<!-- Зональное ограничение на начало езды. Проверяется один раз в начале программы-->
86
<constraint checkOnce="true" failMessage="Робот должен находиться в синей зоне перед стартом!">
87
<inside objectId="robot1" regionId="start_zone"/>
88
</constraint>
89
<!-- Проверяет, что робот находится в допустимом регионе на протяжении всего времени выполнения программы -->
90
<constraint failMessage="Робот покинул допустимую зону!">
91
<conditions glue="or">
92
<inside objectId="robot1" regionId="good_zone1"/>
93
<inside objectId="robot1" regionId="good_zone2"/>
94
<inside objectId="robot1" regionId="good_zone3"/>
95
</conditions>
96
</constraint>
97
<!-- Событие, оповещающее об успешном выполнении программы -->
98
<event id="finish checker" settedUpInitially="true">
99
<condition>
100
<inside objectId="robot1" regionId="finish"/>
101
</condition>
102
<trigger>
103
<success/>
104
</trigger>
105
</event>
106
</constraints>
107
</root>
108
Copied!
Теперь давайте рассмотрим подробнее как происходит проверка.
1. Зададим ограничение на время выполнения задания.
1
<timelimit value="40000"/>
Copied!
2. По условию задачи у робота должен быть подключен только датчик расстояния (других датчиков быть не должно). Для того чтобы убедиться в этом, сравним значение объекта на порту A1 со значением, которое обозначает датчик расстояния. Подробнее о названиях датчиков для разных конструкторов можно узнать по ссылке.
1
<constraint checkOnce="true" failMessage="У робота должен быть установлен датчик расстояния на порт А1">
2
<equals>
3
<typeOf objectId="robot1.A1"/>
4
<string value="twoDModel::robotModel::parts::RangeSensor"/>
5
</equals>
6
</constraint>
Copied!
3. Выполним проверку, что к другим портам не подключены никакие датчики. Для этого сравним значение на каждом порту со строкой “undefined”.
1
<constraint checkOnce="true" failMessage="У робота не должно быть датчиков, кроме датчика расстояния">
2
<conditions glue="and">
3
<equals>
4
<typeOf objectId="robot1.A2"/>
5
<string value="undefined"/>
6
</equals>
7
<equals>
8
<typeOf objectId="robot1.A3"/>
9
<string value="undefined"/>
10
</equals>
11
<equals>
12
<typeOf objectId="robot1.A4"/>
13
<string value="undefined"/>
14
</equals>
15
<equals>
16
<typeOf objectId="robot1.A5"/>
17
<string value="undefined"/>
18
</equals>
19
<equals>
20
<typeOf objectId="robot1.A6"/>
21
<string value="undefined"/>
22
</equals>
23
<equals>
24
<typeOf objectId="robot1.D1"/>
25
<string value="undefined"/>
26
</equals>
27
<equals>
28
<typeOf objectId="robot1.D2"/>
29
<string value="undefined"/>
30
</equals>
31
<equals>
32
<typeOf objectId="robot1.F1"/>
33
<string value="undefined"/>
34
</equals>
35
</conditions>
36
</constraint>
Copied!
4. Зададим ограничение на начальное положение робота. Оно проверится один раз в начале программы, потому что выставлен флаг checkOnce .
1
<constraint checkOnce="true" failMessage="Робот должен находиться в синем квадрате перед запуском!">
2
<inside objectId="robot1" regionId="start_zone"/>
3
</constraint>
Copied!
5. Зададим ограничение на зону, которую робот не может покидать. В предыдущих примерах мы рассматривали ситуацию, когда роботу нужно было находиться в одной зоне. В данном случае допустимая зона состоит из нескольких прямоугольников, поэтому нам нужно проверять, что робот находится в одной из этих зон. Для этого используем тег <conditions></conditions> с атрибутом glue = “or”.
1
<constraint failMessage="Робот покинул допустимую зону!">
2
<conditions glue="or">
3
<inside objectId="robot1" regionId="good_zone1"/>
4
<inside objectId="robot1" regionId="good_zone2"/>
5
<inside objectId="robot1" regionId="good_zone3"/>
6
</conditions>
7
</constraint>
Copied!
6. И наконец, создадим событие, которое будет оповещать об успешном выполнении программы в случае, если робот находится в зоне финиша.
1
<event id="finish checker" settedUpInitially="true">
2
<condition>
3
<inside objectId="robot1" regionId="finish"/>
4
</condition>
5
<trigger>
6
<success/>
7
</trigger>
8
</event>
Copied!

Пример 4. Подсчет перекрестков и вывод на экран

Движение по линии с подсчетом перекрестков: при заезде на перекресток робот должен выводить на экран номер этого перекрестка.
Ниже приведен полный код для проверки этого задания.
1
<?xml version='1.0' encoding='utf-8'?>
2
<root version="20190819">
3
<world>
4
<walls/>
5
<skittles/>
6
<balls/>
7
<colorFields>
8
<cubicBezier id="{6199f811-617a-463d-848f-39b28b918584}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-174.411:98.5051" cp1="-173.503:9.71619" stroke-width="12" cp2="-184.608:-31.2306" fill="#ff000000" end="-103.03:-28.2828"/>
9
<line id="{311aba08-eff0-4d50-98f1-fc7595e22b79}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-97.2997:-28.5387" stroke-width="12" fill="#ff000000" end="353.7:-28.5387"/>
10
<line id="{e4428c3f-4ef1-4214-b5be-9a22eb4f875e}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-175.556:244" stroke-width="12" fill="#ff000000" end="-175.556:106.222"/>
11
<line id="{c921474d-3f18-4f98-b3fd-c83fa6e712b8}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-202.02:102.353" stroke-width="12" fill="#ff000000" end="-149.459:102.353"/>
12
<line id="{5f4000d6-8494-45bb-8e0c-44a5779f3140}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-49.8316:-64.6465" stroke-width="12" fill="#ff000000" end="-49.8316:11.4478"/>
13
<line id="{c20e8d67-e66b-4cd1-a4d5-da909d32717a}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="48.2829:-65.5219" stroke-width="12" fill="#ff000000" end="48.2829:10.5724"/>
14
<line id="{3abe2138-f488-429d-bb27-94b6a13c913e}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="146.599:-64.8485" stroke-width="12" fill="#ff000000" end="146.599:11.2458"/>
15
<line id="{ccaf1f51-b4b8-4ed4-9110-cf08067e7bf4}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="249.63:-65.5219" stroke-width="12" fill="#ff000000" end="249.63:10.5724"/>
16
<line id="{6866e178-6a20-4048-8eab-ed3554098cd4}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="460.157:66.3198" stroke-width="12" fill="#ff000000" end="460.157:260.178"/>
17
<cubicBezier id="{47001b3d-8af4-432d-8e66-9cc7728f2a39}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="358.194:-28.399" cp1="438.051:-29.9289" stroke-width="12" cp2="457.133:13.7415" fill="#ff000000" end="459.881:62.7527"/>
18
<cubicBezier id="{edb3034d-f57c-4349-a714-3439433d2db2}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="458.622:252.499" cp1="457.591:441.101" stroke-width="12" cp2="251.469:440.071" fill="#ff000000" end="249.408:304.03"/>
19
<cubicBezier id="{ff2677c7-98f1-46e0-b17c-197a3d94e664}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="249.408:304.03" cp1="251.469:155.622" stroke-width="12" cp2="-10.3061:151.5" fill="#ff000000" end="-9.27549:302.999"/>
20
<cubicBezier id="{c841736a-ce7b-4bc4-90bb-7bb72bb7dd99}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="-9.27549:302.999" cp1="-9.02218:404.61" stroke-width="12" cp2="-177.667:378.931" fill="#ff000000" end="-175.204:250.438"/>
21
<line id="{34475443-f1cf-4718-bb44-bd4bfc7221bf}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="428.351:105.655" stroke-width="12" fill="#ff000000" end="489.769:105.655"/>
22
<line id="{9e883af6-6280-4577-b0da-608011ca26ed}" stroke-style="solid" fill-style="none" stroke="#ff000000" begin="428.197:199.401" stroke-width="12" fill="#ff000000" end="489.615:199.401"/>
23
</colorFields>
24
<images/>
25
<regions>
26
<region id="region_1" type="rectangle" textX="0" width="80" textY="0" visible="true" y="0" text="1" filled="true" height="80" color="#0000ff" x="-215"/>
27
<region id="region_2" type="rectangle" textX="0" width="80" textY="