Суть олимпиадной дисциплины состоит в том, что автономный робот должен вытолкнуть за пределы ринга робота противника. Размер и форма ринга, стартовые позиции роботов, их габариты и масса определяются регламентом соревнований. С примером регламента можно ознакомится по ссылке.
По регламенту роботы соперников должны начинать движение с задержкой в несколько секунд только после нажатия по кнопке на роботе.
Составьте следующую программу для запуска движения робота после нажатия на центральную кнопку блока. Пауза перед началом движения - 3 секунды.
Запустите программу. Робот должен ждать нажатия центральной кнопки на блоке и после этого проедет прямо на один оборот колеса.
Запуск робота
Все следующие программы для движения по рингу должны запускаться после нажатия на центральную кнопку блока управления.
Алгоритм работы сумо-робота
Опишем один из возможных алгоритмов и последовательно реализуем его.
В первую очередь реализуем поиск противника. Робот будет вращаться на месте, пока не увидит робота на расстоянии меньшем чем 50 см. Направление вращения будем выбирать случайным образом.
Присоедините к роботу ультразвуковой датчик расстояния.
Модифицируйте программу следующим образом:
Блок Случайное значение переключите в режим Логическое значение. Блок Переключатель также переключите в режим Логическое значение. С вероятностью 50% робот будет вращаться на месте по часовой или против часовой стрелке. После обнаружения противника моторы выключаются.
Проверьте работу программы.
Чтобы сократить итоговый код алгоритма, поиск противника поместим в собственный блок. Собственные блоки помогают сгруппировать фрагменты кода в более компактную форму.
Обведите мышью блоки программы отвечающие за поиск противника:
Укажите имя нового блока - poisk и нажмите кнопку Завершить. Весь выбранный код заменится одним собственным блоком:
Все такие блоки также можно найти в разделе Мои блоки палитры блоков:
После обнаружения противника, робот должен ехать в его сторону на максимальной скорости. Нужно помнить, что робот не должен выезжать за пределы ринга. Используем датчик цвета.
Редактирование собственного блока
Чтобы изменить код собственного блока, щелкните по нему дважды. Чтобы отредактировать имя, описание и набор параметров, нажмите на шестерёнку рядом с текущим именем блока.
Присоедините к роботу датчик цвета. Помните, что он должен располагаться на расстоянии не больше 2 см от поверхности.
Для обнаружения границ ринга используем режим измерения уровня отражённого света. Движение робота и проверку условия поместим в цикл. Цикл с командой движения будет завершаться, если выполнится условие в блоке Датчик цвета.
Модифицируйте программу следующим образом:
Блок Датчик цвета переключите в режим Сравнение - Яркость отражённого света. Условие завершения цикла переключите на Логическое значение. Как только полученное условие будет истиной, цикл завершиться и робот остановится.
Протестируйте работу программы.
Блоки, отвечающие за атаку поместим в собственный блок, чтобы сократить запись алгоритма.
Выделите последние добавленные блоки:
Выберите пункт меню Инструменты - Конструктор Мой блок. Откроется Конструктор Моего блока. В поле Имя впишите название нового блока - ataka. Теперь код решения должен выглядеть следующим образом:
Протестируйте работу программы.
В текущей записи программы, робот один раз выполнит поиск противника и поедет в его сторону до обнаружения линии. Эти два действия должны выполняться без остановки до завершения раунда. Поместим их в бесконечный цикл.
Разместите собственные блоки poisk и ataka внутри бесконечного цикла:
Протестируйте работу программы.
Доехав до границы ринга, робот сразу начинает вращаться на месте. Это может привести к тому, что одно из колёс попадет за пределы ринга.
Дополните текущую программу блоком Переключатель:
Режим работы Переключателя - Датчик цвет - Сравнение - Яркость отражённого света. Если робот над чёрной линией - робот поедет назад на 1,5 оборотов.
Проверьте работу программы.
Соревнование “Робо-сумо”
Перед началом раунда участники размещают робот на ринге. Роботы должны располагаться в противоположных секторах ринга. Проекция робота (не считая провода) не должна выходить за пределы ринга (Рисунок 1).
Рисунок 1
Правила:
Один матч состоит из трёх раундов.
Раунд завершается, когда один из роботов касается поверхности за пределами ринга (за исключением проводов). Этот робот считается проигравшим в раунде.
Максимальная продолжительность раунда - 2 минуты. По истечению времени результатом раунда становится ничья. Ничья может присуждаться по решению судьи.
Выигрыш в раунде даёт 3 балла, ничья - 2 балла, проигрыш - 1 балл.
Роботы должны запускаться по нажатию кнопки на блоке управления. Движение робота должно начинаться с задержкой в 3 секунды. После запуска программ участники отходят от ринга. Участник, коснувшийся робота, после запуска программы считается проигравшим в раунде.
Ограничения по конструкции: длина и ширина - 25 см; ограничений по высоте и массе нет.
functiongetRank(rating) {const ranks = [ { threshold:90,name:"Грандмастер сумо",img:'90.png' },// Высший уровень - только для лучших { threshold:80,name:"Мастер сумо",img:'80.png' },// Выдающийся уровень { threshold:70,name:"Эксперт сумо",img:'70.png' },// Экспертный уровень { threshold:60,name:"Боец сумо",img:'60.png' },// Продвинутый уровень { threshold:50,name:"Претендент",img:'50.png' },// Средний уровень { threshold:40,name:"Опытный новичок",img:'40.png' },// Развивающийся уровень { threshold:20,name:"Новичок",img:'20.png' },// Начальный уровень { threshold:0,name:"Ученик",img:'0.png' } // Базовый уровень ];for (let i =0; i < ranks.length; i++) {if (rating >= ranks[i].threshold) {const nextThreshold = i >0? ranks[i-1].threshold:null;return {name: ranks[i].name,img: ranks[i].img,nextThreshold: nextThreshold }; } }return {name:"Ученик",img:'0.png',nextThreshold:20 };}functioncalculateSumoRating(wins, draws, losses) {const totalMatches = wins + draws + losses;// Проверка на минимальное количество матчейif (totalMatches <3) {return {rating:null,rank:"Без ранга",img:'null.png',nextThreshold:null,message:"Необходимо сыграть минимум 3 раунда для получения рейтинга",stats:{totalMatches: totalMatches } }; }// Расчет базового рейтинга на основе соотношения побед/пораженийconst winRate = wins / totalMatches;const lossRate = losses / totalMatches;const drawRate = draws / totalMatches;// Базовые очки: победы сильно повышают рейтинг, ничьи немного, поражения снижаютconst winPoints = winRate *100*1.5;// Увеличенный вес победconst drawPoints = drawRate *100*0.5;// Уменьшенный вес ничьихconst lossPoints = lossRate *100*-0.5;// Отрицательный вес поражений// Бонус за серию побед (если есть)const winStreakBonus = wins >2?Math.min(wins *2,20) :0;// Штраф за серию поражений (если есть)const lossStreakPenalty = losses >2?Math.min(losses *2,20) :0;// Небольшой бонус за опыт (логарифмический, чтобы не давал слишком большого преимущества)const experienceBonus =Math.log2(totalMatches) *2;// Расчет итогового рейтингаlet rating = winPoints + drawPoints + lossPoints + winStreakBonus - lossStreakPenalty + experienceBonus;// Ограничение рейтинга минимальным и максимальным значением rating =Math.max(0,Math.min(100, rating)); rating =Number(rating.toFixed(2));// Определяем рангconst rankInfo =getRank(rating);return { rating,rank: rankInfo.name,nextThreshold: rankInfo.nextThreshold,img: rankInfo.img,stats: { totalMatches,winRate:Number((winRate *100).toFixed(2)),drawRate:Number((drawRate *100).toFixed(2)),lossRate:Number((lossRate *100).toFixed(2)),basePoints:Number((winPoints + drawPoints + lossPoints).toFixed(2)), winStreakBonus, lossStreakPenalty,experienceBonus:Number(experienceBonus.toFixed(2)) } };}
getRank = ƒ(rating)
calculateSumoRating = ƒ(wins, draws, losses)
r =calculateSumoRating(wins, draws, losses)
r = Object {rating: null, rank: "Без ранга", img: "null.png", nextThreshold: null, message: "Необходимо сыграть минимум 3 раунда для получения рейтинга", stats: Object}
Улучшение алгоритма
Сейчас после обнаружения противника робот будет ехать до границы ринга. Но робот соперника также может двигаться в это время. Исправим алгоритм атаки таким образом, чтобы робот останавливался, если видит границы ринга ИЛИ потерял соперника из виду.
Дважды кликните по собственному блоку ataka, чтобы отредактировать его содержимое. Программа блока откроется в новой вкладке.
Добавьте внутрь цикла два новых блока: Ультразвуковой датчик и Логические операции.
Блок Ультразвуковой датчик переключите в режим Сравнение - Расстояние в сантиметрах. Блок Логические операции переключите в режим ИЛИ (OR). Вывод = этого блока присоедините к условию остановки цикла. Ко входам a и b присоедините результаты сравнения значений датчиков.
Проверьте работу исправленного алгоритма.
Еще одно улучшение алгоритма связано с особенностями правил. Робот не обязательно должен становиться так, чтобы сразу обнаружить робота противника. Тактически выгоднее в начале программы сразу доехать до линии, пропустив атаку противника и затем начать поиск робота. Чтобы реализовать эту тактику измените основной алгоритм.
Добавьте собственный блок ataka перед первым циклом. Сразу после паузы, робот поедет в сторону линии и только потом начнёт поиск противника.