From: Doni Pracner Date: Tue, 5 Dec 2017 14:52:44 +0000 (+0100) Subject: ObjedinjenoResenje preimenovano u (adekvatnije) SuperKomplikovanoResenje X-Git-Url: http://svarog.pmf.uns.ac.rs/gitweb/?p=spa2-materijali.git;a=commitdiff_plain;h=548ea5272576d592053c4e99f512b2fadc1053f7 ObjedinjenoResenje preimenovano u (adekvatnije) SuperKomplikovanoResenje --- diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Lavirint.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Lavirint.java deleted file mode 100644 index 5b84e5a..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Lavirint.java +++ /dev/null @@ -1,156 +0,0 @@ -import java.util.Comparator; - -/** - * Klasa Lavirint sadrzi 3 javne i tri privatne metode za trazenje puteva. - * - * Klase KomparatorPoDuzini i KomparatorPoVrednosti predstavljaju komparatore - * koji se korste pri trazenju najkraceg i najvrednijeg puta. - */ -public class Lavirint { - - // Polje m sadrzi kompletnu mapu - private Mapa m; - - // Polje optResenje sluzi za pamcenje optimalnog resenja - private Put optResenje; - - // Ucitava mapu iz datog fajla i stampa je na ekran - Lavirint(String imeFajla) { - m = new Mapa(imeFajla); - m.stampaj(); - } - - // Provarava da li postoji put do izlaza i vraca vrednost true - // ako postoji put ili vrednost false ako ne postoji - public boolean postojiPut(int x, int y) { - if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { - return false; - } - if (m.getPos(x, y) == true) { - return false; - } - if (m.getMat(x, y) == Mapa.ZID) { - return false; - } - if (m.getMat(x, y) == Mapa.IZLAZ) { - return true; - } - m.setPos(x, y, true); - if (postojiPut(x + 1, y)) { - return true; - } - if (postojiPut(x - 1, y)) { - return true; - } - if (postojiPut(x, y + 1)) { - return true; - } - if (postojiPut(x, y - 1)) { - return true; - } - m.setPos(x, y, false); - return false; - } - - // Poziva metodu rput da pronadje i ispise put, ako postoji - // Ukoliko put ne postoji, ispisuje poruku o gresci - public void nadjiPut(int x, int y) { - if (!rput(x, y)) { - System.err.println("Ne postoji put"); - } - } - - // Proverava da li postoji put korsiteci pretrazivanje sa vracanjem - // Ukoliko se pronadje izlaz iz lavirinta, stampa se put u obrnutom - // redosledu - // Put se stampa pri povratku iz rekurzije - private boolean rput(int x, int y) { - if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { - return false; - } - if (m.getPos(x, y)) { - return false; - } - if (m.getMat(x, y) == Mapa.ZID) { - return false; - } - if (m.getMat(x, y) == Mapa.IZLAZ) { - System.out.println(x + " " + y); - return true; - } - m.setPos(x, y, true); - if (rput(x + 1, y) || rput(x, y + 1) || rput(x, y - 1) - || rput(x - 1, y)) { - System.out.println(x + " " + y); - return true; - } - m.setPos(x, y, false); - return false; - } - - // Kreira optimalno resenje za put, pri cemu se za optimalnost resenja - // koristi komparator po duzini resenja, tj. trazi se najkrace resenje - // Samo resenje kreira se u metodi optPut - public Put najkraciPut(int x, int y) { - Put r = new Put(); - optPut(x, y, r, new KomparatorPoDuzini()); - return optResenje; - } - - // Kreira optimalno resenje za put, pri cemu se za optimalnost resenja - // koristi komparator po duzini resenja, tj. trazi se najvrednije resenje - // Samo resenje kreira se u metodi optPut - public Put najvrednijiPut(int x, int y) { - Put trenutni = new Put(); - optPut(x, y, trenutni, new KomparatorPoVredosti()); - return optResenje; - } - - // Proverava da li postoji put korsiteci pretrazivanje sa vracanjem - // Ukoliko se pronadje na prvi ili optimalniji put, taj put se pamti u - // optResenje - // Optimalnost puta se proverava komparatorom - private void optPut(int x, int y, Put trenutni, Comparator c) { - if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { - return; - } - if (m.getPos(x, y)) { - return; - } - if (m.getMat(x, y) == Mapa.ZID) { - return; - } - if (m.getMat(x, y) == Mapa.IZLAZ) { - trenutni.dodaj(x, y, 0); - if (optResenje == null || c.compare(trenutni, optResenje) < 0) { - optResenje = new Put(trenutni); - } - trenutni.izbaciKraj(); - return; - } - - // pokusavamo da trazimo dalje put - m.setPos(x, y, true); - trenutni.dodaj(x, y, m.getMat(x, y)); - optPut(x + 1, y, trenutni, c); - optPut(x, y + 1, trenutni, c); - optPut(x, y - 1, trenutni, c); - optPut(x - 1, y, trenutni, c); - m.setPos(x, y, false); - trenutni.izbaciKraj(); - } -} - -// Komparator za puteve po duzini resenja -class KomparatorPoDuzini implements Comparator { - public int compare(Put r1, Put r2) { - return r1.getLength() - r2.getLength(); - } -} - -// Komparator za puteve po vrednosti resenja -class KomparatorPoVredosti implements Comparator { - public int compare(Put r1, Put r2) { - return r2.getVrednost() - r1.getVrednost(); - } -} diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/LavirintProgram.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/LavirintProgram.java deleted file mode 100644 index 01adf52..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/LavirintProgram.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Program za nalazenje puta u lavirintu. - * - * Date su cetiri varijante problema, od jednostavnijih ka slozenijima, radi - * ilustracije osnovnih koncepata i postepenog uvodjenja novih. - * - * Najjednostavnije je samo nalazenje da li put postoji. - * - * Prosirenje tog resenja nam ispisuje taj nadjeni put. - * - * Treca varijanta nalazi sve puteve i medju njima bira najkraci. - * - * Cetvrta varijanta resava lavirint u kome su rasuti zlatnici na poljima i - * nalazi put na kome se kupi najvise zlatnika. - */ - -public class LavirintProgram { - - public static void main(String[] args) { - Svetovid.out.println("Unesite ime fajla: "); - String fajl = Svetovid.in.readLine(); - if (!Svetovid.testIn(fajl)) { - System.out.println("Greska: nema fajla!"); - return; - } - - Lavirint l = new Lavirint(fajl); - Put r; - - if (l != null) { - System.out.println("1 - da li postoji put"); - System.out.println("2 - ispis nekog puta (ako postoji)"); - System.out.println("3 - nalazenje najkraceg puta"); - System.out.println("4 - nalazenje najvrednijeg puta"); - System.out.println("Unesite izbor 1-4:"); - int op = Svetovid.in.readInt(); - - switch (op) { - case 1: - if (l.postojiPut(0, 0)) { - System.out.println("Postoji put"); - } else { - System.out.println("Ne postoji put"); - } - break; - case 2: - l.nadjiPut(0, 0); - break; - case 3: - r = l.najkraciPut(0, 0); - if (r != null) { - r.stampaj(); - } else { - System.out.println("Nema resenja"); - } - break; - case 4: - r = l.najvrednijiPut(0, 0); - if (r != null) { - r.stampaj(); - System.out.println("Vrednost puta: " + r.getVrednost()); - } else { - System.out.println("Nema resenja"); - } - break; - default: - System.err.println("Uneli ste pogresan izbor"); - } - } - } -} \ No newline at end of file diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Mapa.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Mapa.java deleted file mode 100644 index a39c662..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Mapa.java +++ /dev/null @@ -1,94 +0,0 @@ - -/** - * Klasa Mapa koristi se za reprezentaciju lavirint i njegovih polja. - */ -public class Mapa { - - // Vrednosti polja i njihova znacenja - public final static int IZLAZ = -5; - public final static int ZID = -1; - public final static int GRESKA = Integer.MIN_VALUE; - - // Dimenzije mape - private int visina, sirina; - - // Polja mape - private int[][] mat; - - // Prilikom pretrazivanja ovde mozemo pamtiti koja polja smo posetili a koja nismo - private boolean[][] pos; - - public int getSirina() { - return sirina; - } - - public int getVisina() { - return visina; - } - - public void setPos(int x, int y, boolean b) { - if (0 <= x && x < sirina && 0 <= y && y < visina) { - pos[x][y] = b; - } - } - - public boolean getPos(int x, int y) { - if (0 <= x && x < sirina && 0 <= y && y < visina) { - return pos[x][y]; - } else { - return true; - } - } - - public int getMat(int x, int y) { - if (0 <= x && x < sirina && 0 <= y && y < visina) { - return mat[x][y]; - } else { - return GRESKA; - } - } - - public Mapa(int sirina, int visina) { - this.sirina = sirina; - this.visina = visina; - mat = new int[sirina][visina]; - pos = new boolean[sirina][visina]; - } - - public Mapa(String imeFajla) { - if (!Svetovid.testIn(imeFajla)) { - throw new RuntimeException("Fajl za kreiranje mape (" + imeFajla + ") nije prisupacan"); - } - sirina = Svetovid.in(imeFajla).readInt(); - visina = Svetovid.in(imeFajla).readInt(); - mat = new int[sirina][visina]; - pos = new boolean[sirina][visina]; - for (int j = 0; j < visina; j++) { - for (int i = 0; i < sirina; i++) { - mat[i][j] = Svetovid.in(imeFajla).readInt(); - } - } - Svetovid.closeIn(imeFajla); - Prikaz.boja(ZID, Prikaz.CRNA, null); - Prikaz.boja(IZLAZ, Prikaz.CRVENA, Prikaz.BELA); - Prikaz.boja(1, 20, Prikaz.SVETLO_ZELENA, Prikaz.ZELENA, Prikaz.CRNA); - Prikaz.boja(99, Prikaz.ZUTA, Prikaz.CRNA); - Prikaz.mapa("Lavirint", getSirina(), getVisina(), this::getMat); - } - - public void stampaj() { - if (visina != 0 && sirina != 0) { - System.out.println(visina + " " + sirina); - for (int j = 0; j < visina; j++) { - for (int i = 0; i < sirina; i++) { - System.out.print(mat[i][j] + "\t"); - } - System.out.println(); - } - } - } - - public String toString() { - return "Mapa velicine " + sirina + " x " + visina; - } -} diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Polje.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Polje.java deleted file mode 100644 index 15676d1..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Polje.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Klasa Polje se koristi za pamcenje x i y koordinata nekog polja, kao i - * vrednosti na toj poziciji u mapi - */ -public class Polje { - - private final int x, y, v; - - public Polje(int x, int y, int v) { - this.x = x; - this.y = y; - this.v = v; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getV() { - return v; - } - - public String toString() { - return "(" + x + ", " + y + ") " + v; - } -} diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Prikaz.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Prikaz.java deleted file mode 100644 index aa95160..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Prikaz.java +++ /dev/null @@ -1,487 +0,0 @@ -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import javafx.application.Application; -import javafx.application.Platform; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.geometry.Insets; -import javafx.geometry.VPos; -import javafx.scene.Scene; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.Slider; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.ColumnConstraints; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; -import javafx.scene.shape.Circle; -import javafx.scene.shape.StrokeLineCap; -import javafx.scene.shape.StrokeLineJoin; -import javafx.scene.text.Font; -import javafx.scene.text.FontWeight; -import javafx.scene.text.TextAlignment; -import javafx.stage.Stage; - -public class Prikaz extends Application { - - public static final Color STVARNO_BELA = Color.hsb(0, 0, 1.0); - public static final Color BELA = Color.hsb(0, 0, 0.95); - public static final Color SVETLO_SIVA = Color.hsb(0, 0, 0.8); - public static final Color SIVA = Color.hsb(0, 0, 0.6); - public static final Color TAMNO_SIVA = Color.hsb(0, 0, 0.4); - public static final Color CRNA = Color.hsb(0, 0, 0.2); - public static final Color STVARNO_CRNA = Color.hsb(0, 0, 0.0); - - public static final Color SVETLO_CRVENA = Color.hsb( 0, 0.2, 1.0); - public static final Color SVETLO_NARANDZASTA = Color.hsb( 30, 0.2, 1.0); - public static final Color SVETLO_ZUTA = Color.hsb( 60, 0.2, 1.0); - public static final Color SVETLO_ZELENA = Color.hsb(120, 0.2, 1.0); - public static final Color SVETLO_TIRKIZNA = Color.hsb(180, 0.2, 1.0); - public static final Color SVETLO_AZURNA = Color.hsb(210, 0.2, 1.0); - public static final Color SVETLO_PLAVA = Color.hsb(240, 0.2, 1.0); - public static final Color SVETLO_PURPURNA = Color.hsb(270, 0.2, 1.0); - public static final Color SVETLO_LJUBICASTA = Color.hsb(300, 0.2, 1.0); - public static final Color SVETLO_RUZICASTA = Color.hsb(330, 0.2, 1.0); - - public static final Color CRVENA = Color.hsb( 0, 0.9, 0.8); - public static final Color NARANDZASTA = Color.hsb( 30, 0.9, 0.8); - public static final Color ZUTA = Color.hsb( 60, 0.9, 0.8); - public static final Color ZELENA = Color.hsb(120, 0.9, 0.8); - public static final Color TIRKIZNA = Color.hsb(180, 0.9, 0.8); - public static final Color AZURNA = Color.hsb(210, 0.9, 0.8); - public static final Color PLAVA = Color.hsb(240, 0.9, 0.8); - public static final Color PURPURNA = Color.hsb(270, 0.9, 0.8); - public static final Color LJUBICASTA = Color.hsb(300, 0.9, 0.8); - public static final Color RUZICASTA = Color.hsb(330, 0.9, 0.8); - - public static final Color TAMNO_CRVENA = Color.hsb( 0, 0.8, 0.4); - public static final Color TAMNO_NARANDZASTA = Color.hsb( 30, 0.8, 0.4); - public static final Color TAMNO_ZUTA = Color.hsb( 60, 0.8, 0.4); - public static final Color TAMNO_ZELENA = Color.hsb(120, 0.8, 0.4); - public static final Color TAMNO_TIRKIZNA = Color.hsb(180, 0.8, 0.4); - public static final Color TAMNO_AZURNA = Color.hsb(210, 0.8, 0.4); - public static final Color TAMNO_PLAVA = Color.hsb(240, 0.8, 0.4); - public static final Color TAMNO_PURPURNA = Color.hsb(270, 0.8, 0.4); - public static final Color TAMNO_LJUBICASTA = Color.hsb(300, 0.8, 0.4); - public static final Color TAMNO_RUZICASTA = Color.hsb(330, 0.8, 0.4); - - //////////////////// - // Boje i stilovi // - //////////////////// - - protected static Paint bojaPozadine = BELA; - protected static Paint bojaOkvira = CRNA; - protected static Map bojaPoljaPozadina = new HashMap<>(); - protected static Map bojaPoljaTekst = new HashMap<>(); - protected static Font font = Font.font("Arial", FontWeight.BOLD, 12); - - public static void boja(Paint pozadina, Paint okvir) { - bojaPozadine = pozadina; - bojaOkvira = okvir; - } - - public static void boja(int vrednost, Paint bojaPozadine, Paint bojaTeksta) { - if (bojaPozadine == null) { - bojaPoljaPozadina.remove(vrednost); - } - bojaPoljaPozadina.put(vrednost, bojaPozadine); - if (bojaTeksta == null) { - bojaPoljaTekst.remove(vrednost); - } - bojaPoljaTekst.put(vrednost, bojaTeksta); - } - - public static void boja(int vrednostMin, int vrednostMax, Color bojaMin, Color bojaMax, Paint bojaTeksta) { - if (bojaMin == null || bojaMax == null) { - throw new IllegalArgumentException(); - } - int n = vrednostMax - vrednostMin; - for (int i = 0; i <= n; i++) { - int vrednost = vrednostMin + i; - bojaPoljaPozadina.put(vrednost, bojaMin.interpolate(bojaMax, (double) (i) / n)); - if (bojaTeksta == null) { - bojaPoljaTekst.remove(vrednost); - } - bojaPoljaTekst.put(vrednost, bojaTeksta); - } - } - - //////////////// - // Geometrija // - //////////////// - - private static double velicinaPolja = 32; - private static double velicinaRazmaka = 4; - private static int debljinaOkvira = 0; - private static double debljinaPuta = velicinaPolja / 2; - - public static void velicina(double polje, double razmak, int okvir) { - velicinaPolja = polje; - velicinaRazmaka = razmak; - debljinaOkvira = okvir; - debljinaPuta = velicinaPolja / 2; - } - - protected static double ukupnaDuzina(int brojPolja) { - return x(brojPolja + debljinaOkvira, 0.0); - } - - protected static double x(int indeks, double delta) { - indeks = indeks + debljinaOkvira; - return indeks * (velicinaPolja + velicinaRazmaka) + velicinaRazmaka + velicinaPolja * delta; - } - - protected static double x(int indeks) { - return x(indeks, 0.0); - } - - protected static double k(int indeks) { - return x(indeks, 0.5); - } - - protected static double w(int count, double delta) { - return (velicinaPolja + velicinaRazmaka) * count + velicinaRazmaka * (delta - 1); - } - - protected static double w(int count) { - return w(count, 0); - } - - protected static double r() { - return 2 * velicinaRazmaka; - } - - ///////////// - // Sadrzaj // - ///////////// - - protected static String naslovProzora; - protected static int sirinaMape; - protected static int visinaMape; - protected static FunkcijaZaMapu funkcijaZaMapu; - - @FunctionalInterface - public static interface FunkcijaZaMapu { - public int vrednostNa(int x, int y); - } - - public static void mapa(String naslov, int sirina, int visina, FunkcijaZaMapu funkcijaZaMapu) { - naslovProzora = naslov; - sirinaMape = sirina; - visinaMape = visina; - Prikaz.funkcijaZaMapu = funkcijaZaMapu; - pokreni(); - } - - protected static Map funkcijeZaPuteve = new LinkedHashMap<>(); - protected static Map funkcijeZaVrednostiPuteva = new LinkedHashMap<>(); - protected static Map bojeZaPuteve = new HashMap<>(); - - @FunctionalInterface - public static interface FunkcijaZaPut { - public KorakPuta korak(int indeks); - } - - @FunctionalInterface - public static interface FunkcijaZaVrednostPuta { - public String vrednost(); - } - - public static class KorakPuta { - public int x, y; - } - - public static KorakPuta korak(int x, int y) { - KorakPuta korak = new KorakPuta(); - korak.x = x; korak.y = y; - return korak; - } - - public static void put(String naziv, FunkcijaZaPut funkcijaZaPut, FunkcijaZaVrednostPuta funkcijaZaVrednostPuta, Paint boja) { - odradiKasnije(() -> { - funkcijeZaPuteve.remove(naziv); - funkcijeZaVrednostiPuteva.remove(naziv); - bojeZaPuteve.remove(naziv); - listaPuteva.remove(naziv); - Canvas platno = platnaZaPuteve.remove(naziv); - centerPane.getChildren().remove(platno); - if (funkcijaZaPut != null && funkcijaZaVrednostPuta != null && boja != null) { - funkcijeZaPuteve.put(naziv, funkcijaZaPut); - funkcijeZaVrednostiPuteva.put(naziv, funkcijaZaVrednostPuta); - bojeZaPuteve.put(naziv, boja); - platno = new Canvas(Prikaz.platno.getWidth(), Prikaz.platno.getHeight()); - platno.setOpacity(0.5); - platno.getGraphicsContext2D().setLineCap(StrokeLineCap.ROUND); - platno.getGraphicsContext2D().setLineJoin(StrokeLineJoin.ROUND); - platnaZaPuteve.put(naziv, platno); - centerPane.getChildren().add(1, platno); - listaPuteva.add(naziv); - crtajPut(naziv); - } - }); - } - - public static void put(String naziv, List lista, Function x, Function y, FunkcijaZaVrednostPuta funkcijaZaVrednostPuta, Paint boja) { - FunkcijaZaPut fja = (int indeks) -> { - try { - T element = lista.get(indeks); - return korak(x.apply(element), y.apply(element)); - } catch (IndexOutOfBoundsException e) { - return null; - } - }; - put(naziv, fja, funkcijaZaVrednostPuta, boja); - } - - public static void osveziPut(String naziv) { - odradiKasnije(() -> { - crtajPut(naziv); - listaPuteva.set(listaPuteva.indexOf(naziv), naziv); - }); - cekajAkoTreba(); - } - - ///////// - // GUI // - ///////// - - protected static StackPane centerPane; - protected static ListView listView; - protected static ObservableList listaPuteva = FXCollections.observableArrayList(); - - @Override - public void start(Stage primaryStage) { - Label labelPutevi = new Label("Putevi:"); - listView = new ListView<>(listaPuteva); - listView.setCellFactory(l -> new ListCell() { - public void updateItem(String naziv, boolean empty) { - super.updateItem(naziv, empty); - if (empty || naziv == null) { - setText(null); - setGraphic(null); - } else { - Circle icon = new Circle(8); - icon.setFill(bojeZaPuteve.get(naziv)); - setGraphic(icon); - FunkcijaZaVrednostPuta fja = funkcijeZaVrednostiPuteva.get(naziv); - try { - setText(naziv + ": " + fja.vrednost()); - } catch (RuntimeException e) { - } - } - } - }); - - Label labelAnimacija = new Label(); - Slider slider = new Slider(0, 4, 2); - Button button = new Button(">"); - osveziPanelZaAnimaciju(labelAnimacija, button, slider.getValue()); - slider.valueProperty().addListener((value, oldValue, newValue) -> { - osveziPanelZaAnimaciju(labelAnimacija, button, newValue.doubleValue()); - }); - button.setOnAction(e -> { - zavrsiCekanje(); - }); - button.setMaxHeight(Double.MAX_VALUE); - - GridPane animationPane = new GridPane(); - animationPane.setHgap(6); - animationPane.setVgap(6); - ColumnConstraints column = new ColumnConstraints(); - column.setHgrow(Priority.ALWAYS); - animationPane.getColumnConstraints().add(column); - animationPane.add(labelAnimacija, 0, 0); - animationPane.add(slider, 0, 1); - animationPane.add(button, 1, 0, 1, 2); - - VBox rightPane = new VBox(); - rightPane.setPadding(new Insets(12, 12, 12, 12)); - rightPane.setSpacing(6); - rightPane.getChildren().add(labelPutevi); - listView.setPrefHeight(0); - VBox.setVgrow(listView, Priority.ALWAYS); - rightPane.getChildren().add(listView); - VBox.setMargin(animationPane, new Insets(6, 0, 0, 0)); - rightPane.getChildren().add(animationPane); - - platno = new Canvas(ukupnaDuzina(sirinaMape), ukupnaDuzina(visinaMape)); - osveziMapu(); - centerPane = new StackPane(platno); - - BorderPane rootPane = new BorderPane(); - rootPane.setCenter(centerPane); - rootPane.setRight(rightPane); - Scene scene = new Scene(rootPane); - - primaryStage.setTitle(naslovProzora + " - " + sirinaMape + " x " + visinaMape + ""); - primaryStage.setAlwaysOnTop(true); - primaryStage.setResizable(false); - primaryStage.setOnCloseRequest(e -> podesiVreme(0)); - primaryStage.setScene(scene); - primaryStage.show(); - - } - - protected static void osveziPanelZaAnimaciju(Label labela, Button dugme, double vrednost) { - long vreme = podesiVreme(vrednost); - String tekst = "Brzina animacije: " + String.format("%.2f", vreme / 1000.0) + "s"; - dugme.setVisible(vreme >= 1000); - labela.setText(tekst); - } - - ///////////// - // Crtanje // - ///////////// - - protected static Canvas platno; - protected static Map platnaZaPuteve = new LinkedHashMap<>(); - - protected static void osveziMapu() { - crtajMapu(platno.getGraphicsContext2D(), platno.getWidth(), platno.getHeight()); - } - - protected static void crtajMapu(GraphicsContext gc, double sirina, double visina) { - gc.setTextAlign(TextAlignment.CENTER); - gc.setTextBaseline(VPos.CENTER); - gc.setFont(font); - crtajOkvir(gc, sirina, visina); - for (int j = 0; j < visinaMape; j++) { - for (int i = 0; i < sirinaMape; i++) { - int sadrzaj = funkcijaZaMapu.vrednostNa(i, j); - Paint bojaPozadina = bojaPoljaPozadina.get(sadrzaj); - Paint bojaTekst = bojaPoljaTekst.get(sadrzaj); - crtajPolje(gc, i, j, bojaPozadina, bojaTekst, "" + sadrzaj); - } - } - } - - protected static void crtajOkvir(GraphicsContext gc, double sirina, double visina) { - gc.setFill(bojaPozadine); - gc.fillRect(0, 0, sirina, visina); - if (debljinaOkvira <= 0) { - return; - } - gc.setFill(bojaOkvira); - gc.fillRoundRect(x(-debljinaOkvira), x(-debljinaOkvira), w(sirinaMape + 2 * debljinaOkvira), w(visinaMape + 2 * debljinaOkvira), r(), r()); - gc.setFill(bojaPozadine); - gc.fillRoundRect(x(-1, 1), x(-1, 1), w(sirinaMape, 2), w(visinaMape, 2), r(), r()); - } - - protected static void crtajPolje(GraphicsContext gc, int x, int y, Paint bojaPozadina, Paint bojaTekst, String tekst) { - if (bojaPozadina != null) { - gc.setFill(bojaPozadina); - gc.fillRoundRect(x(x), x(y), w(1), w(1), r(), r()); - } - if (tekst != null && bojaTekst != null) { - gc.setFill(bojaTekst); - gc.fillText(tekst, x(x, 0.5), x(y, 0.5)); - } - } - - protected static void crtajPut(String naziv) { - Canvas platno = platnaZaPuteve.get(naziv); - GraphicsContext gc = platno.getGraphicsContext2D(); - gc.clearRect(0, 0, platno.getWidth(), platno.getHeight()); - FunkcijaZaPut fja = funkcijeZaPuteve.get(naziv); - Paint boja = bojeZaPuteve.get(naziv); - double debljina = debljinaPuta; - List koraci = new ArrayList<>(); - int i = 0; KorakPuta korak; - while ((korak = fja.korak(i++)) != null) { - koraci.add(korak); - } - crtajPut(gc, koraci, boja, debljina); - } - - protected static void crtajPut(GraphicsContext gc, List koraci, Paint boja, double debljina) { - gc.setStroke(boja); - gc.setLineWidth(debljina); - if (koraci.size() == 1) { - KorakPuta k = koraci.get(0); - gc.setFill(boja); - gc.fillOval(k(k.x) - debljina / 2, k(k.y) - debljina / 2, debljina, debljina); - } - for (int j = 1; j < koraci.size(); j++) { - KorakPuta k1 = koraci.get(j - 1); - KorakPuta k2 = koraci.get(j); - gc.strokeLine(k(k1.x), k(k1.y), k(k2.x), k(k2.y)); - } - } - - /////////////// - // Animacija // - /////////////// - - protected static boolean nekoCeka = false; - protected static long vremeCekanja = 1000; - - protected static synchronized void cekajAkoTreba() { - long pocetak = System.currentTimeMillis(); - if (vremeCekanja == 0) { - return; - } - nekoCeka = true; - long vreme; - boolean bioPrekid = Thread.interrupted(); - while (nekoCeka && (vreme = pocetak + vremeCekanja - System.currentTimeMillis()) > 0) { - try { - Prikaz.class.wait(vreme); - } catch (InterruptedException e) { - bioPrekid = true; - } - } - if (bioPrekid) { - Thread.currentThread().interrupt(); - } - nekoCeka = false; - } - - protected static synchronized void podesiVreme(long novoVremeCekanja) { - vremeCekanja = novoVremeCekanja; - Prikaz.class.notify(); - } - - protected static synchronized void zavrsiCekanje() { - nekoCeka = false; - Prikaz.class.notify(); - } - - protected static long podesiVreme(double stepen) { - stepen = 5 - stepen; - if (stepen <= 1) { - podesiVreme(0); - return 0; - } - long vrednost = (long) Math.pow(10, stepen); - podesiVreme(vrednost); - return vrednost; - } - - //////////////// - // Pokretanje // - //////////////// - - protected static void pokreni() { - Runnable launcher = () -> { - launch(new String[] {}); - }; - new Thread(launcher).start(); - } - - protected static void odradiKasnije(Runnable zadatak) { - Platform.runLater(zadatak); - } -} diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Put.java b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Put.java deleted file mode 100644 index e942883..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/Put.java +++ /dev/null @@ -1,98 +0,0 @@ -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javafx.scene.paint.Color; - -/** - * Klasa Put koristi se za pamcenje puta kroz mapu. - */ -public class Put { - - // Pamtimo sva polja na putu - private ArrayList polja; - - // Dodato da se omoguci pristup poljima puta "od spolja" (za proveru kvaliteta puta na primer), - // ali tako da ne moze da se utice na sam sadrzaj te liste - private List nepromenljivaListaPolja; - - // Potrebno za graficki prikaz - private String naziv; - - // Potrebno za graficki prikaz - private Put(String naziv, Color boja) { - polja = new ArrayList(); - nepromenljivaListaPolja = Collections.unmodifiableList(polja); - this.naziv = naziv; - Prikaz.put(naziv, polja, Polje::getX, Polje::getY, this::toString, boja); - } - - // Kreira novo prazno resenje - public Put() { - this("Trenutni", Prikaz.TIRKIZNA); - } - - // Kreira novo resenje sa istim sadrzajem kao original - public Put(Put original) { - this("Optimalan", Prikaz.LJUBICASTA); - polja.addAll(original.polja); - } - - // Dodaje polje u resenje - public void dodaj(int x, int y, int v) { - polja.add(new Polje(x, y, v)); - Prikaz.osveziPut(naziv); - } - - // Izbacuje poslednje polje iz puta - public void izbaciKraj() { - if (getLength() > 0) { - polja.remove(getLength() - 1); - Prikaz.osveziPut(naziv); - } else { - throw new IllegalStateException("Resenje je vec prazno"); - } - } - - // Stampa put - public void stampaj() { - System.out.println(getLength()); - for (int i = 0; i < getLength(); i++) { - System.out.println(polja.get(i)); - } - Prikaz.put("Trenutni", null, null, null); - Prikaz.put("Optimalan", null, null, null); - Prikaz.put("Najbolji", polja, Polje::getX, Polje::getY, this::toString, Prikaz.LJUBICASTA); - } - - public String toString() { - return getVrednost() + "\u20ac " + getLength() + "m"; - } - - // Vraca duzinu puta - public int getLength() { - return polja.size(); - } - - // Vraca i-to polje na putu - // Ne koristi se u ovoj verziji zadatka. Moze se koristiti za proveru kvaliteta resenja - public Polje getPolje(int i) { - return polja.get(i); - } - - // Vraca sva polja na putu - // Ne koristi se u ovoj verziji zadatka. Moze se koristiti za proveru kvaliteta resenja - public List getPolja() { - return nepromenljivaListaPolja; - } - - // Vraca vrednost puta - // Vrednost se definise kao zbir svih vrednosti polja na putu - public int getVrednost() { - int rez = 0; - for (Polje p : polja) { - rez = rez + p.getV(); - } - return rez; - } -} diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago1.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago1.txt deleted file mode 100644 index 5105c10..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago1.txt +++ /dev/null @@ -1,5 +0,0 @@ -5 4 - 0 0 5 0 0 - 0 4 -1 0 0 - 0 1 -1 -1 -1 - 5 0 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago2.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago2.txt deleted file mode 100644 index 7bfb346..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago2.txt +++ /dev/null @@ -1,6 +0,0 @@ -5 5 - 0 0 0 -1 -5 - 7 -1 0 -1 0 - 0 -1 3 3 5 - 0 -1 1 -1 0 --1 -1 15 0 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago3.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago3.txt deleted file mode 100644 index 28a830e..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/blago3.txt +++ /dev/null @@ -1,10 +0,0 @@ -8 9 - 0 0 0 4 0 2 0 0 --1 -1 -1 -1 -1 -1 0 -1 - 0 4 0 3 0 0 0 -1 - 0 2 5 1 0 6 0 -1 - 0 -1 -1 -1 0 0 12 -1 - 0 10 -5 1 -1 0 0 -1 --1 -1 -1 0 0 6 0 1 - 0 -1 20 0 -1 0 -1 0 --1 -1 0 15 0 0 -1 99 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l-prazan.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l-prazan.txt deleted file mode 100644 index cc98c8e..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l-prazan.txt +++ /dev/null @@ -1,4 +0,0 @@ -3 3 - 0 0 0 - 0 0 0 - 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l1.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l1.txt deleted file mode 100644 index 3b92da0..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l1.txt +++ /dev/null @@ -1,5 +0,0 @@ -5 4 - 0 0 0 0 0 - 0 0 -1 0 0 - 0 0 -1 -1 -1 - 0 0 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l2.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l2.txt deleted file mode 100644 index 28796c0..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l2.txt +++ /dev/null @@ -1,6 +0,0 @@ -5 5 - 0 0 0 -1 -5 - 0 -1 0 -1 0 - 0 -1 0 0 0 - 0 -1 0 -1 0 --1 -1 0 0 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l3.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l3.txt deleted file mode 100644 index fb1f4e4..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l3.txt +++ /dev/null @@ -1,10 +0,0 @@ -8 9 - 0 0 0 0 0 0 0 0 --1 -1 -1 -1 -1 -1 0 -1 - 0 0 0 0 0 0 0 -1 - 0 0 0 0 0 0 0 -1 - 0 -1 -1 -1 0 0 0 -1 - 0 0 -5 0 -1 0 0 -1 --1 -1 -1 0 0 0 0 0 - 0 -1 0 0 -1 0 -1 0 --1 -1 0 0 0 0 -1 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l4.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l4.txt deleted file mode 100644 index 444dab5..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/l4.txt +++ /dev/null @@ -1,11 +0,0 @@ -10 10 - 0 0 0 0 0 0 0 0 0 0 - 0 -1 -1 -1 -1 -1 -1 -1 0 -1 - 0 -1 0 0 0 0 0 -1 0 -1 - 0 -1 0 -1 0 -1 0 -1 0 -1 - 0 -1 0 -1 0 -1 0 -1 0 -1 - 0 -1 0 0 -5 -1 0 -1 0 -1 - 0 0 0 -1 -1 0 0 -1 0 0 - 0 0 0 -1 0 0 -1 0 0 0 --1 -1 0 -1 0 0 0 0 -1 0 - 0 0 0 0 0 0 0 0 -1 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lav.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lav.txt deleted file mode 100644 index e32db19..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lav.txt +++ /dev/null @@ -1,7 +0,0 @@ -5 6 - 0 0 0 -1 -5 - 0 -1 0 -1 0 - 0 -1 0 0 0 - 0 -1 0 -1 0 --1 -1 0 0 0 - 0 -1 0 0 -1 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lavblok.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lavblok.txt deleted file mode 100644 index ee5fe19..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/lavblok.txt +++ /dev/null @@ -1,4 +0,0 @@ -3 3 - 0 0 0 - 0 -1 -1 - 0 -1 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/readme.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/readme.txt deleted file mode 100644 index cb7d47d..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/readme.txt +++ /dev/null @@ -1,11 +0,0 @@ -Pri koristicenju programa moguce je koristiti sledece fajlove: - -lav.txt - sadrzi lavirint koji se moze koristiti za proveru da -li postoji put, ispis puta i ispis najkraceg puta. - -lavblok.txt - sadrzi lavirint u kojem ne postoji put - -l1.txt, l2.txt, l3.txt, l4.txt sadrze razlicite resive lavirinte. - -blago1.txt, blago2.txt i blago3.txt - sadrzi lavirinte sa blagom -za testiranje najvrednijeg puta. diff --git a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/zadatak-lavirint.txt b/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/zadatak-lavirint.txt deleted file mode 100644 index 5581283..0000000 --- a/PretrazivanjeSaVracanjem/Lavirint/ObjedinjenoResenje/zadatak-lavirint.txt +++ /dev/null @@ -1,57 +0,0 @@ -Zadatak - pretrazivanje sa vracanjem - lavirint -============================================================ - -Napisati program koji ucitava lavirint iz fajla i nalazi put -ili puteve sa odredjenim osobinama. - - -Format fajla ------------------------------------------------------------- - -Lavirint je u fajlu predstavljen na sledeci nacin: - -U prvom redu se nalaze dva broja S i V (1<= S, V <=10), koji -predstavljaju sirinu i visinu lavirinta. U sledecih V redova -se nalaze po S celih brojeva koji predstavljaju lavirint. -Brojevi imaju sledece znacenje: - - 0 - prazno polje --1 - zid, na ovo polje se ne moze stupiti --5 - izlaz iz lavirinta - -Sa jednog polja se moze preci na drugo, ukoliko imaju -zajednicku stranicu, odnosno mozemo preci na polje levo, -desno, gore ili dole. - -Pri ucitavanju pretpostaviti da ukoliko fajl postoji da su -podaci u njemu ispravno zadati. - - -Zadatak ------------------------------------------------------------- - -- Napisati program tako da proverava da li postoji put od -pocetnog polja do izlaza iz lavirinta. Pocetno polje je na -koordinatama 1,1, odnosno u gornjem levom uglu. - -- Program prosiriti tako da na ekran ispisuje trazeni put -(ako postoji). - -- Modifikovati program tako da vraca najkraci put do -izlaza. - -- Razmotriti sledecu modifikaciju problema: - -U drevnim lavirintima se nalaze zlatnici razasuti po -poljima. Ovi lavirinti su veoma opasni, pa ih nije -jednostavno pokupiti, vec se to moze raditi samo pomocu -specijalnih robota. Na srecu pronadjene su mape koje -precizno pokazuju kako lavirinti izgledaju, gde su im izlazi -i koliko zlatnika se moze pokupiti na kom polju. Sada treba -naci put kroz lavirint tako da se pokupi sto vise zlatnika, -a da se pri tome ne nagazi na isto polje dva puta. - -Pri ucitavanju lavirinta, bilo koji pozitivan broj -predstavlja broj zlatnika na tom polju. Program treba da -vraca optimalni put do izlaza, odnosno takav da se pokupi -sto vise zlatnika na putu. diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Lavirint.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Lavirint.java new file mode 100644 index 0000000..5b84e5a --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Lavirint.java @@ -0,0 +1,156 @@ +import java.util.Comparator; + +/** + * Klasa Lavirint sadrzi 3 javne i tri privatne metode za trazenje puteva. + * + * Klase KomparatorPoDuzini i KomparatorPoVrednosti predstavljaju komparatore + * koji se korste pri trazenju najkraceg i najvrednijeg puta. + */ +public class Lavirint { + + // Polje m sadrzi kompletnu mapu + private Mapa m; + + // Polje optResenje sluzi za pamcenje optimalnog resenja + private Put optResenje; + + // Ucitava mapu iz datog fajla i stampa je na ekran + Lavirint(String imeFajla) { + m = new Mapa(imeFajla); + m.stampaj(); + } + + // Provarava da li postoji put do izlaza i vraca vrednost true + // ako postoji put ili vrednost false ako ne postoji + public boolean postojiPut(int x, int y) { + if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { + return false; + } + if (m.getPos(x, y) == true) { + return false; + } + if (m.getMat(x, y) == Mapa.ZID) { + return false; + } + if (m.getMat(x, y) == Mapa.IZLAZ) { + return true; + } + m.setPos(x, y, true); + if (postojiPut(x + 1, y)) { + return true; + } + if (postojiPut(x - 1, y)) { + return true; + } + if (postojiPut(x, y + 1)) { + return true; + } + if (postojiPut(x, y - 1)) { + return true; + } + m.setPos(x, y, false); + return false; + } + + // Poziva metodu rput da pronadje i ispise put, ako postoji + // Ukoliko put ne postoji, ispisuje poruku o gresci + public void nadjiPut(int x, int y) { + if (!rput(x, y)) { + System.err.println("Ne postoji put"); + } + } + + // Proverava da li postoji put korsiteci pretrazivanje sa vracanjem + // Ukoliko se pronadje izlaz iz lavirinta, stampa se put u obrnutom + // redosledu + // Put se stampa pri povratku iz rekurzije + private boolean rput(int x, int y) { + if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { + return false; + } + if (m.getPos(x, y)) { + return false; + } + if (m.getMat(x, y) == Mapa.ZID) { + return false; + } + if (m.getMat(x, y) == Mapa.IZLAZ) { + System.out.println(x + " " + y); + return true; + } + m.setPos(x, y, true); + if (rput(x + 1, y) || rput(x, y + 1) || rput(x, y - 1) + || rput(x - 1, y)) { + System.out.println(x + " " + y); + return true; + } + m.setPos(x, y, false); + return false; + } + + // Kreira optimalno resenje za put, pri cemu se za optimalnost resenja + // koristi komparator po duzini resenja, tj. trazi se najkrace resenje + // Samo resenje kreira se u metodi optPut + public Put najkraciPut(int x, int y) { + Put r = new Put(); + optPut(x, y, r, new KomparatorPoDuzini()); + return optResenje; + } + + // Kreira optimalno resenje za put, pri cemu se za optimalnost resenja + // koristi komparator po duzini resenja, tj. trazi se najvrednije resenje + // Samo resenje kreira se u metodi optPut + public Put najvrednijiPut(int x, int y) { + Put trenutni = new Put(); + optPut(x, y, trenutni, new KomparatorPoVredosti()); + return optResenje; + } + + // Proverava da li postoji put korsiteci pretrazivanje sa vracanjem + // Ukoliko se pronadje na prvi ili optimalniji put, taj put se pamti u + // optResenje + // Optimalnost puta se proverava komparatorom + private void optPut(int x, int y, Put trenutni, Comparator c) { + if (x < 0 || x >= m.getSirina() || y < 0 || y >= m.getVisina()) { + return; + } + if (m.getPos(x, y)) { + return; + } + if (m.getMat(x, y) == Mapa.ZID) { + return; + } + if (m.getMat(x, y) == Mapa.IZLAZ) { + trenutni.dodaj(x, y, 0); + if (optResenje == null || c.compare(trenutni, optResenje) < 0) { + optResenje = new Put(trenutni); + } + trenutni.izbaciKraj(); + return; + } + + // pokusavamo da trazimo dalje put + m.setPos(x, y, true); + trenutni.dodaj(x, y, m.getMat(x, y)); + optPut(x + 1, y, trenutni, c); + optPut(x, y + 1, trenutni, c); + optPut(x, y - 1, trenutni, c); + optPut(x - 1, y, trenutni, c); + m.setPos(x, y, false); + trenutni.izbaciKraj(); + } +} + +// Komparator za puteve po duzini resenja +class KomparatorPoDuzini implements Comparator { + public int compare(Put r1, Put r2) { + return r1.getLength() - r2.getLength(); + } +} + +// Komparator za puteve po vrednosti resenja +class KomparatorPoVredosti implements Comparator { + public int compare(Put r1, Put r2) { + return r2.getVrednost() - r1.getVrednost(); + } +} diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/LavirintProgram.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/LavirintProgram.java new file mode 100644 index 0000000..01adf52 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/LavirintProgram.java @@ -0,0 +1,71 @@ +/** + * Program za nalazenje puta u lavirintu. + * + * Date su cetiri varijante problema, od jednostavnijih ka slozenijima, radi + * ilustracije osnovnih koncepata i postepenog uvodjenja novih. + * + * Najjednostavnije je samo nalazenje da li put postoji. + * + * Prosirenje tog resenja nam ispisuje taj nadjeni put. + * + * Treca varijanta nalazi sve puteve i medju njima bira najkraci. + * + * Cetvrta varijanta resava lavirint u kome su rasuti zlatnici na poljima i + * nalazi put na kome se kupi najvise zlatnika. + */ + +public class LavirintProgram { + + public static void main(String[] args) { + Svetovid.out.println("Unesite ime fajla: "); + String fajl = Svetovid.in.readLine(); + if (!Svetovid.testIn(fajl)) { + System.out.println("Greska: nema fajla!"); + return; + } + + Lavirint l = new Lavirint(fajl); + Put r; + + if (l != null) { + System.out.println("1 - da li postoji put"); + System.out.println("2 - ispis nekog puta (ako postoji)"); + System.out.println("3 - nalazenje najkraceg puta"); + System.out.println("4 - nalazenje najvrednijeg puta"); + System.out.println("Unesite izbor 1-4:"); + int op = Svetovid.in.readInt(); + + switch (op) { + case 1: + if (l.postojiPut(0, 0)) { + System.out.println("Postoji put"); + } else { + System.out.println("Ne postoji put"); + } + break; + case 2: + l.nadjiPut(0, 0); + break; + case 3: + r = l.najkraciPut(0, 0); + if (r != null) { + r.stampaj(); + } else { + System.out.println("Nema resenja"); + } + break; + case 4: + r = l.najvrednijiPut(0, 0); + if (r != null) { + r.stampaj(); + System.out.println("Vrednost puta: " + r.getVrednost()); + } else { + System.out.println("Nema resenja"); + } + break; + default: + System.err.println("Uneli ste pogresan izbor"); + } + } + } +} \ No newline at end of file diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Mapa.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Mapa.java new file mode 100644 index 0000000..a39c662 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Mapa.java @@ -0,0 +1,94 @@ + +/** + * Klasa Mapa koristi se za reprezentaciju lavirint i njegovih polja. + */ +public class Mapa { + + // Vrednosti polja i njihova znacenja + public final static int IZLAZ = -5; + public final static int ZID = -1; + public final static int GRESKA = Integer.MIN_VALUE; + + // Dimenzije mape + private int visina, sirina; + + // Polja mape + private int[][] mat; + + // Prilikom pretrazivanja ovde mozemo pamtiti koja polja smo posetili a koja nismo + private boolean[][] pos; + + public int getSirina() { + return sirina; + } + + public int getVisina() { + return visina; + } + + public void setPos(int x, int y, boolean b) { + if (0 <= x && x < sirina && 0 <= y && y < visina) { + pos[x][y] = b; + } + } + + public boolean getPos(int x, int y) { + if (0 <= x && x < sirina && 0 <= y && y < visina) { + return pos[x][y]; + } else { + return true; + } + } + + public int getMat(int x, int y) { + if (0 <= x && x < sirina && 0 <= y && y < visina) { + return mat[x][y]; + } else { + return GRESKA; + } + } + + public Mapa(int sirina, int visina) { + this.sirina = sirina; + this.visina = visina; + mat = new int[sirina][visina]; + pos = new boolean[sirina][visina]; + } + + public Mapa(String imeFajla) { + if (!Svetovid.testIn(imeFajla)) { + throw new RuntimeException("Fajl za kreiranje mape (" + imeFajla + ") nije prisupacan"); + } + sirina = Svetovid.in(imeFajla).readInt(); + visina = Svetovid.in(imeFajla).readInt(); + mat = new int[sirina][visina]; + pos = new boolean[sirina][visina]; + for (int j = 0; j < visina; j++) { + for (int i = 0; i < sirina; i++) { + mat[i][j] = Svetovid.in(imeFajla).readInt(); + } + } + Svetovid.closeIn(imeFajla); + Prikaz.boja(ZID, Prikaz.CRNA, null); + Prikaz.boja(IZLAZ, Prikaz.CRVENA, Prikaz.BELA); + Prikaz.boja(1, 20, Prikaz.SVETLO_ZELENA, Prikaz.ZELENA, Prikaz.CRNA); + Prikaz.boja(99, Prikaz.ZUTA, Prikaz.CRNA); + Prikaz.mapa("Lavirint", getSirina(), getVisina(), this::getMat); + } + + public void stampaj() { + if (visina != 0 && sirina != 0) { + System.out.println(visina + " " + sirina); + for (int j = 0; j < visina; j++) { + for (int i = 0; i < sirina; i++) { + System.out.print(mat[i][j] + "\t"); + } + System.out.println(); + } + } + } + + public String toString() { + return "Mapa velicine " + sirina + " x " + visina; + } +} diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Polje.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Polje.java new file mode 100644 index 0000000..15676d1 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Polje.java @@ -0,0 +1,30 @@ +/** + * Klasa Polje se koristi za pamcenje x i y koordinata nekog polja, kao i + * vrednosti na toj poziciji u mapi + */ +public class Polje { + + private final int x, y, v; + + public Polje(int x, int y, int v) { + this.x = x; + this.y = y; + this.v = v; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getV() { + return v; + } + + public String toString() { + return "(" + x + ", " + y + ") " + v; + } +} diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Prikaz.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Prikaz.java new file mode 100644 index 0000000..aa95160 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Prikaz.java @@ -0,0 +1,487 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import javafx.application.Application; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Insets; +import javafx.geometry.VPos; +import javafx.scene.Scene; +import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.Slider; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import javafx.scene.shape.Circle; +import javafx.scene.shape.StrokeLineCap; +import javafx.scene.shape.StrokeLineJoin; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.scene.text.TextAlignment; +import javafx.stage.Stage; + +public class Prikaz extends Application { + + public static final Color STVARNO_BELA = Color.hsb(0, 0, 1.0); + public static final Color BELA = Color.hsb(0, 0, 0.95); + public static final Color SVETLO_SIVA = Color.hsb(0, 0, 0.8); + public static final Color SIVA = Color.hsb(0, 0, 0.6); + public static final Color TAMNO_SIVA = Color.hsb(0, 0, 0.4); + public static final Color CRNA = Color.hsb(0, 0, 0.2); + public static final Color STVARNO_CRNA = Color.hsb(0, 0, 0.0); + + public static final Color SVETLO_CRVENA = Color.hsb( 0, 0.2, 1.0); + public static final Color SVETLO_NARANDZASTA = Color.hsb( 30, 0.2, 1.0); + public static final Color SVETLO_ZUTA = Color.hsb( 60, 0.2, 1.0); + public static final Color SVETLO_ZELENA = Color.hsb(120, 0.2, 1.0); + public static final Color SVETLO_TIRKIZNA = Color.hsb(180, 0.2, 1.0); + public static final Color SVETLO_AZURNA = Color.hsb(210, 0.2, 1.0); + public static final Color SVETLO_PLAVA = Color.hsb(240, 0.2, 1.0); + public static final Color SVETLO_PURPURNA = Color.hsb(270, 0.2, 1.0); + public static final Color SVETLO_LJUBICASTA = Color.hsb(300, 0.2, 1.0); + public static final Color SVETLO_RUZICASTA = Color.hsb(330, 0.2, 1.0); + + public static final Color CRVENA = Color.hsb( 0, 0.9, 0.8); + public static final Color NARANDZASTA = Color.hsb( 30, 0.9, 0.8); + public static final Color ZUTA = Color.hsb( 60, 0.9, 0.8); + public static final Color ZELENA = Color.hsb(120, 0.9, 0.8); + public static final Color TIRKIZNA = Color.hsb(180, 0.9, 0.8); + public static final Color AZURNA = Color.hsb(210, 0.9, 0.8); + public static final Color PLAVA = Color.hsb(240, 0.9, 0.8); + public static final Color PURPURNA = Color.hsb(270, 0.9, 0.8); + public static final Color LJUBICASTA = Color.hsb(300, 0.9, 0.8); + public static final Color RUZICASTA = Color.hsb(330, 0.9, 0.8); + + public static final Color TAMNO_CRVENA = Color.hsb( 0, 0.8, 0.4); + public static final Color TAMNO_NARANDZASTA = Color.hsb( 30, 0.8, 0.4); + public static final Color TAMNO_ZUTA = Color.hsb( 60, 0.8, 0.4); + public static final Color TAMNO_ZELENA = Color.hsb(120, 0.8, 0.4); + public static final Color TAMNO_TIRKIZNA = Color.hsb(180, 0.8, 0.4); + public static final Color TAMNO_AZURNA = Color.hsb(210, 0.8, 0.4); + public static final Color TAMNO_PLAVA = Color.hsb(240, 0.8, 0.4); + public static final Color TAMNO_PURPURNA = Color.hsb(270, 0.8, 0.4); + public static final Color TAMNO_LJUBICASTA = Color.hsb(300, 0.8, 0.4); + public static final Color TAMNO_RUZICASTA = Color.hsb(330, 0.8, 0.4); + + //////////////////// + // Boje i stilovi // + //////////////////// + + protected static Paint bojaPozadine = BELA; + protected static Paint bojaOkvira = CRNA; + protected static Map bojaPoljaPozadina = new HashMap<>(); + protected static Map bojaPoljaTekst = new HashMap<>(); + protected static Font font = Font.font("Arial", FontWeight.BOLD, 12); + + public static void boja(Paint pozadina, Paint okvir) { + bojaPozadine = pozadina; + bojaOkvira = okvir; + } + + public static void boja(int vrednost, Paint bojaPozadine, Paint bojaTeksta) { + if (bojaPozadine == null) { + bojaPoljaPozadina.remove(vrednost); + } + bojaPoljaPozadina.put(vrednost, bojaPozadine); + if (bojaTeksta == null) { + bojaPoljaTekst.remove(vrednost); + } + bojaPoljaTekst.put(vrednost, bojaTeksta); + } + + public static void boja(int vrednostMin, int vrednostMax, Color bojaMin, Color bojaMax, Paint bojaTeksta) { + if (bojaMin == null || bojaMax == null) { + throw new IllegalArgumentException(); + } + int n = vrednostMax - vrednostMin; + for (int i = 0; i <= n; i++) { + int vrednost = vrednostMin + i; + bojaPoljaPozadina.put(vrednost, bojaMin.interpolate(bojaMax, (double) (i) / n)); + if (bojaTeksta == null) { + bojaPoljaTekst.remove(vrednost); + } + bojaPoljaTekst.put(vrednost, bojaTeksta); + } + } + + //////////////// + // Geometrija // + //////////////// + + private static double velicinaPolja = 32; + private static double velicinaRazmaka = 4; + private static int debljinaOkvira = 0; + private static double debljinaPuta = velicinaPolja / 2; + + public static void velicina(double polje, double razmak, int okvir) { + velicinaPolja = polje; + velicinaRazmaka = razmak; + debljinaOkvira = okvir; + debljinaPuta = velicinaPolja / 2; + } + + protected static double ukupnaDuzina(int brojPolja) { + return x(brojPolja + debljinaOkvira, 0.0); + } + + protected static double x(int indeks, double delta) { + indeks = indeks + debljinaOkvira; + return indeks * (velicinaPolja + velicinaRazmaka) + velicinaRazmaka + velicinaPolja * delta; + } + + protected static double x(int indeks) { + return x(indeks, 0.0); + } + + protected static double k(int indeks) { + return x(indeks, 0.5); + } + + protected static double w(int count, double delta) { + return (velicinaPolja + velicinaRazmaka) * count + velicinaRazmaka * (delta - 1); + } + + protected static double w(int count) { + return w(count, 0); + } + + protected static double r() { + return 2 * velicinaRazmaka; + } + + ///////////// + // Sadrzaj // + ///////////// + + protected static String naslovProzora; + protected static int sirinaMape; + protected static int visinaMape; + protected static FunkcijaZaMapu funkcijaZaMapu; + + @FunctionalInterface + public static interface FunkcijaZaMapu { + public int vrednostNa(int x, int y); + } + + public static void mapa(String naslov, int sirina, int visina, FunkcijaZaMapu funkcijaZaMapu) { + naslovProzora = naslov; + sirinaMape = sirina; + visinaMape = visina; + Prikaz.funkcijaZaMapu = funkcijaZaMapu; + pokreni(); + } + + protected static Map funkcijeZaPuteve = new LinkedHashMap<>(); + protected static Map funkcijeZaVrednostiPuteva = new LinkedHashMap<>(); + protected static Map bojeZaPuteve = new HashMap<>(); + + @FunctionalInterface + public static interface FunkcijaZaPut { + public KorakPuta korak(int indeks); + } + + @FunctionalInterface + public static interface FunkcijaZaVrednostPuta { + public String vrednost(); + } + + public static class KorakPuta { + public int x, y; + } + + public static KorakPuta korak(int x, int y) { + KorakPuta korak = new KorakPuta(); + korak.x = x; korak.y = y; + return korak; + } + + public static void put(String naziv, FunkcijaZaPut funkcijaZaPut, FunkcijaZaVrednostPuta funkcijaZaVrednostPuta, Paint boja) { + odradiKasnije(() -> { + funkcijeZaPuteve.remove(naziv); + funkcijeZaVrednostiPuteva.remove(naziv); + bojeZaPuteve.remove(naziv); + listaPuteva.remove(naziv); + Canvas platno = platnaZaPuteve.remove(naziv); + centerPane.getChildren().remove(platno); + if (funkcijaZaPut != null && funkcijaZaVrednostPuta != null && boja != null) { + funkcijeZaPuteve.put(naziv, funkcijaZaPut); + funkcijeZaVrednostiPuteva.put(naziv, funkcijaZaVrednostPuta); + bojeZaPuteve.put(naziv, boja); + platno = new Canvas(Prikaz.platno.getWidth(), Prikaz.platno.getHeight()); + platno.setOpacity(0.5); + platno.getGraphicsContext2D().setLineCap(StrokeLineCap.ROUND); + platno.getGraphicsContext2D().setLineJoin(StrokeLineJoin.ROUND); + platnaZaPuteve.put(naziv, platno); + centerPane.getChildren().add(1, platno); + listaPuteva.add(naziv); + crtajPut(naziv); + } + }); + } + + public static void put(String naziv, List lista, Function x, Function y, FunkcijaZaVrednostPuta funkcijaZaVrednostPuta, Paint boja) { + FunkcijaZaPut fja = (int indeks) -> { + try { + T element = lista.get(indeks); + return korak(x.apply(element), y.apply(element)); + } catch (IndexOutOfBoundsException e) { + return null; + } + }; + put(naziv, fja, funkcijaZaVrednostPuta, boja); + } + + public static void osveziPut(String naziv) { + odradiKasnije(() -> { + crtajPut(naziv); + listaPuteva.set(listaPuteva.indexOf(naziv), naziv); + }); + cekajAkoTreba(); + } + + ///////// + // GUI // + ///////// + + protected static StackPane centerPane; + protected static ListView listView; + protected static ObservableList listaPuteva = FXCollections.observableArrayList(); + + @Override + public void start(Stage primaryStage) { + Label labelPutevi = new Label("Putevi:"); + listView = new ListView<>(listaPuteva); + listView.setCellFactory(l -> new ListCell() { + public void updateItem(String naziv, boolean empty) { + super.updateItem(naziv, empty); + if (empty || naziv == null) { + setText(null); + setGraphic(null); + } else { + Circle icon = new Circle(8); + icon.setFill(bojeZaPuteve.get(naziv)); + setGraphic(icon); + FunkcijaZaVrednostPuta fja = funkcijeZaVrednostiPuteva.get(naziv); + try { + setText(naziv + ": " + fja.vrednost()); + } catch (RuntimeException e) { + } + } + } + }); + + Label labelAnimacija = new Label(); + Slider slider = new Slider(0, 4, 2); + Button button = new Button(">"); + osveziPanelZaAnimaciju(labelAnimacija, button, slider.getValue()); + slider.valueProperty().addListener((value, oldValue, newValue) -> { + osveziPanelZaAnimaciju(labelAnimacija, button, newValue.doubleValue()); + }); + button.setOnAction(e -> { + zavrsiCekanje(); + }); + button.setMaxHeight(Double.MAX_VALUE); + + GridPane animationPane = new GridPane(); + animationPane.setHgap(6); + animationPane.setVgap(6); + ColumnConstraints column = new ColumnConstraints(); + column.setHgrow(Priority.ALWAYS); + animationPane.getColumnConstraints().add(column); + animationPane.add(labelAnimacija, 0, 0); + animationPane.add(slider, 0, 1); + animationPane.add(button, 1, 0, 1, 2); + + VBox rightPane = new VBox(); + rightPane.setPadding(new Insets(12, 12, 12, 12)); + rightPane.setSpacing(6); + rightPane.getChildren().add(labelPutevi); + listView.setPrefHeight(0); + VBox.setVgrow(listView, Priority.ALWAYS); + rightPane.getChildren().add(listView); + VBox.setMargin(animationPane, new Insets(6, 0, 0, 0)); + rightPane.getChildren().add(animationPane); + + platno = new Canvas(ukupnaDuzina(sirinaMape), ukupnaDuzina(visinaMape)); + osveziMapu(); + centerPane = new StackPane(platno); + + BorderPane rootPane = new BorderPane(); + rootPane.setCenter(centerPane); + rootPane.setRight(rightPane); + Scene scene = new Scene(rootPane); + + primaryStage.setTitle(naslovProzora + " - " + sirinaMape + " x " + visinaMape + ""); + primaryStage.setAlwaysOnTop(true); + primaryStage.setResizable(false); + primaryStage.setOnCloseRequest(e -> podesiVreme(0)); + primaryStage.setScene(scene); + primaryStage.show(); + + } + + protected static void osveziPanelZaAnimaciju(Label labela, Button dugme, double vrednost) { + long vreme = podesiVreme(vrednost); + String tekst = "Brzina animacije: " + String.format("%.2f", vreme / 1000.0) + "s"; + dugme.setVisible(vreme >= 1000); + labela.setText(tekst); + } + + ///////////// + // Crtanje // + ///////////// + + protected static Canvas platno; + protected static Map platnaZaPuteve = new LinkedHashMap<>(); + + protected static void osveziMapu() { + crtajMapu(platno.getGraphicsContext2D(), platno.getWidth(), platno.getHeight()); + } + + protected static void crtajMapu(GraphicsContext gc, double sirina, double visina) { + gc.setTextAlign(TextAlignment.CENTER); + gc.setTextBaseline(VPos.CENTER); + gc.setFont(font); + crtajOkvir(gc, sirina, visina); + for (int j = 0; j < visinaMape; j++) { + for (int i = 0; i < sirinaMape; i++) { + int sadrzaj = funkcijaZaMapu.vrednostNa(i, j); + Paint bojaPozadina = bojaPoljaPozadina.get(sadrzaj); + Paint bojaTekst = bojaPoljaTekst.get(sadrzaj); + crtajPolje(gc, i, j, bojaPozadina, bojaTekst, "" + sadrzaj); + } + } + } + + protected static void crtajOkvir(GraphicsContext gc, double sirina, double visina) { + gc.setFill(bojaPozadine); + gc.fillRect(0, 0, sirina, visina); + if (debljinaOkvira <= 0) { + return; + } + gc.setFill(bojaOkvira); + gc.fillRoundRect(x(-debljinaOkvira), x(-debljinaOkvira), w(sirinaMape + 2 * debljinaOkvira), w(visinaMape + 2 * debljinaOkvira), r(), r()); + gc.setFill(bojaPozadine); + gc.fillRoundRect(x(-1, 1), x(-1, 1), w(sirinaMape, 2), w(visinaMape, 2), r(), r()); + } + + protected static void crtajPolje(GraphicsContext gc, int x, int y, Paint bojaPozadina, Paint bojaTekst, String tekst) { + if (bojaPozadina != null) { + gc.setFill(bojaPozadina); + gc.fillRoundRect(x(x), x(y), w(1), w(1), r(), r()); + } + if (tekst != null && bojaTekst != null) { + gc.setFill(bojaTekst); + gc.fillText(tekst, x(x, 0.5), x(y, 0.5)); + } + } + + protected static void crtajPut(String naziv) { + Canvas platno = platnaZaPuteve.get(naziv); + GraphicsContext gc = platno.getGraphicsContext2D(); + gc.clearRect(0, 0, platno.getWidth(), platno.getHeight()); + FunkcijaZaPut fja = funkcijeZaPuteve.get(naziv); + Paint boja = bojeZaPuteve.get(naziv); + double debljina = debljinaPuta; + List koraci = new ArrayList<>(); + int i = 0; KorakPuta korak; + while ((korak = fja.korak(i++)) != null) { + koraci.add(korak); + } + crtajPut(gc, koraci, boja, debljina); + } + + protected static void crtajPut(GraphicsContext gc, List koraci, Paint boja, double debljina) { + gc.setStroke(boja); + gc.setLineWidth(debljina); + if (koraci.size() == 1) { + KorakPuta k = koraci.get(0); + gc.setFill(boja); + gc.fillOval(k(k.x) - debljina / 2, k(k.y) - debljina / 2, debljina, debljina); + } + for (int j = 1; j < koraci.size(); j++) { + KorakPuta k1 = koraci.get(j - 1); + KorakPuta k2 = koraci.get(j); + gc.strokeLine(k(k1.x), k(k1.y), k(k2.x), k(k2.y)); + } + } + + /////////////// + // Animacija // + /////////////// + + protected static boolean nekoCeka = false; + protected static long vremeCekanja = 1000; + + protected static synchronized void cekajAkoTreba() { + long pocetak = System.currentTimeMillis(); + if (vremeCekanja == 0) { + return; + } + nekoCeka = true; + long vreme; + boolean bioPrekid = Thread.interrupted(); + while (nekoCeka && (vreme = pocetak + vremeCekanja - System.currentTimeMillis()) > 0) { + try { + Prikaz.class.wait(vreme); + } catch (InterruptedException e) { + bioPrekid = true; + } + } + if (bioPrekid) { + Thread.currentThread().interrupt(); + } + nekoCeka = false; + } + + protected static synchronized void podesiVreme(long novoVremeCekanja) { + vremeCekanja = novoVremeCekanja; + Prikaz.class.notify(); + } + + protected static synchronized void zavrsiCekanje() { + nekoCeka = false; + Prikaz.class.notify(); + } + + protected static long podesiVreme(double stepen) { + stepen = 5 - stepen; + if (stepen <= 1) { + podesiVreme(0); + return 0; + } + long vrednost = (long) Math.pow(10, stepen); + podesiVreme(vrednost); + return vrednost; + } + + //////////////// + // Pokretanje // + //////////////// + + protected static void pokreni() { + Runnable launcher = () -> { + launch(new String[] {}); + }; + new Thread(launcher).start(); + } + + protected static void odradiKasnije(Runnable zadatak) { + Platform.runLater(zadatak); + } +} diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Put.java b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Put.java new file mode 100644 index 0000000..e942883 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/Put.java @@ -0,0 +1,98 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javafx.scene.paint.Color; + +/** + * Klasa Put koristi se za pamcenje puta kroz mapu. + */ +public class Put { + + // Pamtimo sva polja na putu + private ArrayList polja; + + // Dodato da se omoguci pristup poljima puta "od spolja" (za proveru kvaliteta puta na primer), + // ali tako da ne moze da se utice na sam sadrzaj te liste + private List nepromenljivaListaPolja; + + // Potrebno za graficki prikaz + private String naziv; + + // Potrebno za graficki prikaz + private Put(String naziv, Color boja) { + polja = new ArrayList(); + nepromenljivaListaPolja = Collections.unmodifiableList(polja); + this.naziv = naziv; + Prikaz.put(naziv, polja, Polje::getX, Polje::getY, this::toString, boja); + } + + // Kreira novo prazno resenje + public Put() { + this("Trenutni", Prikaz.TIRKIZNA); + } + + // Kreira novo resenje sa istim sadrzajem kao original + public Put(Put original) { + this("Optimalan", Prikaz.LJUBICASTA); + polja.addAll(original.polja); + } + + // Dodaje polje u resenje + public void dodaj(int x, int y, int v) { + polja.add(new Polje(x, y, v)); + Prikaz.osveziPut(naziv); + } + + // Izbacuje poslednje polje iz puta + public void izbaciKraj() { + if (getLength() > 0) { + polja.remove(getLength() - 1); + Prikaz.osveziPut(naziv); + } else { + throw new IllegalStateException("Resenje je vec prazno"); + } + } + + // Stampa put + public void stampaj() { + System.out.println(getLength()); + for (int i = 0; i < getLength(); i++) { + System.out.println(polja.get(i)); + } + Prikaz.put("Trenutni", null, null, null); + Prikaz.put("Optimalan", null, null, null); + Prikaz.put("Najbolji", polja, Polje::getX, Polje::getY, this::toString, Prikaz.LJUBICASTA); + } + + public String toString() { + return getVrednost() + "\u20ac " + getLength() + "m"; + } + + // Vraca duzinu puta + public int getLength() { + return polja.size(); + } + + // Vraca i-to polje na putu + // Ne koristi se u ovoj verziji zadatka. Moze se koristiti za proveru kvaliteta resenja + public Polje getPolje(int i) { + return polja.get(i); + } + + // Vraca sva polja na putu + // Ne koristi se u ovoj verziji zadatka. Moze se koristiti za proveru kvaliteta resenja + public List getPolja() { + return nepromenljivaListaPolja; + } + + // Vraca vrednost puta + // Vrednost se definise kao zbir svih vrednosti polja na putu + public int getVrednost() { + int rez = 0; + for (Polje p : polja) { + rez = rez + p.getV(); + } + return rez; + } +} diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago1.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago1.txt new file mode 100644 index 0000000..5105c10 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago1.txt @@ -0,0 +1,5 @@ +5 4 + 0 0 5 0 0 + 0 4 -1 0 0 + 0 1 -1 -1 -1 + 5 0 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago2.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago2.txt new file mode 100644 index 0000000..7bfb346 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago2.txt @@ -0,0 +1,6 @@ +5 5 + 0 0 0 -1 -5 + 7 -1 0 -1 0 + 0 -1 3 3 5 + 0 -1 1 -1 0 +-1 -1 15 0 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago3.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago3.txt new file mode 100644 index 0000000..28a830e --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/blago3.txt @@ -0,0 +1,10 @@ +8 9 + 0 0 0 4 0 2 0 0 +-1 -1 -1 -1 -1 -1 0 -1 + 0 4 0 3 0 0 0 -1 + 0 2 5 1 0 6 0 -1 + 0 -1 -1 -1 0 0 12 -1 + 0 10 -5 1 -1 0 0 -1 +-1 -1 -1 0 0 6 0 1 + 0 -1 20 0 -1 0 -1 0 +-1 -1 0 15 0 0 -1 99 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l-prazan.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l-prazan.txt new file mode 100644 index 0000000..cc98c8e --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l-prazan.txt @@ -0,0 +1,4 @@ +3 3 + 0 0 0 + 0 0 0 + 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l1.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l1.txt new file mode 100644 index 0000000..3b92da0 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l1.txt @@ -0,0 +1,5 @@ +5 4 + 0 0 0 0 0 + 0 0 -1 0 0 + 0 0 -1 -1 -1 + 0 0 0 0 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l2.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l2.txt new file mode 100644 index 0000000..28796c0 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l2.txt @@ -0,0 +1,6 @@ +5 5 + 0 0 0 -1 -5 + 0 -1 0 -1 0 + 0 -1 0 0 0 + 0 -1 0 -1 0 +-1 -1 0 0 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l3.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l3.txt new file mode 100644 index 0000000..fb1f4e4 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l3.txt @@ -0,0 +1,10 @@ +8 9 + 0 0 0 0 0 0 0 0 +-1 -1 -1 -1 -1 -1 0 -1 + 0 0 0 0 0 0 0 -1 + 0 0 0 0 0 0 0 -1 + 0 -1 -1 -1 0 0 0 -1 + 0 0 -5 0 -1 0 0 -1 +-1 -1 -1 0 0 0 0 0 + 0 -1 0 0 -1 0 -1 0 +-1 -1 0 0 0 0 -1 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l4.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l4.txt new file mode 100644 index 0000000..444dab5 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/l4.txt @@ -0,0 +1,11 @@ +10 10 + 0 0 0 0 0 0 0 0 0 0 + 0 -1 -1 -1 -1 -1 -1 -1 0 -1 + 0 -1 0 0 0 0 0 -1 0 -1 + 0 -1 0 -1 0 -1 0 -1 0 -1 + 0 -1 0 -1 0 -1 0 -1 0 -1 + 0 -1 0 0 -5 -1 0 -1 0 -1 + 0 0 0 -1 -1 0 0 -1 0 0 + 0 0 0 -1 0 0 -1 0 0 0 +-1 -1 0 -1 0 0 0 0 -1 0 + 0 0 0 0 0 0 0 0 -1 0 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lav.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lav.txt new file mode 100644 index 0000000..e32db19 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lav.txt @@ -0,0 +1,7 @@ +5 6 + 0 0 0 -1 -5 + 0 -1 0 -1 0 + 0 -1 0 0 0 + 0 -1 0 -1 0 +-1 -1 0 0 0 + 0 -1 0 0 -1 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lavblok.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lavblok.txt new file mode 100644 index 0000000..ee5fe19 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/lavblok.txt @@ -0,0 +1,4 @@ +3 3 + 0 0 0 + 0 -1 -1 + 0 -1 -5 diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/readme.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/readme.txt new file mode 100644 index 0000000..cb7d47d --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/readme.txt @@ -0,0 +1,11 @@ +Pri koristicenju programa moguce je koristiti sledece fajlove: + +lav.txt - sadrzi lavirint koji se moze koristiti za proveru da +li postoji put, ispis puta i ispis najkraceg puta. + +lavblok.txt - sadrzi lavirint u kojem ne postoji put + +l1.txt, l2.txt, l3.txt, l4.txt sadrze razlicite resive lavirinte. + +blago1.txt, blago2.txt i blago3.txt - sadrzi lavirinte sa blagom +za testiranje najvrednijeg puta. diff --git a/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/zadatak-lavirint.txt b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/zadatak-lavirint.txt new file mode 100644 index 0000000..5581283 --- /dev/null +++ b/PretrazivanjeSaVracanjem/Lavirint/SuperKomplikovanoResenje/zadatak-lavirint.txt @@ -0,0 +1,57 @@ +Zadatak - pretrazivanje sa vracanjem - lavirint +============================================================ + +Napisati program koji ucitava lavirint iz fajla i nalazi put +ili puteve sa odredjenim osobinama. + + +Format fajla +------------------------------------------------------------ + +Lavirint je u fajlu predstavljen na sledeci nacin: + +U prvom redu se nalaze dva broja S i V (1<= S, V <=10), koji +predstavljaju sirinu i visinu lavirinta. U sledecih V redova +se nalaze po S celih brojeva koji predstavljaju lavirint. +Brojevi imaju sledece znacenje: + + 0 - prazno polje +-1 - zid, na ovo polje se ne moze stupiti +-5 - izlaz iz lavirinta + +Sa jednog polja se moze preci na drugo, ukoliko imaju +zajednicku stranicu, odnosno mozemo preci na polje levo, +desno, gore ili dole. + +Pri ucitavanju pretpostaviti da ukoliko fajl postoji da su +podaci u njemu ispravno zadati. + + +Zadatak +------------------------------------------------------------ + +- Napisati program tako da proverava da li postoji put od +pocetnog polja do izlaza iz lavirinta. Pocetno polje je na +koordinatama 1,1, odnosno u gornjem levom uglu. + +- Program prosiriti tako da na ekran ispisuje trazeni put +(ako postoji). + +- Modifikovati program tako da vraca najkraci put do +izlaza. + +- Razmotriti sledecu modifikaciju problema: + +U drevnim lavirintima se nalaze zlatnici razasuti po +poljima. Ovi lavirinti su veoma opasni, pa ih nije +jednostavno pokupiti, vec se to moze raditi samo pomocu +specijalnih robota. Na srecu pronadjene su mape koje +precizno pokazuju kako lavirinti izgledaju, gde su im izlazi +i koliko zlatnika se moze pokupiti na kom polju. Sada treba +naci put kroz lavirint tako da se pokupi sto vise zlatnika, +a da se pri tome ne nagazi na isto polje dva puta. + +Pri ucitavanju lavirinta, bilo koji pozitivan broj +predstavlja broj zlatnika na tom polju. Program treba da +vraca optimalni put do izlaza, odnosno takav da se pokupi +sto vise zlatnika na putu.