16 / 16 / 1
Регистрация: 15.03.2009
Сообщений: 94
|
||||||
1 | ||||||
Черепашья графика07.02.2010, 19:18. Показов 12841. Ответов 24
Метки нет (Все метки)
Полистал тут Дейтелов, пятое большое издание и нашёл простенькую задачку, но код получился черезчур увесистый, по моему разумению. Помогите оптимизировать и привести к более компактному виду. Заодно может научусь чему новому...
Текст задачи: Язык Лого, особенно популярный среди пользователей персональных компьютеров, сделал знаменитой черепашью графику. Представьте себе механическую черепаху, которая ползает по комнате под управлением программы на C++. Черепаха несет пишущее перо, которое может находиться в одной из двух позиций - нижней или верхней. Если перо в нижней позиции, черепаха вычерчивает траекторию движения, если в верхней, то черепаха передвигается свободно и ничего не вычерчивает. В этой задаче вы будете моделировать действия черепахи и создавать компьютерезированный эскиз пути. Используя массив floor размером 20 на 20 с нулевым начальным условиями. Считывайте команды из содержащего их массива. Всё время отмечайте текущую позицию черепахи и положение пера - нижнее или верхнее. Предполагйте, что черепаха всегда стартует из позиции 0, 0 на полу с верхним положением пера. Ваша программа должна подавать команды черепахе в соответствии со следующими обозначениями: 1 - поднять перо 2 - опустить перо 3 - поворот направо 4 - поворот налево 5 - движение вперёд 6 - печать массива 20 на 20 9 - конец данных (контрольное значение) вот моё решение задачи:
32 просмотра и ниодного комментария, это говорит об моей идеально решённой задаче?))) неужели ни у кого нет других вариантов? да, код грамоздкий, но если чуть-чуть изменить условия задачи, а именно сделать не просто поворот на лево/поворот направо, а, грубо говоря, так: 3 - шаг влево 4 - шаг вправо 5 - шаг вверх 6 - шаг вниз то задача решается проще пареной репы, одним switch'ом. Но тут то и интересность задачи, в её формулировке. Поэтому мне чисто интересно, возможно ли написать более простой и более понятный алгоритм в функции move()...может кто нибудь всё таки поделится идеями? Потому что мне кажется, что от этого алгоритма один шаг до создания игры "змейка"...кстати, следующая прога, которую я собираюсь писать.
1
|
07.02.2010, 19:18 | |
Ответы с готовыми решениями:
24
Черепашья графика Черепашья графика Черепашья графика Черепашья графика (язык Лого) |
1 / 1 / 0
Регистрация: 18.02.2010
Сообщений: 4
|
||||||
18.02.2010, 23:04 | 2 | |||||
Привет. Лень кодить на плюсах, сделал на додиезе. Вот посмотри мой вариант, явно покороче получилось. Правда задача нечётко сформулирована, и поэтому возможны вольности в трактовке некоторых моментов. Но идея общая сохранится в любом случае. В плане реализации таких задач на алгоритмы C# мало чем отличается от Си++.
1
|
16 / 16 / 1
Регистрация: 15.03.2009
Сообщений: 94
|
|
19.02.2010, 09:10 [ТС] | 3 |
2spacistor:
а не мог бы в двух словах обрисовать идею алгоритма, а то я чет пару моментов в твоём коде недопонимаю....
0
|
1 / 1 / 0
Регистрация: 18.02.2010
Сообщений: 4
|
|||||||||||
19.02.2010, 10:56 | 4 | ||||||||||
G-Cat, нет никакой идеи или алгоритма. Задача решается в лоб. Класс Tortoise представляет требуемую черепаху. У неё хранится состояние: floor - поле 20 * 20, x,y - положение черепахи, pen - положение пера (0 - поднято, 1 опущено). direction - направление куда повёрнута голова черепахи (целое число от 0 до 3х). Приращения для перехода черепахи если будет дана команда "двигаться прямо" берутся из массивов dx, dy. То есть x += dx[direction], y+=dy[direction]. Это позволяет избежать громоздких конструкций со switch как при движении прямо, так и при поворотах. Когда приходит команда поворот налево, я просто уменьшаю direction на единицу, направо - увеличиваю (разумеется, надо учесть что если значение выходит за пределы 0..3, то оно должно "проворачиваться"). Вот собственно и всё.
По методам: SafeInc: увеличивае т значение value (передаётся по указателю) на величину delta с проверкой, что значение не может выходить за пределы min..max. Если cycle истина, то при выходе за указанные пределы значение "проворачивается" и принимает максимальное значение если было меньше минимального и минимальное если было больше максимального. Если же cycle ложно, то value просто "упирается" в ограничитель (min или max) и не выходит за пределы. Этот метод используется для инкрементирования(delta >0)/декрементирования(delta < 0) direction (cycle = true) и x, y (cycle = false). Command: выполняет команду, переданные в виде целого числа. Если cmd < 3 - Это команда поднять/опустить перо. Причём если "опустить" то сразу ставится точка на поле. Если 3 <= cmd < 5 - это команда на поворот. direction просто инкрементируется или дектрементируется на единицу. "2 * cmd - 7" принимает -1 если cmd = 3 и +1 если cmd = 4 работает быстрее, чем if, но в 99,9% случаев так лучше не писать, ибо запутывает код. Если cmd = 5 - движение. Просто инкрементим x, y на величину dx[direction], dy[direction]. Кстати там у меня баг - надо floor[x, y] = pen делать только если перо опущено:
В основной программе посимвольно с консоли считываются команды и выполняются, пока не встретится 9 (конец ввода).
0
|
arbuzaki
|
|
20.01.2011, 01:00 | 5 |
Привет! Чуток доделал! На "с" будет выглядеть так:
|
0 / 0 / 0
Регистрация: 30.01.2011
Сообщений: 23
|
||||||
05.03.2011, 18:18 | 6 | |||||
Добавил буфер памяти для команд, чтобы двигаться вперед ввести 5 затем количество шагов (контрольное значение сделал -1 чтобы не мешало).
arbuzaki что здесь делает #include <stdlib.h> ?
0
|
Vlad-grigoryan
|
||||||
09.07.2011, 01:20 | 7 | |||||
Вот код программы только что написал и протестиравал на dev-c++ все работает там все прокоментириванно наслождайтесь
|
3 / 3 / 2
Регистрация: 07.10.2011
Сообщений: 87
|
|
18.10.2011, 19:16 | 8 |
Как то тут все сложновато у Вас, если кому-то интересно гляньте как я реализовал эту задачу на С:
Код
#include "stdio.h" #define SIZE 10 int main(){ int command[20]={2,4,5,49,3,5,10,8,5,30,4,5,15,6}; int floor [50][50]={0}; int i=0; int j=0; int k=0; int h=0; int g=0; int ziy=0; for (k=0;k<=20;k++){ int z=0; if (command[k]==1){ g++; }// 1 if pero podniato if (command[k]==2){ h++; }//2 if pero opyscheno if ((command[k]==5)&&(h>=g)){ if (command[k-1]==3){ for(z;z<command[k+1];z++){ floor[i][j++]=1; }//end for printf("i=%d j=%d\n", i,j); }//pero vpravo if (command[k-1]==4){ for(z;z<command[k+1];z++){ floor[i++][j]=1; }//end for printf("%d %d\n", i,j); }//pero vniz if (command[k-1]==7){ z=0; for(z;z<command[k+1];z++){ floor[i][j--]=1; }//end for printf("%d %d\n", i,j); }//pero vlevo if (command[k-1]==8){ z=0; for(z;z<command[k+1];z++){ floor[i--][j]=1; }//end for printf("%d %d\n", i,j); }//pero vverh }//end if5 if (command[k]==6){ for (i=0;i<50;i++){ printf("\n"); for (j=0;j<50;j++){ printf("%d",floor[i][j]); } } }//if 6 if (command[k]==3){ continue; } if (command[k]==4){ continue; } if (command[k]==7){ continue; } if (command[k]==8){ continue; } } // end for scanf("%d",&h); return 0; }// end all Добавлено через 7 минут
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
|
|
18.10.2011, 19:23 | 9 |
Vlad-grigoryan, твоя прога просит меня команды вводить и сколько их нужно ввести? Так-то всю жизнь вводить можно
1
|
1 / 1 / 2
Регистрация: 21.12.2011
Сообщений: 73
|
||||||
09.04.2012, 23:23 | 10 | |||||
Дошёл в книжке до этого задания, но вот что-то черепаха упорно отказывается идти правильно.
Проверьте мою карикатуру и скажите что тут не так.
0
|
31 / 31 / 3
Регистрация: 19.05.2012
Сообщений: 67
|
||||||
24.05.2012, 15:26 | 11 | |||||
Мой вариант, полностью работает
0
|
0 / 0 / 0
Регистрация: 08.12.2012
Сообщений: 7
|
||||||
17.01.2013, 23:46 | 12 | |||||
Немного непонятен этот момент, если можно, подробнее объясните этот фрагмент кода.
0
|
22.05.2013, 12:43 | 13 |
Прочитал уже несколько тем об этой черепахе, но нигде не смог найти решение ситуации, на которой застопорился я. Мне понятен алгоритм движения черепахи и рисования траектории ее движения, с этим проблем нет. Проблема есть в следующем. К этой задаче прилагается пример:
12 шагов вперед; поворот направо; 12 шагов вперед... и так 4 раза. В примере следует утверждение, что при данных командах черепаха нарисует квадрат 12x12. Вот это мне не понятно и я буду рад любой помощи. Я рассуждаю так: 1. Если я стою в начальной ячейке (0,0) и делаю 5 шагов вправо (предположим, что это вектор черепахи по умолчанию) с опущенным пером, то в какой ячейке я окажусь в итоге и какие ячейки будут закрашены. С точки зрения реального мира, если я опущу перо в начальной ячейке и сделаю 5 шагов (шаг = 1 ячейка), то я окажусь в ячейке (0,5) и все посещенные мной ячейки будут отмечены (включая начальную и конечную). Их будет 6, а не 5, но это противоречит логике примера. 2. Для достижения результатов, указанных в примере, во время движения мне необходимо считать мою текущую ячейку как пройденную(1 шаг). Кажется, что логика в этом есть, но... если мой шаг равен 1, то черепаха в этом случае не меняет своего местоположения, а это уже нонсенс. Так какой из вариантов мне выбрать для реализации (может предложите еще варианты)? Может я где то отклонился от сути в своих размышлениях? Или же это просто ошибка в примере? Помогите, 3-й час уже пошел, а мне хочется сегодня уснуть "со спокойной душой и ясным разумом"
0
|
9 / 9 / 1
Регистрация: 28.04.2013
Сообщений: 55
|
|
22.05.2013, 17:36 | 14 |
Vlad-grigoryan, пожалуй самый путевый метод
Добавлено через 8 минут поторопился я с выводами)
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
||||||
22.05.2013, 17:39 | 15 | |||||
Мимино, длину хода можно представить как количество закрашенных ячеек. В данном случае при вводе 5, закрашиваются все ячейки кроме той, где черепаха останавливается.
То есть реализовать можно в цикли вот так:
0
|
22.05.2013, 17:44 | 16 | |||||
Ну, раз на то пошло, прошу оценить и мое "творение"
З.Ы. Постом выше я описал свою проблему понимания этой задачи. Взял для реализации 1-й вариант. Принцип тот же, а ошибку завышения/занижения на 1 исправить можно.
Хоть кто-то отозвался, спасибо. Я вот тоже сначала выбрал этот путь, но, опять же, как быть с перемещением на 1 шаг? В этом случае факт движения присутствует, а на положении черепахи это никак не отображается.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
22.05.2013, 17:46 | 17 |
Мимино, ну как же, она передвигается на 1 шаг. Закрашивает текущую клетку и сдвигается на следующую.
0
|
22.05.2013, 18:00 | 18 |
Да, мысль понял. Но этот метод тоже немного "взрывает" мой мозг Объясню. Это равносильно тому, что перо поднимается при последнем шаге. Или, к примеру, если черепаху повернуть и сдвинуть на 1 шаг, это изменит траекторию черепахи, а на "графическом" отображении траектории это не будет заметно.
Я даже провел следующий опыт: 1. Разложил на полу 6 листов бумаги в ряд. 2. Взял бутылку с водой. 3. Встал на 1-й лист и приоткрыл бутылку, чтобы из нее текла вода (опустил перо). 4. Сделал 5 шагов. Итог: траектория моего движения полностью отображена на полу, мокрые 6 листов, а не 5. На чем я прокололся (мозг/выбор профессии не в счет)?
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
22.05.2013, 18:10 | 19 |
Задание обучающее, и дано в книге для изучения массивов, если мне не изменяет память. Можно так же закрашивать все клетки, по которым прошла черепаха, суть то, в принципе, не в этом.
1
|
22.05.2013, 18:16 | 20 |
0
|
22.05.2013, 18:16 | |
22.05.2013, 18:16 | |
Помогаю со студенческими работами здесь
20
Черепашья графика на С (Си) Черепашья графика Черепашья графика в консоли на C Chart - диаграмма: изменить точность делений графика, установить центр графика в (0,0) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |