В предыдущих постах я:
* Рассказал о том, как как нарисовать равнобедренный треугольник в консоли с помощью звёздочек, и описал проблему создания рисунка, похожего на ель.
* Рассмотрел простой алгоритм отрисовки ёлки, заключающийся в удвоении каждой строки.
Постановка задачи
Последний (и самый, на мой взгляд, интересный) способ отрисовки ели заключается в следующем. Я рисую в строке количество звёздочек, равное номеру строки. Для того, чтобы ель сохраняла некоторую симметричность, я сдвигаю каждую чётную строку вправо на 1 символ.
В итоге, должно получиться следующее:
01 X
02 **
03 ***
04 ****
05 *****
06 ******
07 *******
08 ********
09 *********
10 **********
12 ##
13 ##
Реализация
Для начала, зададим цвет для звезды на верхушке ели, цвет для самой ели и цвет для ствола дерева. Несмотря на то, что программа будет работать в консоли, это не проблема - можно использовать управляющие символы. О них можно прочитать, например, здесь:
http://www.linuxjournal.com/article/8603
Чтобы каждый раз не писать управляющие последовательности для задания цвета строки, я решил поступить следующим образом:
#include <stdio.h>
#define N 15
int main() {
char c_red[N] = "\033[49;31;5m"; // Красный
char c_green[N] = "\033[49;32;5m"; // Зелёный
char c_yellow[N] = "\033[49;33;5m"; // Жёлтый
char c_reset[N] = "\033[0;0;0m"; // Возврат к первоначальным
// значениям
// ...
}
Теперь я могу использовать более осмысленные названия цветов в вызове функции printf(), например:
printf("%sHello %sWorld%s\n", c_yellow, c_green, c_reset);
Дабы сократить количество вычислений в циклах, заведу дополнительную переменную half_base_width, в которой буду хранить результат деления ширины ели, заданной пользователем, на 2.
int base_width, half_base_width;
int i, j;
printf("Please enter height of the fir-tree:\n> ");
scanf("%d", &base_width);
half_base_width = base_width / 2;
for(i = 1; i <= base_width; i++) {
/* Печатаю номер строки */
printf("%s%02d\t", c_red, i);
/* Печатаю одну линию */
for(j = 1; j < (half_base_width + (i / 2) + 1); j++) {
if(((i % 2) > 0) && (j < (half_base_width - (i / 2))) ||
((i % 2) == 0) && (j <= (half_base_width - (i / 2))))
putchar(' ');
else
if(i == 1)
printf("%sX", c_red); // Большая звезда на верхушке
else
printf("%s*", c_green); // Ель
}
putchar('\n');
}
Для повышения реалистичности, в завершении отрисовки ёлки нарисую ещё ствол дерева.
for(i = base_width + 1;
i < (base_width + base_width / 10 * 3); i++) {
printf("%s%02d\t", c_red, i);
for(j = 0; j <= half_base_width + (base_width / 10) / 2; j++)
if(j < half_base_width - (base_width / 10))
putchar(' ');
else
printf("%s#", c_yellow);
putchar('\n');
}
Значение (base_width + base_width / 10 * 3) используется для задания высоты ствола в зависимости от высоты ели. Значение half_base_width + (base_width / 10) / 2 и half_base_width - (base_width / 10) используется для задания ширины ствола.
В итоге, ель у меня выглядит вот так:
Комментариев нет:
Отправить комментарий