Processing math: 100%

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Час 9 - гранање и петље у петљама

Наизменично смењивање облика или боја

У многим ситуацијама су цртежи такви да се наизменично смењују два правила на основу којих се црта. На пример, ако желимо да нацртамо „црта-тачка” линију, тада у непарним корацима цртамо црте, а у парним тачке. Размотримо неколико примера цртежа у којима се јавља овај облик правилности и прикажимо неке могућности да се такви цртежи нацртају.

Жуто-зелени квадрати

Напиши програм који ширину екрану попуњава помоћу 10 квадратића, пет жутих и пет зелених, који се наизменично ређају почевши од жутог.

 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (500, 100) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Квадрати - наизменично мењање боја")
6
7
# broj kvadrata koje treba iscrtati
8
broj_kvadrata = 10
9
# širina i visina jednog kvadrata
10
dimenzija_kvadrata = sirina / broj_kvadrata
11
# vertikalna sredina ekrana
12
sredina = visina / 2
13
14
for i in range(0, broj_kvadrata):
15
    # boja zavisi od toga da li je redni broj kvadrata paran ili neparan
16
    if ???:
17
        boja = pg.Color("yellow")
18
    else:
19
        boja = pg.Color("green")
20
    # koordinate gornjeg levog temena
21
    (levo, gore) = (???, ???)
22
    # crtamo kvadrat
23
    pg.draw.rect(prozor, boja, (levo, gore, dimenzija_kvadrata, dimenzija_kvadrata))
24
25
# prikazujemo prozor i čekamo da ga korisnik isključi
26
pygamebg.wait_loop()
27

(kvadratici_naizmenicno)

