diff --git a/Alberi1/src/Main.java b/Alberi1/src/Main.java index da011a6..8829598 100644 --- a/Alberi1/src/Main.java +++ b/Alberi1/src/Main.java @@ -1,15 +1,14 @@ import static java.lang.Math.max; class Nodo{ + static java.util.Random rnd = new java.util.Random(); int dato; Nodo left, right; - public Nodo(int dato, Nodo left, Nodo right) { this.dato = dato; this.left = left; this.right = right; } - static void stampa(Nodo n, int livello, String lr) { if(n==null) return; for(int i=0;ialbero.dato) return new Nodo(albero.dato, albero.left, insOrd(val, albero.right)); return new Nodo(albero.dato, insOrd(val, albero.left), albero.right); } - static boolean trova(Nodo albero, int valore) { + static boolean trova(Nodo albero, int valore) { //Trova un valore if(albero==null) return false; else if(albero.dato==valore) return true; else return trova(albero.left, valore) || trova(albero.right, valore); } - static String valoriNelLivello(Nodo albero, int livello){ + static String valoriNelLivello(Nodo albero, int livello){ //Trova un valore in un livello if(albero==null) return ""; else if(livello==0) return albero.dato + " "; else return valoriNelLivello(albero.left, livello-1) + valoriNelLivello(albero.right, livello-1); } - static int altezza(Nodo albero){ + static int altezza(Nodo albero){ //Trova l'altezza dell'albero if(albero==null) return 0; else if (albero.left == null && albero.right == null) return 1; return 1 + max(altezza(albero.left), altezza(albero.right)); } + static boolean uguali(Nodo a, Nodo b) { //Controlla che i due alberi siano uguali + if (a == null && b == null) return true; + if (a == null || b == null) return false; + if (a.dato != b.dato) return false; + return uguali(a.left, b.left) && uguali(a.right, b.right); + } + static int profondita(Nodo albero, int val) { //Restituisce la profondità massima + if(albero==null) return -1; + else if(albero.left == null && albero.right == null && albero.dato != val) return -1; + else if(albero.dato == val) return 1; + int pl = profondita(albero.left,val); + int pr = profondita(albero.right,val); + int m = max(pl, pr); + if (m == -1) return -1; + return 1 + m; + } + static int contaFiglio(Nodo albero) { //Conta i nodi che hanno un solo figlio + int count = 0; + if(albero==null) return count; + else if ((albero.left == null && albero.right != null) || (albero.left != null && albero.right == null)) count = 1; + return count + contaFiglio(albero.left) + contaFiglio(albero.right); + } + static int contaNelLivello(Nodo albero, int livello) { //Conta i nodi nel livello + if(albero==null) return 0; + else if (livello == 0) return 1; + return contaNelLivello(albero.left, livello-1) + contaNelLivello(albero.right, livello-1); + } + static Nodo crea(int altezza) { //Crea un albero con altezza determinata + if (altezza == 0) return null; + else if (altezza == 1) return new Nodo(rnd.nextInt(41) + 10,null,null); + Nodo left = crea(altezza - 1); + Nodo right = crea(altezza - 1); + return new Nodo(rnd.nextInt(41) + 10, left, right); + } } @@ -92,5 +120,4 @@ public class Main { System.out.println("Somma: " + Nodo.somma(n4)); System.out.println("Trovato 24? " + Nodo.trova(n4,24)); } - } \ No newline at end of file diff --git a/LabirintoGUI/.gitignore b/LabirintoGUI/.gitignore new file mode 100644 index 0000000..13275f1 --- /dev/null +++ b/LabirintoGUI/.gitignore @@ -0,0 +1,30 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +.kotlin + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/LabirintoGUI/.idea/.gitignore b/LabirintoGUI/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/LabirintoGUI/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/LabirintoGUI/.idea/misc.xml b/LabirintoGUI/.idea/misc.xml new file mode 100644 index 0000000..07115cd --- /dev/null +++ b/LabirintoGUI/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LabirintoGUI/.idea/modules.xml b/LabirintoGUI/.idea/modules.xml new file mode 100644 index 0000000..a394414 --- /dev/null +++ b/LabirintoGUI/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/LabirintoGUI/.idea/vcs.xml b/LabirintoGUI/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/LabirintoGUI/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LabirintoGUI/LabirintoGUI.iml b/LabirintoGUI/LabirintoGUI.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/LabirintoGUI/LabirintoGUI.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/LabirintoGUI/src/MazeGame.java b/LabirintoGUI/src/MazeGame.java new file mode 100644 index 0000000..c6f5c81 --- /dev/null +++ b/LabirintoGUI/src/MazeGame.java @@ -0,0 +1,276 @@ +import javax.swing.*; +import javax.swing.Timer; +import java.awt.*; +import java.awt.event.*; +import java.util.*; + +public class MazeGame extends JFrame { + private static final int ROWS = 21; + private static final int COLS = 31; + private static final int CELL_SIZE = 25; + + private static final int WALL = 0; + private static final int PATH = 1; + private static final int END = 3; + private static final int PLAYER = 4; + + private final int[][] maze; + private int playerRow, playerCol; + private int endRow, endCol; + private MazePanel mazePanel; + private JLabel statusLabel; + private JLabel movesLabel; + private int moveCount = 0; + + public MazeGame() { + setTitle("Gioco del Labirinto"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setResizable(false); + + maze = new int[ROWS][COLS]; + generateMaze(); + + setupUI(); + + pack(); + setLocationRelativeTo(null); + setVisible(true); + } + + private void setupUI() { + setLayout(new BorderLayout()); + + // Panel superiore con informazioni + JPanel topPanel = new JPanel(new GridLayout(2, 1)); + topPanel.setBackground(new Color(44, 62, 80)); + topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + statusLabel = new JLabel("Raggiungi la bandiera! Usa le frecce per muoverti", SwingConstants.CENTER); + statusLabel.setFont(new Font("Arial", Font.BOLD, 16)); + statusLabel.setForeground(Color.WHITE); + + movesLabel = new JLabel("Mosse: 0", SwingConstants.CENTER); + movesLabel.setFont(new Font("Arial", Font.PLAIN, 14)); + movesLabel.setForeground(new Color(52, 152, 219)); + + topPanel.add(statusLabel); + topPanel.add(movesLabel); + + // Panel del labirinto + mazePanel = new MazePanel(); + mazePanel.setFocusable(true); + mazePanel.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + handleKeyPress(e.getKeyCode()); + } + }); + + // Panel inferiore con pulsanti + JPanel bottomPanel = new JPanel(); + bottomPanel.setBackground(new Color(44, 62, 80)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + JButton newGameButton = new JButton("Nuovo Gioco"); + newGameButton.setFont(new Font("Arial", Font.BOLD, 14)); + newGameButton.setBackground(new Color(46, 204, 113)); + newGameButton.setForeground(Color.WHITE); + newGameButton.setFocusPainted(false); + newGameButton.addActionListener(e -> newGame()); + + bottomPanel.add(newGameButton); + + add(topPanel, BorderLayout.NORTH); + add(mazePanel, BorderLayout.CENTER); + add(bottomPanel, BorderLayout.SOUTH); + } + + private void generateMaze() { + // Inizializza con muri + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + maze[i][j] = WALL; + } + } + + // Genera percorsi usando DFS + Random rand = new Random(); + Stack stack = new Stack<>(); + + int startRow = 1; + int startCol = 1; + maze[startRow][startCol] = PATH; + stack.push(new int[]{startRow, startCol}); + + int[][] directions = {{-2, 0}, {2, 0}, {0, -2}, {0, 2}}; + + while (!stack.isEmpty()) { + int[] current = stack.peek(); + int row = current[0]; + int col = current[1]; + + java.util.List neighbors = new ArrayList<>(); + + for (int[] dir : directions) { + int newRow = row + dir[0]; + int newCol = col + dir[1]; + + if (newRow > 0 && newRow < ROWS - 1 && + newCol > 0 && newCol < COLS - 1 && + maze[newRow][newCol] == WALL) { + neighbors.add(new int[]{newRow, newCol, row + dir[0]/2, col + dir[1]/2}); + } + } + + if (!neighbors.isEmpty()) { + int[] next = neighbors.get(rand.nextInt(neighbors.size())); + maze[next[2]][next[3]] = PATH; + maze[next[0]][next[1]] = PATH; + stack.push(new int[]{next[0], next[1]}); + } else { + stack.pop(); + } + } + + // Posiziona giocatore e fine + playerRow = 1; + playerCol = 1; + endRow = ROWS - 2; + endCol = COLS - 2; + + maze[playerRow][playerCol] = PLAYER; + maze[endRow][endCol] = END; + } + + private void handleKeyPress(int keyCode) { + int newRow = playerRow; + int newCol = playerCol; + + switch (keyCode) { + case KeyEvent.VK_UP: + newRow--; + break; + case KeyEvent.VK_DOWN: + newRow++; + break; + case KeyEvent.VK_LEFT: + newCol--; + break; + case KeyEvent.VK_RIGHT: + newCol++; + break; + default: + return; + } + + // Verifica se la mossa è valida + if (newRow >= 0 && newRow < ROWS && newCol >= 0 && newCol < COLS) { + if (maze[newRow][newCol] != WALL) { + // Muovi il giocatore + maze[playerRow][playerCol] = PATH; + playerRow = newRow; + playerCol = newCol; + + // Verifica se ha raggiunto la fine + if (playerRow == endRow && playerCol == endCol) { + maze[playerRow][playerCol] = PLAYER; + mazePanel.repaint(); + showVictory(); + } else { + maze[playerRow][playerCol] = PLAYER; + moveCount++; + movesLabel.setText("Mosse: " + moveCount); + mazePanel.repaint(); + } + } + } + } + + private void showVictory() { + statusLabel.setText("🎉 Complimenti! Hai vinto in " + moveCount + " mosse! 🎉"); + statusLabel.setForeground(new Color(46, 204, 113)); + + Timer timer = new Timer(3000, e -> { + int choice = JOptionPane.showConfirmDialog( + this, + "Hai completato il labirinto in " + moveCount + " mosse!\nVuoi giocare di nuovo?", + "Vittoria!", + JOptionPane.YES_NO_OPTION, + JOptionPane.INFORMATION_MESSAGE + ); + + if (choice == JOptionPane.YES_OPTION) { + newGame(); + } + }); + timer.setRepeats(false); + timer.start(); + } + + private void newGame() { + moveCount = 0; + movesLabel.setText("Mosse: 0"); + statusLabel.setText("Raggiungi la bandiera! Usa le frecce per muoverti"); + statusLabel.setForeground(Color.WHITE); + generateMaze(); + mazePanel.repaint(); + mazePanel.requestFocusInWindow(); + } + + class MazePanel extends JPanel { + public MazePanel() { + setPreferredSize(new Dimension(COLS * CELL_SIZE, ROWS * CELL_SIZE)); + setBackground(Color.BLACK); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + int x = j * CELL_SIZE; + int y = i * CELL_SIZE; + + switch (maze[i][j]) { + case WALL: + g2d.setColor(new Color(52, 73, 94)); + g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE); + g2d.setColor(new Color(44, 62, 80)); + g2d.drawRect(x, y, CELL_SIZE, CELL_SIZE); + break; + case PATH: + g2d.setColor(new Color(236, 240, 241)); + g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE); + break; + case END: + g2d.setColor(new Color(236, 240, 241)); + g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE); + // Bandiera + g2d.setColor(new Color(231, 76, 60)); + g2d.fillRect(x + 10, y + 5, 10, 8); + g2d.setColor(new Color(52, 73, 94)); + g2d.fillRect(x + 9, y + 5, 2, 15); + break; + case PLAYER: + g2d.setColor(new Color(236, 240, 241)); + g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE); + // Giocatore (cerchio) + g2d.setColor(new Color(52, 152, 219)); + g2d.fillOval(x + 5, y + 5, CELL_SIZE - 10, CELL_SIZE - 10); + g2d.setColor(Color.WHITE); + g2d.fillOval(x + 10, y + 8, 4, 4); + g2d.fillOval(x + CELL_SIZE - 14, y + 8, 4, 4); + break; + } + } + } + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(MazeGame::new); + } +} \ No newline at end of file diff --git a/LabirintoTest/.gitignore b/LabirintoTest/.gitignore new file mode 100644 index 0000000..13275f1 --- /dev/null +++ b/LabirintoTest/.gitignore @@ -0,0 +1,30 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +.kotlin + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/LabirintoTest/.idea/.gitignore b/LabirintoTest/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/LabirintoTest/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/LabirintoTest/.idea/misc.xml b/LabirintoTest/.idea/misc.xml new file mode 100644 index 0000000..07115cd --- /dev/null +++ b/LabirintoTest/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LabirintoTest/.idea/modules.xml b/LabirintoTest/.idea/modules.xml new file mode 100644 index 0000000..d3e904d --- /dev/null +++ b/LabirintoTest/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/LabirintoTest/.idea/vcs.xml b/LabirintoTest/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/LabirintoTest/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LabirintoTest/LabirintoTest.iml b/LabirintoTest/LabirintoTest.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/LabirintoTest/LabirintoTest.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/LabirintoTest/src/MazeSolver.java b/LabirintoTest/src/MazeSolver.java new file mode 100644 index 0000000..b2df16a --- /dev/null +++ b/LabirintoTest/src/MazeSolver.java @@ -0,0 +1,127 @@ +import java.util.*; + +public class MazeSolver { + private static final int ROWS = 15; + private static final int COLS = 25; + private static final char WALL = '█'; + private static final char PATH = ' '; + private static final char START = 'S'; + private static final char END = 'E'; + private static final char SOLUTION = '·'; + private char[][] maze; + private boolean[][] visited; + private int startRow, startCol, endRow, endCol; + public MazeSolver() { + maze = new char[ROWS][COLS]; + visited = new boolean[ROWS][COLS]; + generateMaze(); + } + private void generateMaze() { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + maze[i][j] = WALL; + } + } + Random rand = new Random(); + Stack stack = new Stack<>(); + startRow = 1; + startCol = 1; + maze[startRow][startCol] = PATH; + stack.push(new int[]{startRow, startCol}); + int[][] directions = {{-2, 0}, {2, 0}, {0, -2}, {0, 2}}; + while (!stack.isEmpty()) { + int[] current = stack.peek(); + int row = current[0]; + int col = current[1]; + List neighbors = new ArrayList<>(); + for (int[] dir : directions) { + int newRow = row + dir[0]; + int newCol = col + dir[1]; + + if (newRow > 0 && newRow < ROWS - 1 && + newCol > 0 && newCol < COLS - 1 && + maze[newRow][newCol] == WALL) { + neighbors.add(new int[]{newRow, newCol, row + dir[0]/2, col + dir[1]/2}); + } + } + if (!neighbors.isEmpty()) { + int[] next = neighbors.get(rand.nextInt(neighbors.size())); + maze[next[2]][next[3]] = PATH; // Rompi il muro + maze[next[0]][next[1]] = PATH; + stack.push(new int[]{next[0], next[1]}); + } else { + stack.pop(); + } + } + endRow = ROWS - 2; + endCol = COLS - 2; + maze[startRow][startCol] = START; + maze[endRow][endCol] = END; + } + + private void printMaze() { + System.out.println("\n╔" + "═".repeat(COLS) + "╗"); + for (int i = 0; i < ROWS; i++) { + System.out.print("║"); + for (int j = 0; j < COLS; j++) { + System.out.print(maze[i][j]); + } + System.out.println("║"); + } + System.out.println("╚" + "═".repeat(COLS) + "╝"); + } + + private boolean solveMaze(int row, int col, List path) { + if (row < 0 || row >= ROWS || col < 0 || col >= COLS) { + return false; + } + + if (maze[row][col] == WALL || visited[row][col]) { + return false; + } + visited[row][col] = true; + path.add(new int[]{row, col}); + if (row == endRow && col == endCol) { + return true; + } + if (solveMaze(row - 1, col, path) || + solveMaze(row + 1, col, path) || + solveMaze(row, col - 1, path) || + solveMaze(row, col + 1, path)) { + return true; + } + path.remove(path.size() - 1); + return false; + } + private void markSolution(List path) { + for (int[] pos : path) { + int row = pos[0]; + int col = pos[1]; + if (maze[row][col] != START && maze[row][col] != END) { + maze[row][col] = SOLUTION; + } + } + } + public void solve() { + System.out.println("LABIRINTO ORIGINALE:"); + printMaze(); + List path = new ArrayList<>(); + visited = new boolean[ROWS][COLS]; + System.out.println("\nRisoluzione in corso..."); + if (solveMaze(startRow, startCol, path)) { + markSolution(path); + System.out.println("\nLABIRINTO RISOLTO:"); + printMaze(); + System.out.println("\nPercorso trovato! Lunghezza: " + path.size() + " passi"); + } else { + System.out.println("\nNessuna soluzione trovata!"); + } + } + public static void main(String[] args) { + System.out.println("=== GENERATORE E RISOLUTORE DI LABIRINTI ==="); + System.out.println("Legenda: " + START + " = Inizio, " + END + " = Fine, " + + SOLUTION + " = Soluzione"); + MazeSolver solver = new MazeSolver(); + solver.solve(); + } +} \ No newline at end of file