Съдържание:

Интересни ръководства за програмиране за дизайнер-Контрол на процеса на програмата-Изявление за цикъл: 8 стъпки
Интересни ръководства за програмиране за дизайнер-Контрол на процеса на програмата-Изявление за цикъл: 8 стъпки

Видео: Интересни ръководства за програмиране за дизайнер-Контрол на процеса на програмата-Изявление за цикъл: 8 стъпки

Видео: Интересни ръководства за програмиране за дизайнер-Контрол на процеса на програмата-Изявление за цикъл: 8 стъпки
Видео: CS50 2013 - Week 2, continued 2024, Ноември
Anonim
Интересни ръководства за програмиране за дизайнер-Контрол на програмния процес-констатация за цикъл
Интересни ръководства за програмиране за дизайнер-Контрол на програмния процес-констатация за цикъл

Контрол на програмния процес- цикъл

От тази глава ще се свържете с важна и мощна декларация за точката на знанието.

Преди да прочетете тази глава, ако искате да нарисувате 10 000 кръга в програмата, можете да направите само с ужасен метод. Това означава да напишете 10 000 реда елипсов код. Тези мързеливи дизайнери на код, които искат да подобрят ефективността по всякакъв начин, определено не биха позволили това да се случи. Така че се създава цикъл. С това изявление можете интуитивно да усетите силата на компютърната автоматизация.

Стъпка 1: За цикъл

Има много циклични изявления, сред които най -широко използваният е For Loop. Всички знаем, че функцията за изтегляне непрекъснато работи в обращение. Започнете от първото изречение в началото, то ще се прилага отгоре надолу до последното изречение. След като приключи операцията, тя ще започне отново от първото изречение. За изявлението е малко подобно на функцията draw. Кодът в рамките на оператора for може да се изпълнява многократно.

Ето неговата граматическа структура:

За (израз 1; израз 2; израз 3) {

Примково тяло

}

Очевидно изреченията в тялото на цикъла са това, което очаквахме да бъдат приложени многократно. Израз 1 се използва за инициализиране и присвояване на първата стойност на променливата на цикъла. Израз 2 е за условие на цикъл. Израз 3 ще актуализира стойността на променливата на цикъла.

Какво е променлива на цикъла? Всъщност тя е еквивалентна на локална променлива. Нека да разгледаме цялостно писане.

за (int i = 0; i <10; i ++) {

Примково тяло

}

За да се реализира циклична функция, операторът for разчита главно на локална променлива, която ще се използва при прекратяване на цикъла. Локалната променлива в горния пример е i. Израз 1 завърши инициализацията на локална променлива. По -късно, всеки път, когато цикълът работи веднъж, тази променлива трябва да се актуализира. Сред горния пример i ++ в израз 3 се използва за реализиране на функция за актуализация. Чрез него променливата ще се увеличава с 1 при всяко актуализиране. В крайна сметка кодът в тялото на цикъла не може да се циклира за неопределено време, в противен случай последните изявления не могат да бъдат изпълнени. По този начин се нуждаем от терминално условие. Express 2 е точно за него. Тук програмата ще прецени дали i е по -малко от 10. Ако е така, продължете да работите. Ако не е, тогава излезте от цикъла.

Следователно последователността на операциите на оператора for е точно такава.

Израз 1 (Инициализация на локална променлива)

Израз 2 (удовлетворен, след това продължете да работите)

Корпус на цикъла (първа циркулация)

Израз 3 (актуализация)

Израз 2 (удовлетворен, след това продължете да работите)

Цикъл на тялото (Втора циркулация)

Израз 3 (актуализация)

Израз 2 (удовлетворен, след това продължете да работите)

Корпус на цикъла (трета циркулация)…

Израз 3 (актуализация)

Израз 2 (Не е удовлетворен, след това излезте от цикъла)

Можете да симулирате тази последователност на изпълнение в главата си няколко пъти. Но е невъзможно наистина да разберете кода, без да го напишете с ръка веднъж. Когато искаме да открием странна концепция, можем да отпечатаме стойността в конзолата чрез оператора println.

Пример за код (5-1): void setup () {

за (int i = 0; i <10; i ++) {

println ("run");

}

}

Можете да преброите броя на изпълненията в конзолата. Тук е точно 10. Това ви показва колко пъти е изпълнен кодът в тялото на цикъла. Все още обаче не можем да открием какви промени всъщност са се случили в цикъла. Така че можем да опитаме да променим символа „run into variable“i “и да видим какво ще се случи.

Пример за код (5-2): void setup () {

за (int i = 0; i <10; i ++) {

println (i);

}

}

Сега можем да видим, че стойността i в тялото на цикъла непрекъснато се увеличава. По -късно можем да използваме тази стойност, за да разберем текущия процес на цикъла.

В пример за код (5-2) стойността на i се променя от 0 на 9. В сравнение с действителните времена на цикъла, изглежда, че винаги има 1 по-малко. Ако не сте свикнали с него, изразът в скобите на оператора for може да бъде записан на следното:

за (int i = 1; i <= 10; i ++)

По този начин i справедливо съответства на времената на цикъла. Значението на "<=" е по -малко и равно на. Така че, когато i е равно на 10, той все още ще отговаря на условието. Следователно, той ще работи още веднъж в сравнение с писането в i <10. Въпреки че започва от 1, времената на цикъла са все още 10. Разбира се, ако не е необходимо нищо специално, бих искал да ви предложа да приемете метода на писане в пример в началото. По -късно ще ви представим вектор или масив, като и двамата получават своя елемент чрез неговия индекс. И дефолтните индекси всички започват от 0. Да се определи първоначалната стойност да бъде 0 е сравнително обичайната практика.

В горния пример, ако напишем i е отвъд 0, пограмата ще се срине. Тъй като променливата се увеличава постоянно, тя никога няма да удовлетвори това условие. Това е точно така, сякаш никога не може да бъде спряно, така че програмата да работи в безкраен цикъл.

Локалните променливи в израза for могат не само да декларират пластмасови типове, но и да декларират променливи в типове с плаваща запетая. Например, тя може да бъде записана като (float i = 0; i <10; i + = 0.02).

Стъпка 2: Използвайте за цикъл за решаване на математически задачи

Помните ли още история на математик Гаус в детството му? По това време Гуас беше на 10 години. Неговият учител искаше да възложи задача в класа и въпросът беше

1+2+3+4……+97+98+99+100=?

Ако изчислявате с ръцете си, това ще ви отнеме много време. Но изглежда, че Guass вече е разбрал метода за сумиране на аритметичната последователност. Затова веднага след като въпросът беше зададен, той изговори отговора с лекота, което силно изненада учителя му.

Може би все още не помним какво е сумирането на аритметичната последователност, но можем да получим отговора по примитивен и насилствен начин. И това е за цикъл. Тъй като компютрите са само малка част, която компютрите могат да преброят, трябва да опишем въпроса на език, който може да бъде разпознат от компютъра, след което лесно можем да получим отговора си.

Пример за код (5-3):

void setup () {

int отговор = 0;

for (int i = 1; i <= 100; i ++) {

отговор += i;

}

println (отговор);

}

Вярвам, че резултатът, който получавате, е същият като отговора, докладван от Guass: той е 5050!

Съвети: Името на локалните променливи в цикъла for може да се променя по желание при условие, че то спазва правилата за именуване на променливите. Можете да го напишете да бъде (int k = 1; k <= 100; k ++). Ако не са настъпили специални условия, по подразбиране i е името на променливата.

Стъпка 3: За рисуване на контур

След поредица от изглеждащи скучни постелки, най -накрая можем да влезем в по -интересен раздел. Това означава да използвате for loop за рисуване на снимки. Вече можем да оставим настрана тези досадни математически изчисления. Ние, дизайнерите, сме по -чувствителни към графиката.

Използвайте за цикъл за начертаване на кръгов масив

Когато искаме да използваме цикъл for за представяне на група от повтарящи се елементи, трябва предварително да се уверим в числовото отношение на тези елементи, след което можем да използваме for цикъл, за да го реализираме удобно, вместо да правим масивна повторна работа. Да предположим, че ако искаме да нарисуваме ред кръг, еднакво разпръснат в хоризонтална посока. Неговата виртуална координата е непроменена, докато хоризонталната ѝ се променя. И отляво надясно хоризонталната координата непрекъснато се увеличава и увеличаващото се разстояние е същото. По това време можем да използваме i in for цикъл, за да получим хоризонталната координата на всеки кръг.