Пошто знамо укупан број квадрата и ширину целог екрана дуж око којег су они распоређени, ширину једног квадрата можемо једноставно израчунати дељењем укупне ширине бројем квадрата. Квадрате цртамо у петљи. Ако вредност бројачке променљиве почиње од 0, тада се координата x левог горњег темена i-тог квадрата може добити множењем ширине квадрата бројем i (заиста, ако је ширина квадрата a, тада квадрати редом почињу на координатама 0,a,2a,,(n1)a. Координата y горњег левог темена сваког квадрата се добија одузимањем половине висине квадрата од средине екрана (коју израчунавамо дељењем висине екрана са два). На тај начин се вертикално средиште квадрата налази на средини екрана. На крају, боју квадрата можемо одредити у зависности од парности редног броја квадрата који се црта. Када је бројач у петљи i паран (када му је вредност 0, 2, 4, 6 или 8, што можемо израчунати поређењем остатка при дељењу i % 2 са нулом) тада квадрат бојимо у жуто, а када је непаран (када му је вредност 1, 3, 5, 7 или 9), тада квадрат бојимо у зелено.

Још један начин да се наизменично мењају боје је да се уведе логичка променљива којом се означава да ли цртамо жути квадрат. У почетку је постављамо на вредност тачно, у сваком кораку петље јој мењамо истинитосну вредност (тако што је негирамо оператором not), а у телу петље боју одређујемо на основу те вредности, гранањем.

Приметимо да смо наредбом гранања (наредби if-else) само поставили боју, а да смо сам квадрат цртали независно, након гранања. Наиме, да смо у наредби гранања цртали квадрат, непотребно бисмо понављали кôд и тиме начинили програм тежим за одржавање.

Могуће је још једно, суштински другачије решење овог задатка, које се не заснива на гранању, већ на листи у којој се памте боје које се циклично смењују. Редни број квадрата је одређен бројачком променљивом i, која редом узима вредности 0, 1, 2, 3, 4, … Са друге стране позиција боје у листи редом треба да узима вредности 0, 1, 0, 1, 0, … Можемо приметити да се та позиција може добити од вредности i тако што се израчуна остатак при дељењу са 2. Ово се лако може уопштити и на више од две боје. Када би се наизменично смењивале 3 боје, тада би позиције требало да узимају вредности 0, 1, 2, 0, 1, 2, … и добијале би се израчунавањем остатка при дељењу са 3. У општем случају, потребно је израчунати остатак при дељењу дужином листе. На основу ове дискусије покушај да допуниш наредни код.

26
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (500, 100) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Квадрати - наизменично мењање боја")
6
7
# broj kvadrata koje treba iscrtati
8
broj_kvadrata = 10
9
# širina i visina jednog kvadrata
10
dimenzija_kvadrata = ???
11
# vertikalna sredina ekrana
12
sredina = ???
13
14
# lista koja sadrži boje  koje se smenjuju
15
boje = [pg.Color("yellow"), pg.Color("green")]
16
for i in range(0, broj_kvadrata):
17
    # boju odredjujemo na osnovu vrednosti brojača i
18
    boja = ???
19
    # koordinate gornjeg levog temena
20
    (levo, gore) = (???, ???)
21
    # crtamo kvadrat
22
    pg.draw.rect(prozor, boja, (levo, gore, dimenzija_kvadrata, dimenzija_kvadrata))
23
24
# prikazujemo prozor i čekamo da ga korisnik isključi
25
pygamebg.wait_loop()
26

(kvadratici_naizmenicno_lista)

Патент затварач

Напиши програм који исцртава шару која подсећа на патент-затварач (рајсфершлус, цибзар).

34
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (100, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "")
7
8
sirina_linije = 50         # širina linije rajsferšlusa
9
margina_levo_desno = 15    # margina do leve i desne ivice prozora
10
margina_gore_dole  = 20    # margina do gornje i donje ivice prozora
11
razmak = 15                # razmak između linija rasjferšlusa
12
13
# x koordinate početaka linija
14
x_levo = margina_levo_desno
15
x_desno = (sirina - margina_levo_desno) - sirina_linije
16
17
# koordinate početka tekuće linije
18
x_poc = x_levo
19
y = margina_gore_dole
20
21
while y < visina - margina_gore_dole:
22
    x_kraj = ???
23
    pg.draw.line(prozor, pg.Color("yellow"), ???, ???, 6);
24
25
    # pripremamo crtanje sledece linije
26
    y += razmak            # y je zadati broj piksela niže
27
    if x_poc == x_levo:    # x_poc je suprotno od prethodnog
28
        x_poc = ???
29
    else:
30
        x_poc = ???
31
32
# prikazujemo prozor i čekamo da ga korisnik isključi
33
pygamebg.wait_loop()
34

(rajsferslus)

Покушај и овај задатак да решиш коришћењем листе, без гранања (овај пут ћеш у листу сместити две позиције почетка линије).

Угнежђене петље

Видели смо како облике можемо да распоређујемо хоризонтално и вертикално. У многим ситуацијама имамо потребу да облике распоредимо у правилну мрежу и то постижемо помоћу угнежђених петљи. Подсетимо се, угнежђене петље подразумевају да се једна (унутрашња) петља налази унутар тела друге (спољашње петље). За сваку вредност бројачке променљиве спољне петље, унутрашња петља се извршава из почетка. Тако, на пример, код

4
 
1
for i in range(3):
2
    for j in range(3):
3
        ...
4

(ugnezdjene_petlje_primer_1)

Набраја редом парове (i, j) и то редом (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2).

Слично, петља

4
 
1
for i in range(5, 15+1, 5):
2
    for j in range(10, 30+1, 10):
3
        ...
4

(ugnezdjene_petlje_primer_2)

набраја редом парове (5, 10), (5, 20), (5, 30), (10, 10), (10, 20), (10, 30), (15, 10), (15, 20), (15, 30).

Плесни подијум

Плесни подијуми 1970-их су били издељени на квадратне плоче које су могле да светле у различитим бојама. Прикажи један такав подијум (гледан одозго) тако што ћеш поделити екран на n×n квадрата и сваки квадрат обојити у насумичну боју.

../_images/podijum.jpg

Претпоставићемо да на располагању имамо функцију која на насумичан начин одабире боју (њу је веома једноставно испрограмирати коришћењем функције random.randint). Угнежђеним петљама ћемо набрајати све парове (0,0), (0,1), …, (0,n1), (1,0), …, (1,n1), …, (n1,0), …, (0,n1). Задатак се онда своди на то да одредимо горње лево теме квадрата који се налази у врсти са редним бројем i и колони са редним бројем j. Пошто се лево од тог квадрата налази тачно j квадрата, док се изнад њега налази тачно i квадрата, координате његовог горњег левог темена су (ja,ia). На основу овога лако можеш допунити наредни код.

23
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (400, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Подијум за игру")
7
8
def nasumicna_boja():
9
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
10
11
# broj kvadrata
12
broj_kvadrata = 8
13
# dimenzija kvadrata
14
a = sirina / broj_kvadrata
15
16
# prolazimo kroz sva polja
17
for i in range(broj_kvadrata):
18
    for j in range(broj_kvadrata):
19
        pg.draw.rect(prozor, nasumicna_boja(), ???)
20
21
# prikazujemo prozor i čekamo da ga korisnik isključi
22
pygamebg.wait_loop()
23

(podijum)

Сивкасти насумични кружићи

Напиши програм који исцртава мрежу правилно распоређених кружића, при чему се пречник и нијанса сиве боје кружића насумично одређује.

Овај задатак је сличан претходном, једино што су нам уместо горњих левих темена сваког поља потребне координате центра сваког поља. За свако поље насумично генеришемо полупречник (цео број из интервала [2,d]), нијансу сиве боје (цео број из интервала [0,255]) и на основу боје, координата центра и полупречника вршимо цртање круга. Подсетимо се, за насумични одабир целог броја из интервала [a,b] користимо функцију random.randint(a, b).

Покушај да самостално урадиш овај задатак. Ако не успеваш, онда искористи понуђену помоћ, па допуни започети програм.

12
 
1
import random
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (400, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Мрежа кружића")
7
8
9
10
# prikazujemo prozor i čekamo da ga korisnik isključi
11
pygamebg.wait_loop()
12

(nasumični_kruzici)

Зграда

Напиши програм који исцртава прозоре на згради која има дати број спратова и дати број вертикала.

Зграда коју треба да нацртамо је приказана на наредној слици.

../_images/zgrada.png

Зеленом бојом су означени међуспратови, укључујући и простор испод првог спрата и изнад последњег спрата, док су црвеном бојом означене међувертикале, укључујући и простор лево од прве и десно од последње вертикале. Видимо да је број међуспратова за један већи од броја спратова, док је број међувертикала за један већи од броја вертикала. Претпоставићемо да је висина сваког прозора иста као висина сваког међуспрата и да је ширина сваког прозора једнака ширини сваке међувертикале. Одавде можемо израчунати висину прозора зграде (тако што укупну висину поделимо са збиром броја спратова и међуспратова) и ширину прозора зграде (тако што укупну ширину поделимо са збиром вертикала и међувертикала). Прозоре можемо цртати од горе на доле (иако се спратови увек броје од доле на горе). Координате горњег левог темена прозора у врсти i и колони j можемо добити тако што на ширину међувертикале додамо j пута збир ширине прозора и ширине међувертикале (што је у нашем случају једнако двострукој ширини прозора) тј. тако што на ширину међуспрата додамо i пута збир висине спрата и висине међуспрата (што је у нашем случају једнако двострукој ширини међуспрата).

Покушај да на основу претходне дискусије самостално урадиш овај задатак. Ако не успеваш, онда искористи понуђену помоћ, па допуни започети програм.

12
 
1
import math
2
import pygame as pg
3
import pygamebg
4
5
(sirina, visina) = (200, 400) # otvaramo prozor
6
prozor = pygamebg.open_window(sirina, visina, "Зграда")
7
8
9
10
# prikazujemo prozor i čekamo da ga korisnik isključi
11
pygamebg.wait_loop()
12

(zgrada)

Уместо петљи у којима се редом наводе редни бројеви, могли смо употребити и петље са кораком.

4
 
1
for x in range(sirina_prozora, sirina, 2*sirina_prozora):
2
    for y in range(visina_prozora, visina, 2*visina_prozora):
3
       ...
4

(ugnezdjene_sa_korakom)

Покушај сада да прилагодиш претходни програм тако да висина међуспрата буде само пола висине спрата.

Шаховска табла

Напиши програм који исцртава шаховску таблу.

Овај задатак је веома сличан оном у ком смо цртали плесни подијум. Главна разлика је у томе што се боја не одређује насумично, већ се наизменично смењују црна и бела поља. Можемо позадину целе табле обојити у бело, а затим исцртати само црна поља. Главни изазов у овом задатку је како на основу редног броја врсте i и редног броја колоне j одредити да ли се на том месту налази црни или бели квадрат. Покушај да одредиш ово правило, а ако не успеш, онда погледај решење.

24
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (400, 400) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Шаховска табла")
6
7
# bojimo pozadinu u belo
8
prozor.fill(pg.Color("white"))
9
10
# dimenzije table i polja
11
broj_polja = 8
12
sirina_polja = sirina / broj_polja
13
visina_polja = visina / broj_polja
14
15
# prolazimo kroz sva polja
16
for i in range(broj_polja):
17
    for ???:
18
        # bojimo crna polja
19
        if ???:
20
            pg.draw.rect(prozor, ???, (i*sirina_polja, j*visina_polja, sirina_polja, visina_polja))
21
22
# prikazujemo prozor i čekamo da ga korisnik isključi
23
pygamebg.wait_loop()
24

(sahovska_tabla)

Домаћи задатак - паркет

Напиши програм који исцртава паркет на поду.

Овај задатак представља комбинацију два задатка који смо раније радили: шпартања екрана вертикалним линијама и шаховске табле. Покушај да самостално урадиш овај задатак. Ако не успеваш, онда искористи понуђену помоћ, па допуни започети програм.

11
 
1
import pygame as pg
2
import pygamebg
3
4
(sirina, visina) = (300, 300) # otvaramo prozor
5
prozor = pygamebg.open_window(sirina, visina, "Паркет")
6
7
8
9
# prikazujemo prozor i čekamo da ga korisnik isključi
10
pygamebg.wait_loop()
11

(parket)