С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 44, средняя оценка - 4.61
G-Cat
16 / 16 / 1
Регистрация: 15.03.2009
Сообщений: 94
#1

Черепашья графика - C++

07.02.2010, 19:18. Просмотров 6045. Ответов 23
Метки нет (Все метки)

Полистал тут Дейтелов, пятое большое издание и нашёл простенькую задачку, но код получился черезчур увесистый, по моему разумению. Помогите оптимизировать и привести к более компактному виду. Заодно может научусь чему новому...

Текст задачи:
Язык Лого, особенно популярный среди пользователей персональных компьютеров, сделал знаменитой черепашью графику. Представьте себе механическую черепаху, которая ползает по комнате под управлением программы на C++. Черепаха несет пишущее перо, которое может находиться в одной из двух позиций - нижней или верхней. Если перо в нижней позиции, черепаха вычерчивает траекторию движения, если в верхней, то черепаха передвигается свободно и ничего не вычерчивает. В этой задаче вы будете моделировать действия черепахи и создавать компьютерезированный эскиз пути.
Используя массив floor размером 20 на 20 с нулевым начальным условиями. Считывайте команды из содержащего их массива. Всё время отмечайте текущую позицию черепахи и положение пера - нижнее или верхнее. Предполагйте, что черепаха всегда стартует из позиции 0, 0 на полу с верхним положением пера. Ваша программа должна подавать команды черепахе в соответствии со следующими обозначениями:
1 - поднять перо
2 - опустить перо
3 - поворот направо
4 - поворот налево
5 - движение вперёд
6 - печать массива 20 на 20
9 - конец данных (контрольное значение)



вот моё решение задачи:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
    using std::cout;
    using std::endl;
    using std::cin;
#include <iomanip>
    using std::setw;
 
void printFloor( bool [ 20 ][ 20 ] );
int move( bool [ 20 ][ 20 ], bool, bool );
 
int main( void )
{
    bool array[ 20 ][ 20 ] = { 0 };
    int press;
    bool feather = 0;
    bool way = 0;
    
    do
    {
        cout << "Enter a command:\n";
        cin >> press;
        
        switch( press )
        {
            case 1:
                feather = 0;//pero vverhu
                break;
            case 2:
                feather = 1;//pero vnizu
                break;
            case 3:
                way = 0;//vpravo
                break;
            case 4:
                way = 1;//vlevo
                break;
            case 5:
                move( array, way, feather );        
                break;
            case 6:
                printFloor( array );
                break;
            case 9:
                break;
            default:
                cout << "Wrong enter. Try again.\n";
                break;
        }
        
    }
    while( press != 9 );
 
    return 0;
}
 
int move( bool array[ 20 ][ 20 ], bool way, bool feather )
{
    static int nowX = 5;
    static int nowY = 5;
    
    static int lastX = 6;
    static int lastY = 5;
    
    if( way == 0 )//dvishenie vpravo
    {
        if( (nowX == lastX - 1) && (nowY == lastY) )
        {
            lastX = nowX;
            lastY = nowY;
            nowY++;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX) && (nowY == lastY + 1) )
        {
            lastX = nowX;
            lastY = nowY;
            nowX++;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX + 1) && (nowY == lastY) )
        {
            lastX = nowX;
            lastY = nowY;
            nowY--;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX) && (nowY == lastY - 1) )
        {
            lastX = nowX;
            lastY = nowY;
            nowX--;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
    }
    else//dvishenie vlevo
    {
        if( (nowX == lastX - 1) && (nowY == lastY) )
        {
            lastX = nowX;
            lastY = nowY;
            nowY--;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX) && (nowY == lastY - 1) )
        {
            lastX = nowX;
            lastY = nowY;
            nowX++;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX - 1) && (nowY == lastY) )
        {
            lastX = nowX;
            lastY = nowY;
            nowY++;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
        if( (nowX == lastX) && (nowY == lastY + 1) )
        {
            lastX = nowX;
            lastY = nowY;
            nowX--;
            if( feather == 1 )
                array[ nowX ][ nowY ] = 1;
            return 0;
        }
    }
}
 
void printFloor( bool array[ 20 ][ 20 ])
{
    for( int i = 0; i < 20; i++ )
    {
        for( int j = 0; j < 20; j++ )
        {
            if( array[ i ][ j ] == 1 )
                cout << setw( 2 ) << '*';
            else
                cout << setw( 2 ) << ' ';
        }
        
        cout << endl;
    }
}
Добавлено через 15 часов 49 минут
32 просмотра и ниодного комментария, это говорит об моей идеально решённой задаче?)))
неужели ни у кого нет других вариантов? да, код грамоздкий, но если чуть-чуть изменить условия задачи, а именно сделать не просто поворот на лево/поворот направо, а, грубо говоря, так:
3 - шаг влево
4 - шаг вправо
5 - шаг вверх
6 - шаг вниз
то задача решается проще пареной репы, одним switch'ом. Но тут то и интересность задачи, в её формулировке. Поэтому мне чисто интересно, возможно ли написать более простой и более понятный алгоритм в функции move()...может кто нибудь всё таки поделится идеями? Потому что мне кажется, что от этого алгоритма один шаг до создания игры "змейка"...кстати, следующая прога, которую я собираюсь писать.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2010, 19:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Черепашья графика (C++):

Черепашья графика - C++
Язык Лого, особенно популярный среди пользователей персональных компьютеров, сделал знаменитой черепашью графику. Представьте себе...

Черепашья графика - C++
Многоугольник (не обязательно выпуклый) задан след. образом: длина очередной стороны, угол поворота к след. стороне (положительный или...

Черепашья графика - C++
Текст задачи из учебника Дейтела: Язык Лого, особенно популярный среди пользователей персональных компьютеров, сделал знаменитой...

Черепашья графика (язык Лого) - C++
Хочу смоделировать перемещение черепахи по полю. У черепахи есть перо. Если оно опущено, то на поле остается след, если поднято - следа не...

Черепашья графика на С (Си) - C (СИ)
Черепаха несет перо, которое может находится в одной из 2х позиций – нижней или верхней. Если перо в нижней позиции, то черепаха рисует...

Chart - диаграмма: изменить точность делений графика, установить центр графика в (0,0) - C#
Создал диаграмму (все прекрасно считается точки расставляются), но есть проблемыЖ 1. В случае диаграммы - &quot;Спектр амплитуд&quot;, series2 он...

23
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
22.05.2013, 17:44 #16
Ну, раз на то пошло, прошу оценить и мое "творение"
З.Ы. Постом выше я описал свою проблему понимания этой задачи. Взял для реализации 1-й вариант. Принцип тот же, а ошибку завышения/занижения на 1 исправить можно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "stdafx.h"
#include <iostream>
using namespace std;
 
int x = 0, y = 0, turn = 0, pen = 1;
 
void printFloor(int [][20], int);
void turtleStep(int [][20], int, int);
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
    const int n = 20, m = 20;
    int floor[n][m] = {0};
    int command = 1, step;
 
    cout << "************************************************************************" << endl;
    cout << "               Погонять черепаху? Нет ничего проще!" << endl;
    cout << "  Запоминай команды, которые нужно вводить через \"пробел\" или \"Enter\"." << endl;
    cout << "            По умолчанию черепаха двигается туда ----->" << endl << endl;
    cout << "1 - Поднять перо(по умолчанию)" << endl << "2 - Опустить перо (осторожно, оставляет следы на полу!)" << endl;
    cout << "3 - Повернуть направо" << endl << "4 - Налево (не рекомендуется семейным людям)." << endl;
    cout << "5 - Пнуть черепаху" << endl << "Циферка после 5-ки - как далеко пнуть." << endl;
    cout << "6 - Посмотреть и ужаснуться от следа на полу." << endl;
    cout << "8 - \"Дяденька, а где черепаха? :'(\"" << endl;
    cout << "9 - Надоело!" << endl;
    cout << "************************************************************************" << endl << endl;
    cout << "Правила обращения с черепахой:" << endl;
    cout << "1. Не заставляйте черепаху биться головой о стену - это больно!" << endl;
    cout << "2. Не \"говорите\" черепахе команд, которых она не знает." << endl << "Она их может не понять или вовсе зависнуть. " << endl << endl;
    cout << "ВПЕРЕД, КОМАНДИР ЧЕРЕПАХИ! ДЕЙСТВУЙ!" << endl << endl;
    while (command != 9)
    {
        cin >> command;
        switch (command)
        {
            case 1:
                pen = 1;
                break;
            case 2:
                pen = 2;
                break;
            case 3:
                turn++;
                break;
            case 4:
                turn--;
                break;
            case 5:
                cin >> step;
                turtleStep(floor, n, step);
                break;
            case 6:
                printFloor(floor, n);
                break;
            case 8:
                cout << "(" << x << ", " << y << ")" << endl;
                break;
            case 9:
                break;
            default:
                cout << "Черепаха вас не понимает :(" << endl;
                break;
        }
    }
 
    system("pause");
    return 0;
}
 
 
void turtleStep(int ground[][20], int a, int walk)
{
    if (turn >= 4 || turn <= -4)
        turn = turn % 4;
    if (turn < 0)
        turn = 4 + turn;
 
    switch (turn)
    {
        case 0:
            if (y + walk > 19)
            {
                cout << "Черепаха стоит и не хочет ударяться головой о стену" << endl;
                break;
            }
 
            if (pen == 1)
                y = y + walk;
            else
                for (int i = 0; i <= walk; i++)
                {
                    ground[x][y]++;
                    if (i < walk) 
                        y++;
                }
            break;
 
        case 1:
            if (x + walk > 19)
            {
                cout << "Черепаха стоит и не хочет ударяться головой о стену" << endl;
                break;
            }
 
            if (pen == 1)
                x = x + walk;
            else
                for (int i = 0; i <= walk; i++)
                {
                    ground[x][y]++;
                    if (i < walk)
                        x++;
                }
            break;
        case 2:
            if (y - walk < 0)
            {
                cout << "Черепаха стоит и не хочет ударяться головой о стену" << endl;
                break;
            }
 
            if (pen == 1)
                y = y - walk;
            else
                for (int i = 0; i <= walk; i++)
                {
                    ground[x][y]++;
                    if (i < walk)
                        y--;
                }
            break;
        case 3:
            if (x - walk < 0)
            {
                cout << "Черепаха стоит и не хочет ударяться головой о стену" << endl;
                break;
            }
 
            if (pen == 1)
                x = x - walk;
            else
                for (int i = 0; i <= walk; i++)
                {
                    ground[x][y]++;
                    if (i < walk)
                        x--;
                }
            break;
 
    }
}
 
 
void printFloor(int arr[][20], int size)
{
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            if (arr[i][j] > 0)
                cout << "*";
            else
                cout << " ";
 
        }
        cout << endl;
    }
}
Добавлено через 3 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Мимино, длину хода можно представить как количество закрашенных ячеек. В данном случае при вводе 5, закрашиваются все ячейки кроме той, где черепаха останавливается.
То есть реализовать можно в цикли вот так:

C++
1
2
for ( int i = 0; i < steps; i++ )
   floor[ x++ ][ y ] = true;
Хоть кто-то отозвался, спасибо. Я вот тоже сначала выбрал этот путь, но, опять же, как быть с перемещением на 1 шаг? В этом случае факт движения присутствует, а на положении черепахи это никак не отображается.
0
Toshkarik
1147 / 864 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
22.05.2013, 17:46 #17
Мимино, ну как же, она передвигается на 1 шаг. Закрашивает текущую клетку и сдвигается на следующую.
0
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
22.05.2013, 18:00 #18
Цитата Сообщение от Toshkarik Посмотреть сообщение
Мимино, ну как же, она передвигается на 1 шаг. Закрашивает текущую клетку и сдвигается на следующую.
Да, мысль понял. Но этот метод тоже немного "взрывает" мой мозг Объясню. Это равносильно тому, что перо поднимается при последнем шаге. Или, к примеру, если черепаху повернуть и сдвинуть на 1 шаг, это изменит траекторию черепахи, а на "графическом" отображении траектории это не будет заметно.
Я даже провел следующий опыт:
1. Разложил на полу 6 листов бумаги в ряд.
2. Взял бутылку с водой.
3. Встал на 1-й лист и приоткрыл бутылку, чтобы из нее текла вода (опустил перо).
4. Сделал 5 шагов.
Итог: траектория моего движения полностью отображена на полу, мокрые 6 листов, а не 5.
На чем я прокололся (мозг/выбор профессии не в счет)?
0
Toshkarik
1147 / 864 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
22.05.2013, 18:10 #19
Задание обучающее, и дано в книге для изучения массивов, если мне не изменяет память. Можно так же закрашивать все клетки, по которым прошла черепаха, суть то, в принципе, не в этом.
1
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
22.05.2013, 18:16 #20
Цитата Сообщение от Toshkarik Посмотреть сообщение
Задание обучающее, и дано в книге для изучения массивов, если мне не изменяет память. Можно так же закрашивать все клетки, по которым прошла черепаха, суть то, в принципе, не в этом.
Вот это уж точно +/- 1 тут особой роли не играет.
0
Turfur
0 / 0 / 0
Регистрация: 16.11.2014
Сообщений: 2
16.11.2014, 21:29 #21
Сделал криво, в том смысле что массив создается в функции main() и передается по ссылке функции interpritate(), что не вполне логично. Хотел исправить, но лень. Ах да, чуть не забыл, поменял цифры на мнемонические буквы, что-бы было не так мозголомно тестить. Также в моей версии отображается сама черепаха символом @.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define SIZE_OF_CANVAS 20
#define MAXPROG 501
 
enum direction {up,right,down,left};
 
static void move(enum direction dir, int * x, int * y, bool pero,char canvas[][SIZE_OF_CANVAS])
{
    if (pero)
        canvas[*x][*y] = '#';
    switch (dir)
    {
        case right:
            if ((*y+1) < SIZE_OF_CANVAS)
                (*y)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case left:
            if (*y > 0)
                (*y)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case up:
            if (*x > 0)
                (*x)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case down:
            if ((*x+1) < SIZE_OF_CANVAS)
                (*x)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
    }
}
 
static void show_canvas(char canvas[][SIZE_OF_CANVAS],int x,int y)
{
    int i,j;
    puts("");
    for (i = 0; i < SIZE_OF_CANVAS; i++)
    {
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            if ((i != x) || (j != y))
                putchar(canvas[i][j]);
            else
                putchar('@');
        putchar('\n');
    }
    puts("");
}
 
void interpritate(char * program, char canvas[][SIZE_OF_CANVAS])
{
    int x = 0,y = 0,i = 0;
    bool pero = false;
    enum direction dir = right;
    while (program[i] != '\n')
    {
        switch (program[i])
        {
            case 'p':
                pero = false; 
                break;
            case 'o':
                pero = true;
                break;
            case 'r':
                switch (dir)
                {
                    case right: dir = down; break;
                    case down: dir = left; break;
                    case left: dir = up; break;
                    case up: dir = right; break;
                }
                break;
            case 'l':
                switch (dir)
                {
                    case right: dir = up; break;
                    case down: dir = right; break;
                    case left: dir = down; break;
                    case up: dir = left; break;
                }
                break;
            case 'm':
                move(dir,&x,&y,pero,canvas);
                break;
            case 's':
                show_canvas(canvas,x,y);
                break;
            case 'e':
                show_canvas(canvas,x,y);
                return;
            default:
                printf("Syntax error\n");
                return;
        }
        i++;
    }
}
 
int main(int argc, char *argv[]) {
    char canvas[SIZE_OF_CANVAS][SIZE_OF_CANVAS],program[MAXPROG],i,j;
    for (i = 0; i < SIZE_OF_CANVAS; i++)
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            canvas[i][j] = ' ';
    printf("Enter program to turtle: \n");
    if (fgets(program,MAXPROG - 1,stdin) != NULL)
        interpritate(program,canvas);
    else
        printf("Error of input\n");
    system("pause");
    return 0;
}
Добавлено через 4 часа 2 минуты
Убрал пару статиков, ибо делалось в двух файлах. Теперь поле не из пробелов, а из точек. Добавлены команды видимости черепахи v и i, соответственно visible and invisible. Добавлены аргументы при m.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define SIZE_OF_CANVAS 20
#define MAXPROG 501
 
enum direction {up,right,down,left};
 
void move(enum direction dir, int * x, int * y, bool pero,char canvas[][SIZE_OF_CANVAS])
{
    if (pero)
        canvas[*x][*y] = '#';
    switch (dir)
    {
        case right:
            if ((*y+1) < SIZE_OF_CANVAS)
                (*y)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case left:
            if (*y > 0)
                (*y)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case up:
            if (*x > 0)
                (*x)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case down:
            if ((*x+1) < SIZE_OF_CANVAS)
                (*x)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
    }
}
 
void moven(enum direction dir, int * x, int * y, bool pero,char canvas[][SIZE_OF_CANVAS],int n)
{
    int i;
    for (i = 0; i < n; i++)
        move(dir,x,y,pero,canvas);
}
 
void show_canvas(char canvas[][SIZE_OF_CANVAS],int x,int y, bool visible)
{
    int i,j;
    puts("");
    for (i = 0; i < SIZE_OF_CANVAS; i++)
    {
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            if ((visible == true) && (x == i) && (y == j))
                putchar('@');
            else
                putchar(canvas[i][j]);
        putchar('\n');
    }
    puts("");
}
 
void interpritate(char * program, char canvas[][SIZE_OF_CANVAS])
{
    int x = 0,y = 0,i = 0;
    bool pero = false,visible = true;
    enum direction dir = right;
    while (program[i] != '\n')
    {
        switch (program[i])
        {
            case 'p':
                pero = false; 
                break;
            case 'o':
                pero = true;
                break;
            case 'r':
                switch (dir)
                {
                    case right: dir = down; break;
                    case down: dir = left; break;
                    case left: dir = up; break;
                    case up: dir = right; break;
                }
                break;
            case 'l':
                switch (dir)
                {
                    case right: dir = up; break;
                    case down: dir = right; break;
                    case left: dir = down; break;
                    case up: dir = left; break;
                }
                break;
            case 'm':
                i++;
                if (atoi((char []){program[i],'\0'}) != 0)
                    moven(dir,&x,&y,pero,canvas,atoi((char []){program[i],'\0'}));
                else
                    puts("Incorrect argument of \"m\"");
                break;
            case 's':
                show_canvas(canvas,x,y,visible);
                break;
            case 'v':
                visible = true;
                break;
            case 'i':
                visible = false;
                break;
            case 'e':
                show_canvas(canvas,x,y,visible);
                return;
            default:
                printf("Syntax error\n");
                return;
        }
        i++;
    }
}
 
int main(int argc, char *argv[]) {
    char canvas[SIZE_OF_CANVAS][SIZE_OF_CANVAS],program[MAXPROG],i,j;
    for (i = 0; i < SIZE_OF_CANVAS; i++)
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            canvas[i][j] = '.';
    printf("Enter program to turtle: \n");
    if (fgets(program,MAXPROG - 1,stdin) != NULL)
        interpritate(program,canvas);
    else
        printf("Error of input\n");
    system("pause");
    return 0;
}
0
gunslinger
случайный прохожий
1146 / 764 / 197
Регистрация: 20.07.2013
Сообщений: 2,137
16.11.2014, 22:31 #22
Можно считать, что черепаха рисует хвостом и при нахождении в текущей клетке (ячейке) касается предыдущей. Чтобы закрасить текущую, нужно сместиться в следующую.
При повороте можно допустить, что хвост касается границы между клетками, поэтому "левые" (не относящиеся к "пути следования", не путать с направлением) клетки не закрашиваются.
0
Turfur
0 / 0 / 0
Регистрация: 16.11.2014
Сообщений: 2
18.12.2014, 18:36 #23
От нечего делать добавил в предыдущую версию возможность писать комментарии, заключенные в c...c и циклы в виде fa...e где a - односимвольное число, означающее кол-во итераций(хотел сделать многосимвольное, но мне лень). Теперь все это работает в REPL режиме, а выход символом q вместо последовательности команд. Код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define SIZE_OF_CANVAS 21
#define MAXPROG 501
#define SIZE_OF_RBODY 20
 
enum direction {up,right,down,left};
 
void move(enum direction dir, int * x, int * y, bool pero,char canvas[][SIZE_OF_CANVAS])
{
    if (pero)
        canvas[*x][*y] = '#';
    switch (dir)
    {
        case right:
            if ((*y+1) < SIZE_OF_CANVAS)
                (*y)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case left:
            if (*y > 0)
                (*y)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case up:
            if (*x > 0)
                (*x)--;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
        case down:
            if ((*x+1) < SIZE_OF_CANVAS)
                (*x)++;
            else
            {
                puts("Out of canvas!\n");
                return;
            }
            break;
    }
}
 
void moven(enum direction dir, int * x, int * y, bool pero,char canvas[][SIZE_OF_CANVAS],int n)
{
    int i;
    for (i = 0; i < n; i++)
        move(dir,x,y,pero,canvas);
}
 
void show_canvas(char canvas[][SIZE_OF_CANVAS],int x,int y, bool visible)
{
    int i,j;
    puts("");
    for (i = 0; i < SIZE_OF_CANVAS; i++)
    {
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            if ((visible == true) && (x == i) && (y == j))
                putchar('@');
            else
                putchar(canvas[i][j]);
        putchar('\n');
    }
    puts("");
}
 
void interpritate(char * program, char canvas[][SIZE_OF_CANVAS],int * x,int * y,bool * pero,bool * visible,enum direction * dir)
{
    int i = 0;
    while (program[i] != '\n')
    {
        switch (program[i])
        {
            case 'p':
                *pero = false; 
                break;
            case 'o':
                *pero = true;
                break;
            case 'r':
                switch (*dir)
                {
                    case right: *dir = down; break;
                    case down: *dir = left; break;
                    case left: *dir = up; break;
                    case up: *dir = right; break;
                }
                break;
            case 'l':
                switch (*dir)
                {
                    case right: *dir = up; break;
                    case down: *dir = right; break;
                    case left: *dir = down; break;
                    case up: *dir = left; break;
                }
                break;
            case 'm':
                i++;
                if (atoi((char []){program[i],'\0'}) != 0)
                    moven(*dir,x,y,*pero,canvas,atoi((char []){program[i],'\0'}));
                else
                    puts("Incorrect argument of \"m\"");
                break;
            case 's':
                show_canvas(canvas,*x,*y,*visible);
                break;
            case 'v':
                *visible = true;
                break;
            case 'i':
                *visible = false;
                break;
            case 'c':
                i++;
                while (program[i] != 'c')
                    i++;
                break;
            case 'f':
                i++;
                if (atoi((char []){program[i],'\0'}) != 0)
                {
                    char body[SIZE_OF_RBODY],n = atoi((char []){program[i],'\0'}),j = 0;
                    i++;
                    while (program[i] != 'e')
                    {
                        body[j] = program[i];
                        j++;i++;
                    }
                    body[j] = '\n';
                    body[j+1] = '\0';
                    for (j = 0; j < n; j++)
                        interpritate(body,canvas,x,y,pero,visible,dir);
                }
                else
                    puts("Incorrect argument of \"f\"");
                break;
            default:
                printf("Syntax error\n");
                return;
        }
        i++;
    }
}
 
int main(int argc, char *argv[]) {
    char canvas[SIZE_OF_CANVAS][SIZE_OF_CANVAS],program[MAXPROG],i,j;
    int x = 0,y = 0;
    bool pero = false,visible = true;
    enum direction dir= right;
    for (i = 0; i < SIZE_OF_CANVAS; i++)
        for (j = 0; j < SIZE_OF_CANVAS; j++)
            canvas[i][j] = '.';
    while (1)
    {
        printf("Enter program to turtle: \n");
        if (fgets(program,MAXPROG - 1,stdin) != NULL)
            if (strcmp(program,"q\n"))
                interpritate(program,canvas,&x,&y,&pero,&visible,&dir);
            else
                break;
        else
            printf("Error of input\n");
    }
    puts("Bye!");
    system("pause");
    return 0;
}
Полный набор команд:
p - поднять перо,
o - опустить перо,
r - повернуть направо,
l - повернуть налево,
ma - сдвинуться на a шагов вперед(a - односимвольное),
s - отобразить холст на момент вызова,
v - сделать черепаху видимой,
i - сделать черепаху невидимой,
fa..e - цикл из a итераций с телом вместо ..(a - односимвольное),
c..c - комментарии,
q - выход из программы. Работает только если подан в качестве единственного символа, иначе будет воспринят как синтаксическая ошибка.
0
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 539
Завершенные тесты: 1
29.04.2016, 21:55 #24
Кликните здесь для просмотра всего текста
[CPP][static int nowX = 5;
static int nowY = 5;

static int lastX = 6;
static int lastY = 5;

if( way == 0 )//dvishenie vpravo
{
if( (nowX == lastX - 1) && (nowY == lastY) )
{
lastX = nowX;
lastY = nowY;
nowY++;
if( feather == 1 )
array[ nowX ][ nowY ] = 1;
return 0;
}
if( (nowX == lastX) && (nowY == lastY + 1) )
{
lastX = nowX;
lastY = nowY;
nowX++;
if( feather == 1 )
array[ nowX ][ nowY ] = 1;
return 0;
}
if( (nowX == lastX + 1) && (nowY == lastY) )
{
lastX = nowX;
lastY = nowY;
nowY--;
if( feather == 1 )
array[ nowX ][ nowY ] = 1;
return 0;
}
if( (nowX == lastX) && (nowY == lastY - 1) )
{
lastX = nowX;
lastY = nowY;
nowX--;
if( feather == 1 )
array[ nowX ][ nowY ] = 1;
return 0;
}
}
/CPP]
Дошёл до этой задачи у Дейтела и оказался в ступоре, если честно, если с выборам ещё понятно, что нужно применить либо
C++
1
else if
, либо
C++
1
switch
то с движением полная ..опа. Вот этот кусок кода мне не понятен, как это, Грубо говоря это координаты X и Y так? начало и конец соответственно, так? Это как в декартовой системе координат X это всё, что относится к координатам по горизонтали, а Y соответственно всё что относится к координтам по вертикали, так? Помогите разобраться для начала с этим или направте на статью где доходчиво описано это всё?
0
29.04.2016, 21:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.04.2016, 21:55
Привет! Вот еще темы с ответами:

Рисование графика: обработка новых входящих данных и движение графика на форме - C#
Подскажите каким способом можно вывести график частью главного окна программы, при чем график получает данные *в живую* с устройства по...

Автоматическое изменение графика при переносе данных, формулы и графика на другой лист - MS Excel
На первом листе, на основании каких-либо вычислений строим график, а затем полностью копируем первой лист на второй, а затем изменяем...

Совмещение поточечного графика и графика построенного функцией на отрезке - Mathematica
Есть некий массив array1 = {...} и func = y /. NDslove По отдельности строю так: Plot и ListLogPlot Как их совместить? ...

Построение графика производной для каждого графика из 3 режимов - Matlab
Дорогие друзья, прошу помочь доделать три программы. В каждой программе выводится по одному графику и нужно чтобы каждая программа выводила...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
24
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.