Пример за код (5-4): void setup () {

размер (700, 700);

фон (83, 51, 194);

noStroke ();

}

void draw () {

за (int i = 0; i <7; i ++) {

елипса (50.0 + i * 100.0, височина/2.0, 80.0, 80.0);

}

}

50 означава началната позиция на първия кръг вляво. 100 в i * 100 представлява увеличаващото се разстояние.

Стъпка 4: Използвайте за цикъл, за да нарисувате произволна кръгла точка

Горната графична позиция е предвидима. Това ще намали много интереса. Можем да използваме функция random, която споменахме в предишната глава, и да се опитаме да я запишем във функция за рисуване.

Пример за код (5-5):

void setup () {

размер (700, 700);

фон (0);

noStroke ();

}

void draw () {

фон (0);

за (int i = 0; i <10; i ++) {

float randomWidth = случаен (60.0);

елипса (произволна (ширина), произволна (височина), произволна ширина, произволна ширина);

}

}

Тук причината, поради която позицията на кръга непрекъснато мига, е, че всеки път, когато функция случайно работи за веднъж, резултатът е случаен. Тъй като функцията за чертане на функции е зададена по подразбиране за изпълнение на 60 кадъра в секунда, така че всеки 10 кръга, нарисувани за секунда, ще променят позицията си за 60 пъти. Тази бърза светкавица прави картината да има повече от 10 кръга. Промяната на проста стойност в програмата ще ви донесе напълно различен ефект. Можем да променим времената на цикъла, като преразгледаме условието на терминала. Терминалното състояние на снимката по -долу е i <100

  1. Ето ефекта, когато терминалното състояние е i <1000:
  2. RandomSeed
  3. Ако не искам позицията на кръга да се генерира на случаен принцип, както и неговата светкавица, какво мога да направя? Един от методите е да се създават и съхраняват независими променливи за всеки кръг и да се инициализират тези променливи в настройката. Задайте на тези променливи случайна стойност. По този начин, когато използваме функция за рисуване в рамките на draw, това, което извикахме, е стойността, съхранявана в променливи. Тя няма да се промени по всяко време. За да нарисуваме 10 кръга, можем просто да използваме този метод. Но какво ще стане, ако искаме да нарисуваме 1000 кръга или 10 000 кръга? Ще бъде доста обезпокоително, ако използваме този традиционен метод за изграждане на тези променливи и го наречем. Не е нужно да научаваме нов метод за изграждане на променлива. Ето един гъвкав метод, който може да ни помогне да постигнем тази цел. Това означава да използвате randomSeed. Нека сега разгледаме ефекта му след употреба. Пример за код (5-6): [cceN_cpp theme = "dawn"] void setup () {размер (700, 700); фон (0); noStroke ();}
  4. void draw () {

    фон (0);

    randomSeed (1);

    за (int i = 0; i <10; i ++) {

    float randomWidth = случаен (20.0, 60.0);

    елипса (произволна (ширина), произволна (височина), произволна ширина, произволна ширина);

    }

    } [/cceN_cpp]

    В сравнение с кода преди, той няма никакви промени, освен да промени радиуса на кръга от 10 на над 30 с изречение само на SeedRandom. След добавянето на това изречение графиката изглежда статична.

    Формат за извикване:

    randomSeed (а);

    Сред този формат настройката на a е начална. Трябва да попълните цяло число (напишете стойност на плаващата точка в P5, няма да се обърка, но да го третирате като цяло число) в него. Функцията на randomSeed е да зададе началната стойност за случайна стойност. Тогава той ще генерира различен случаен масив според различните семена. След него извикваме функция random, така че резултатът от връщането да е определен. Тук определеното не е за резултата е определена стойност, а за генерирания масив. Това означава, че резултатът от връщането е определен спрямо времето на извикване.

    Пример за код (5-7): [cceN_cpp theme = "dawn"] void setup () {

    randomSeed (0);

    for (int i = 0; i <5; i ++) {

    println (случаен (10));

    }

    } [/cceN_cpp]

    Сега продължаваме да използваме println, за да направим експеримент. След като използвате randomSeed, всеки път, когато затворите програмата и рестартирате програмата, тя ще се върне към низ със същия резултат. Стойността ще съответства на последователността една по една. Ако го изтриете, всеки път ще се върне към различна стойност. Защо има тази настройка? Това е така, защото самата случайна стойност в програмата е псевдослучайна. Резултатът изглежда случаен, но всъщност се генерира чрез фиксиран и повтарящ се метод за изчисление. Еквивалентно е да се определи примитивна стойност за randomSeed, след което следният резултат ще бъде изчислен според това начало. Ако обаче не посочим семето, програмата по подразбиране ще използва настоящото време на системата за генериране на семена. Следователно резултатът от всяка операция е различен. Примерът по -долу може да ви помогне да разберете по -добре randomSeed.

    Примерен код (5-8): [cceN_cpp theme = "dawn"] void setup () {

    размер (700, 700);

    фон (0);

    noStroke ();

    }

    void draw () {

    randomSeed (1);

    за (int i = 0; i <10; i ++) {

    float randomWidth01 = случаен (10, 60);

    елипса (произволна (ширина), произволна (височина), произволна ширина01, произволна ширина01);

    println (randomWidth01);

    }

    randomSeed (1);

    за (int i = 0; i <10; i ++) {

    float randomWidth02 = случаен (10, 60);

    елипса (произволна (ширина), произволна (височина), произволна ширина02, произволна ширина02);

    println (randomWidth02);

    }

    } [/cceN_cpp]

    Опитайте се да преразгледате втория randomSeed (1) към randomSeed (0) и сравнете крайните резултати.

    Съвети: В P5 трябва само да извикаме функция noLoop в края на тегленето, за да постигнем същия ефект. Неговата функция е да прекрати програмата. Той е доста различен от горните принципи на работа по своята същност.

