Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- Задание:
- Робот на поле без перегородок .
- Требуется закрасить поле клетками в шахматном порядке размером NxN .
- Идея для решения :
- Научим робота ходить сразу N клеток , маркировать сразу N клеток и
- проходить сразу N столбцов/строк . Тогда мы сведем эту задачу к просто
- " закрасить поле в шахматном порядке " .
- Бежим в выбранный нами угол и начинаем перемещаться по нашим
- " большим " столбцам/строкам ( шириной N ) с чередованием замаркированных
- и незамаркированных клеток .
- Решение универсально , поэтому вместо " столбцы " и " строки " будем
- говорить " путь "
- %}
- function chess_n(r, u, v, n)
- % Данная функция закрашивает поле без перегородок в шахматном порядке клетками
- % NxN начиная от угла по направлению (u, v)
- % Пример вызова функции: chess_n(r, 's', 'w', 3);
- % Первым делом идём в угол
- go_to_wall(r, u); % Идём роботом до ближайшей стены по направлению u
- go_to_wall(r, v); % А теперь то же самое по направлению v
- % Разворачиваем робота
- u = invert(u); % меняем направление u на противоположное
- v = invert(v); % то же самое с направлением v
- % Начинаем красить поле
- % Вводим логическую переменную finished , которая будет хранить
- % true тогда , когда робот выполнил свою работу полностью
- finished = false;
- % Вводим логическую переменную mark , которая будет хранить
- % true тогда , когда нам нужно начать маркировать с самой первой
- % клетки (без смещения)
- mark = true;
- while ~finished
- % Красим путь шириной n ( то есть , как пример , если робот
- % движется по слобцам , то мы красим сразу n столбцов ! )
- finished = mark_full_path(r, u, v, n, mark);
- % Обеспечиваем чередование клеток , меняя значение mark на противположное
- mark = ~mark;
- end
- end
- function result = invert(u)
- % Функция возвращает противоположное к направлению u
- switch u
- case 'w' result = 'o';
- case 'o' result = 'w';
- case 'n' result = 's';
- case 's' result = 'n';
- end
- end
- function go_to_wall(r, u)
- % Функция перемещает робота вполную к ближайшей стене по направлению u
- while ~r.is_bord(u)
- r.step(u);
- end
- end
- function result = mark_full_path(r, u, v, n, mark)
- % Функция маркирует полный путь , то есть путь , состоящий из n одинарных путей
- % Принимает в качестве параметров:
- % направления u и v ,
- % ширину клетки n
- % mark = true , если нужно закрашивать первую клетку , иначе false
- % Возвращает true , если при смещении по направлению v ( переход
- % на следующий одинарный путь ) робот уперся в стену
- result = false;
- for i = 1:n
- mark_small_path(r, u, n, mark); % Закрашиваем одинарный путь
- go_to_wall(r, invert(u)); % Возвращаемся обратно
- if ~r.is_bord(v) % Если по направлению смещения нет стены
- r.step(v); % То смещаемся на новый одинарный путь
- else
- result = true; % Наткнулить на стену
- break; % Прекращаем работу цикла
- end
- end
- end
- function mark_small_path(r, u, n, mark)
- % Функция гонит робота по направлению u следующим образом:
- % n клеток закрашиваются
- % n клеток не закрашиваются
- % и делает он это до тех пор , пока не упрется в стену
- % Если mark = true , то первые n клеток закрашиваются , иначе нет
- wall = false;
- while ~wall
- wall = step_n(r, u, n, mark);
- wall = step_n(r, u, n, ~mark);
- end
- end
- function result = step_n(r, u, n, mark)
- % Функция заставляет робота сделать n шагов по направлению u
- % При этом , весь пройденный путь робот закрасит , если mark = true
- % Возвращает true , если уперся в стену
- result = false;
- for i = 1:n
- % Сначала закрасим клетку , если это нужно :
- if mark && ~r.is_mark
- r.mark;
- end;
- % Затем уже делаем шаг :
- if ~r.is_bord(u) % Если не уткнулись в стену по направдению u
- r.step(u); % То смело щагаем туда
- else % Если все - таки уткнулись в неё
- result = true; % То сообщаем это
- if mark && ~r.is_mark % И закрасим клетку перед выходом , если нужно
- r.mark;
- end;
- break; % Преждевременно завершаем выполнение цикла
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement