30.2. Домаћи задатак¶
Семафор¶

Напиши програм који симулира рад семафора. Прво се приказује зелено светло, које траје четири секунде, након тога се укључује жуто светло, које траје секунду, а након тога црвено, које траје три секунде. На крају се истовремено пале црвено и жуто светло, што траје секунду, након чега се поново укључује зелено, и циклус понавља.
У низу svetla
можемо чувати редом која се светла укључују и колико
свако од њих траје. За свако светло чувамо уређени пар, који као своју
прву компоненту садржи тројку истинитосних вредности које говоре да ли
је укључено редом црвено, жуто и зелено светло. Друга компонента је
трајање светла у милисекундама. Тако, на пример, ((True, True,
False), 1000)
означава да је црвено-жуто светло укључено током
једне секунде, док ((False, False, True), 4000)
означава да је
зелено светло укључено током четири секунде.
Чуваћемо и редни број светла које тренутно треба да буде укључено и у сваком кораку ћемо га увећавати за 1 (у почетку може да буде постављено на 0, тако да рад семафора креће од црвеног светла). Када се цео циклус проврти, поново се враћамо на почетак (на зелено светло) тако што бројач светла тада постављамо на нулу. То можемо учинити једноставно, било гранањем (након сваког увећавања провераваћемо да ли је бројач светла достигао укупан број светала, и ако јесте, враћаћемо га на нулу) било модуларном аритметиком (након сваког увећавања израчунаћемо остатак при дељењу укупним бројем светала).
Анимацију ћемо засновати на тајмеру који ћемо навијати тако да се
огласи сваки пут када треба да се промени светло. Нагласимо да свако
ново навијање тајмера (позив pg.time.set_timer) поништава старо.
Дакле, сваки пут када се региструје догађај pg.USEREVENT
увећаваћемо редни број светла. Из низа ћемо читати податке о томе која
светла треба да буду укључена и колико дуго. На основу тога ће се
вршити цртање семафора и поново ћемо навијати тајмер на основу
прочитане дужине трајања светла које се управо укључило.
Када је реч о цртању, потребно је да проценимо величину три круга и њихов положај на екрану. Претпоставићемо да је размак између свака два светла једнак 10 пиксела, исто колики је и размак између горње ивице прозора и горњег светла и размак између доњег светла и доње ивице прозора. Дакле, гледано вертикално, висина прозора је попуњена са четири размака (сваки од њих је 10 пиксела) и три пречника светла. Дакле шест полупречника светала и четири размака од по 10 пиксела једнаки су висини прозора, одакле лако можемо израчунати величину полупречника сваког светла. Центар сваког светла је хоризонтално смештен на половину ширине прозора. Што се тиче вертикалне позиције центара, прво светло је од горње ивице удаљено за један размак и један полупречник светла, друго је удаљено за два размака (размак од горње ивице до горњег светла и размак између првог и другог светла) и три полупречника светла (пречник првог светла и полупречник другог), док је центар трећег светла од горње ивице удаљен за три размака (размак од горње ивице, размак између првог и другог и размак између другог и трећег светла) и пет полупречника светла (пречнике првог и другог и полупречник трећег светла).