Стъпка 5: Използвайте за линия за начертаване на линия

След като усвоим използването на randomSeed, можем да опитаме да променим функцията за рисуване. Например, променете чертежа на кръг в чертеж. Само ако проектираме някои променящи се правила до края на реда, можем да използваме много линии, преплетени, за да направим уникален модел.

Пример за код (5-9):

[cceN_cpp theme = "dawn"] void setup () {

размер (700, 700);

фон (0);

}

void draw () {

randomSeed (0);

for (int i = 0; i <2000; i ++) {

поплавък x1 = ширина/2,0;

поплавък x2 = случаен (50.0, 650.0);

ход (255, 20);

ред (x1, 50, x2, 650);

}

} [/cceN_cpp]

Създайте проста четка

Обратно към цикъла for отново. Горните примери не са интерактивни. Ако искаме да направим резултата по -интересен, не можем да забравим да комбинираме mouseX и mouseY в нашия код.

Пример за код (5-10):

[cceN_cpp theme = "dawn"] void setup () {

размер (700, 700);

фон (255);

noStroke ();

}

void draw () {

for (int i = 0; i <1000; i ++) {

попълнете (0, 30);

float x = mouseX + random (-50, 50);

float y = mouseY + random (-50, 50);

елипса (x, y, 2, 2);

}

} [/cceN_cpp]

Създава се четка "точки на разсейване". Тъй като всяка интензивна мини кръгла точка е базирана на позицията на мишката, тя може да премества ограничени посоки от четирите посоки наляво, надясно, нагоре и надолу. Така че окончателното разпределение на формата на четката е подобно на квадрат.

Пример за код (5-11):

[cceN_cpp theme = "dawn"] void setup () {

размер (700, 700);

фон (255);

noStroke ();

}

void draw () {

за (int i = 0; i <1000; i ++) {

float ratio = mouseX/(float) width;

float x = mouseX + random (-50, 50);

float y = mouseY + random (-50, 50);

попълнете (0, съотношение * 255, 255 * (1 - съотношение), 30);

елипса (x, y, 2, 2);

}

}

[/cceN_cpp]

Ако използваме стойността на mouseX, за да повлияем на цвета на пълнежа, тогава ще получим много по -магически цветен градиент.

Стъпка 6: За вмъкнат цикъл

For цикълът може да бъде вложен. Можете да напишете цикъл for отново в цикъла for. Когато трябва да нарисувате двуизмерна матрица с точки, можете да изберете този метод.

Пример за код (5-12):

[cceN_cpp theme = "dawn"] void setup () {

размер (700, 700, P2D);

фон (202, 240, 107);

}

void draw () {

попълнете (0);

for (int i = 0; i <5; i ++) {

за (int j = 0; j <5; j ++) {

поплавък x = 150 + i * 100;

поплавък y = 150 + j * 100;

елипса (x, y, 60, 60);

println (i + ":" + j);

}

}

}

[/cceN_cpp]

За да използвате вложения цикъл за първи път, трябва да разберете неговите логически отношения. Изпълнението на кода в програмата винаги е от горе до долу. Следователно първият реализиран определено е най -външният цикъл. Всеки път, когато външният контур работи веднъж, вътрешният контур ще работи непрекъснато, докато не може да удовлетвори повече условието. След това ще стартира втората външна циклична операция. След като стартира втората операция, вътрешният контур ще продължи на машината, докато не може да задоволи условието. Такова повторение прави, докато не могат да бъдат изпълнени всички условия и изскочи от цикъла.

В горния код тялото на цикъла във външния контур е работило общо 5 пъти, докато тялото на цикъла във вътрешния контур е работило 25 пъти. В рамките на 25 пъти, в зависимост от разликата в стойността i, j, можем да осигурим хоризонталната и вертикалната координата на окръжността отделно. Вградих част от печат, можете да наблюдавате изхода на данни и да мислите за промяната му. Само с два вложени цикъла можем да изпитаме всички комбинации от i, j данни.

Съвети

For цикълът във втория слой обикновено се кондензира с Tab в началото. Това може да направи структурата на кода по -ясна. Трябва да назовете локални променливи в двата слоя for for с различни имена. Сред него най -често се използват „i“, „j“, „k“.

Гъвкаво използване "i", "j"

Името на двете променливи на "i", "j" представляват локални променливи на двата слоя цикъл for. Примерът по -долу ще задълбочи разбирането ви за „i“„j“. Според различните стойности на "i", "j" можем да въведем параметри за групиране на елементите.

Пример за код (5-13): [cceN_cpp theme = "dawn"] void setup () {

размер (700, 700);

фон (0);

noStroke ();

}

void draw () {

фон (0);

попълнете (250, 233, 77);

за (int i = 0; i <7; i ++) {

за (int j = 0; j <7; j ++) {

pushMatrix ();

превод (50 + i * 100, 50 + j * 100);

// Настройка 1

// поплавъчен ъгъл = sin (millis ()/1000.0) * PI/2;

// Настройка 2

// плаващо съотношение = i/7,0;

// поплавъчен ъгъл = sin (millis ()/1000.0 + съотношение * (PI/2)) * PI/2;

// Настройка 3

плаващо съотношение = (i * 7 + j)/49,0;

ъгъл на плаване = sin (милис ()/1000.0 + съотношение * (PI/2)) * PI/2;

завъртане (ъгъл);

rectMode (ЦЕНТЪР);

// Начертайте снимка 1

правоъгълник (0, 0, 80, 80);

// Начертайте снимка 2

// правоъгълник (0, 0, 100, 20);

// Начертайте снимка 3

// rect (0, 0, ratio * 50);

popMatrix ();

}

}

} [/cceN_cpp]

Код Обяснение

rectMode (CENTER) може да промени метода на чертане на квадрат. Оригиналните предишни два параметъра на правоъгълник се използват за определяне на координатата на горния ляв ъгъл на квадрат. След като стартираме тази команда, тези два параметъра ще бъдат използвани за задаване на координатата за квадратната централна точка. Тъй като тук работим с въртенето на paterrn чрез завъртане, затова трябва да използваме този метод, за да привлечем централната точка към първоначалната точка на координатата.

millis () получава времето от стартирането на програмата до настоящия момент. Единицата е ms. Тази стойност ще повлияе на променящата се скорост на изходната стойност на sin. Ако пишем милис директно, променящият се мащаб е твърде голям. По този начин трябва да го разделим на 1000.0.

В този раздел на кода използваме символа за коментар "//", за да скрием няколко настройки. Можете да промените ефектите чрез стартиране или затваряне. Например, ако започваме изречения зад „Настройка 3“, трябва да използваме символа за коментар, за да затворим кодовите блокове преди „Настройка 1“и „Настройка 2“. Що се отнася до примери за тази подобна програмна структура с различни локални променливи, можем да пишем в този формат. По този начин не е нужно да съхраняваме няколко инженерни документа отделно. Можем да използваме това умение често по време на практика и създаване и да запазим някои задоволителни настройки на параметри.

Сред тях влиянието на i, j стойността върху програмата се представя главно чрез изместване на „Настройка 1 (Настройка 2) (Настройка 3)“. Можете да сравните резултатите по -долу.

Начертайте снимка 1: Настройка 1

Начертайте снимка 1: Настройка 2

Начертайте снимка 1: Настройка 3

Начертайте снимка 2: Настройка 1

Начертайте снимка 2: Настройка 2

Начертайте снимка 2: Настройка 3

При настройка 1 не сме използвали i и j, за да повлияем на ъгъла на завъртане на всеки елемент. Така можем да видим, че движението на всеки елемент е едно и също. Докато в настройка 2, ние използвахме i стойност и i i и j в настройка 3. Накрая те повлияха на въвеждането на параметър на функцията sin through ratio. Това промени периодичната промяна на ъгъла. Поради действителния ефект от настройка 2 и настройка 3 не е толкова очевиден в анимираните графики, можем да го наблюдаваме от следната екранна снимка.

Начертайте снимка 2 (вляво: настройка 2; вдясно: настройка 3)

Начертайте снимка 3 (вляво: настройка 2; вдясно: настройка 3)

На първата снимка съотношението се използва, за да повлияе на квадратния ъгъл на завъртане. Докато втората картина, тя трябва да контролира радиуса на кръга директно. Можем да видим, че е използвал i value изречение:

плаващо съотношение = i/7,0;

Неговата промяна на елемента на вертикала е последователна. Тъй като хоризонталната координата за управление на картината зависи само от стойността на i, така че шаблоните със същата хоризонтална координата ще бъдат еднакви. Стойността на съотношението, ъгъла на завъртане и радиуса на окръжността също са еднакви.

В същото време използваме i, j изречение:

плаващо съотношение = (i * 7 + j)/49,0;

Той може да опише "градиент". Тук, с метода за умножение на коефициент, той комбинира влиянието на редове и колони. Така че всеки елемент е различен.

Стъпка 7: Докато Loop

Има брат за for цикъл. Това е цикъл while. Какво може да направи цикълът, докато цикълът също може да го направи. Но честотата на използване на цикъл while в creativeCoding не е висока като при цикъл.

Пример за код (5-14): [cceN_cpp theme = "dawn"] void setup () {

int a = 0;

while (a <10) {

println (a);

а ++;

}

} [/cceN_cpp]

Граматичната структура на while е по -лесна за разбиране, отколкото за. Можем да създадем променливи преди оператора while. След това попълнете израз в квадратна скоба. Когато е удовлетворено, тогава оперирайте изреченията в тялото на цикъла. Накрая поставяме израз в тялото на цикъла, за да актуализираме променливите, след което цикълът е завършен. Що се отнася до гарантираните времена на цикъл, ние често използваме for цикъл. Що се отнася до стойността на неопределена променлива, препоръчваме ви да използвате while цикъл.

Мисля:

Опитайте се да използвате всички видове основни елементи, за да замените чертожните елементи във цикъл за създаване на различни различни четки.

Комбинирайте с тригонометрична функция, спомената в последната глава, опитайте се да преработите четката „точки на разсейване“в четка с кръгла форма.

Опитайте се да направите двуизмерна точкова матрица само с цикъл for.

Следваща глава Предварителен преглед Тъй като с този курс ще откриете всички нови знания, които научите, възможността за игра веднага ще се увеличи много. Програмата е кутия за Пандора. Всичко, което можете да си представите, може да го направи за вас. Така че няма причина да не научим този език, който може да комуникира с компютри. В следващата ни глава ще ви представим друго изявление за управление на процеса. Той може да контролира потока на процеса и да генерира по -сложни и променливи резултати. С изявлението if можете да създавате свои собствени текстови приключенски игри с лекота! Тази статия идва от дизайнера Wenzy. Относителни четения: Интересни ръководства за програмиране за дизайнер-Обработка на първоначално докосване Интересно ръководство за програмиране за дизайнер-Създайте първата си програма за обработка Интересно ръководство за програмиране за дизайнер –Покарайте снимката си (първа част) Интересни ръководства за програмиране за дизайнер - стартирайте снимката си (втора част)

Стъпка 8: Източник

Тази статия е от:

Ако имате въпроси, можете да се свържете с: [email protected].

Препоръчано: