Projektovanje softvera/K1 2024
Prvi kolokvijum 2024. godine održan je 27. oktobra 2024. godine. Bile su dostupne prezentacije o svim projektnim obrascima, kao i Java dokumentacija. Vreme za izradu je bilo 120 minuta.
1. zadatak
Postavka
Posmatra se sistem za prikaz i obradu digitalnih slika. Treba obezbediti to da se na originalnu sliku može primeniti proizvoljan broj filtera (ili nijedan), u proizvoljnom redosledu, pri čemu ostatak sistema koji prikazuje i koristi sliku (“klijent”) ne treba da vidi razliku u odnosu na to da li su na sliku primenjeni filteri ili nisu. Svaka slika sadrži niz piksela. Piksel ima R, G i B komponente (intenzitet crvene, zelene i plave boje), gde svaka ima celobrojnu vrednost od 0 do 255. Filteri koji mogu da se primene u ovom sistemu su za sada (kasnije mogu biti osmišljeni i dodati novi filteri):
- Greyscale – svaki piksel se pretvara u odgovarajuću nijansu sive, gde se R, G i B komponente računaju po sledećoj formuli:
R, G, B = 0.3 * R + 0.59 * G + 0.11 * B - Invert – R, G i B komponente svakog piksela se invertuju po sledećoj formuli:
R = 255 – R, G = 255 – G, B = 255 – B
Klijent koji koristi sliku može da pročita vrednosti njenih piksela; ukoliko su na sliku primenjeni filteri, to su vrednosti piksela originalne slike izmenjene dejstvom dodatih filtera (u slučaju da nijedan filter nije primenjen nad originalnom slikom, vraća se neizmenjen niz piksela originalne slike). Korišćenjem projektnog obrasca Dekorater (Decorator) potrebno je implementirati opisani deo sistema i navesti raspodelu uloga iz obrasca klasama u ovom rešenju; opis dati u tekstualnom fajlu z1.txt.
Napisati primer korišćenja date saradnje. Napraviti sliku sa filterima Greyscale i Invert, sa nekim nasumičnim vrednostima piksela, a zatim dohvatiti piksele takve slike i ispisati ih. Implementacija piksela prikazana je u sledećoj klasi:
package zad1;
public class Pixel {
private int R, G, B;
public Pixel(int R, int G, int B) {
this.R = R;
this.G = G;
this.B = B;
}
public int getR() {
return R;
}
public void setR(int R) {
this.R = R;
}
public int getG() {
return G;
}
public void setG(int G) {
this.G = G;
}
public int getB() {
return B;
}
public void setB(int B) {
this.B = B;
}
}
Rešenje
Saradnja
U ovom zadatku potrebno je koristiti uzorak Dekorater, a u izradi se koristio i uzorak Šablonski metod.
- Dekorater
- Učesnici:
- Komponenta (Picture)
- Subjekat (RawPicture)
- Dopuna (Filter)
- KonkretnaDopuna (Greyscale, Inverse)
- Šablonski metod
- Učesnici:
- ApstraktnaKlasa (Filter)
- KonkretnaKlasa (Greyscale, Inverse)
Picture.java
package zad1;
import java.util.List;
public abstract class Picture {
protected List<Pixel> pixels;
public List<Pixel> getPixels() {
return pixels;
}
}
RawPicture.java
package zad1;
import java.util.List;
public class RawPicture extends Picture {
public RawPicture(List<Pixel> pixels) {
this.pixels = pixels;
}
}
Filter.java
package zad1;
import java.util.ArrayList;
import java.util.List;
public abstract class Filter extends Picture {
public Filter(Picture picture) {
pixels = new ArrayList<Pixel>();
for (Pixel pixel : picture.getPixels()) {
pixels.add(applyFilter(pixel));
}
}
public abstract Pixel applyFilter(Pixel pixel);
}
Greyscale.java
package zad1;
public class Greyscale extends Filter {
public Greyscale(Picture picture) {
super(picture);
}
@Override
public Pixel applyFilter(Pixel pixel) {
int color = (int) (pixel.getR() * 0.2 + pixel.getG() * 0.5 + pixel.getB() * 0.3);
return new Pixel(color, color, color);
}
}
Inverse.java
package zad1;
public class Inverse extends Filter {
public Inverse(Picture picture) {
super(picture);
}
@Override
public Pixel applyFilter(Pixel pixel) {
return new Pixel(255 - pixel.getR(), 255 - pixel.getG(), 255 - pixel.getB());
}
}
Main.java
package zad1;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Pixel> pixels = Arrays.asList(new Pixel(100, 0, 50), new Pixel(255, 255, 0), new Pixel(0, 255, 0));
Picture raw = new RawPicture(pixels);
Picture picture = new Greyscale(new Inverse(raw));
for (Pixel pixel : picture.getPixels()) {
System.out.println("R = " + pixel.getR() + "\tG = " + pixel.getG() + "\tB = " + pixel.getB());
}
}
}
2. zadatak
- Ovaj zadatak nije rešen. Pomozite SI Wiki tako što ćete ga rešiti.
Postavka
Posmatra se deo sistema koji simulira kartašku igru. Pre početka igre, igrači mogu da se prijave deliocu karata („krupijeu“) za učestvovanje u igri i mogu da se odjave nakon završene igre. Igra se igra tako da u njoj može učestvovati različit broj igrača i tokom igre igrači ne razgovaraju jedan sa drugim. Broj igrača je uvek dovoljno mali da je sa njima prihvatljiva sinhrona komunikacija. Nakon što se igra pokrene, svaki igrač od krupijea dobija po dve nasumične karte (kojih je samo on svestan). Potom krupije otkriva jednu od preostalih karata i svi igrači se obaveštavaju o karti koja je otkrivena. Na osnovu ovih informacija, svaki igrač može da odluči koliko će novca uložiti. Neki igrači igraju agresivno, a neki štedljivo; način igranja može da se konfiguriše za svakog igrača različito, pri čemu se predviđa osmišljavanje novih različitih načina igre, pa različiti igrači sa istim informacijama ulažu različitu količinu novca. Nakon što svi igrači ulože svoj novac, sledi ponovo otkrivanje nove karte oko koje se igrači obaveštavaju i nakon čega svaki može ponovo da uloži novac. Ovo se ponavlja pet puta po igri, na kraju čega igrač sa najboljom kombinacijom karata dobija sav novac i igra se završava. Logika odabira pobednika se takođe može menjati od igre do igre, mada konkretna implementacija ove logike nije od interesa za ovaj zadatak.
Doraditi i ispraviti datu implementaciju sistema korišćenjem odgovarajućih projektnih obrazaca. Navesti sve primene projektnih obrazaca u sistemu sa kratkim obrazloženjem u tekstualnom fajlu z2.txt (jedna do dve rečenice).