Compare commits
5 Commits
16f1d7af9e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 33bc3d76c6 | |||
| 89421ac1c4 | |||
| 241fe7271f | |||
| c6a896f0e2 | |||
| 80c5ea412e |
123
Alberi1/src/Main.java
Normal file
123
Alberi1/src/Main.java
Normal file
@@ -0,0 +1,123 @@
|
||||
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;i<livello-1;i++)
|
||||
System.out.print("\t");
|
||||
if(livello!=0) System.out.print("+------->");
|
||||
System.out.println(n.dato+lr);
|
||||
stampa(n.left, livello+1,"L");
|
||||
stampa(n.right, livello+1,"R");
|
||||
}
|
||||
/*
|
||||
0) fissate l'intestazione della funzione e
|
||||
pensate che esista già e che funzioni
|
||||
1) caso base, trovare un caso in cui la risposta
|
||||
è ovvia e non serve computazione
|
||||
2) cosa fare col dato attuale e cosa fare con i rimanenti
|
||||
|
||||
*/
|
||||
static int somma(Nodo albero) {
|
||||
if(albero==null) return 0;
|
||||
return albero.dato+somma(albero.left)+somma(albero.right);
|
||||
}
|
||||
static int conta(Nodo albero) {//conta quanti sono i nodi
|
||||
if(albero==null) return 0;
|
||||
return 1+conta(albero.left)+conta(albero.right);
|
||||
}
|
||||
static int contaFoglie(Nodo albero) {//conta quanti sono le foglie (nodi senza figli)
|
||||
if(albero==null) return 0;
|
||||
if (albero.left == null && albero.right == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return contaFoglie(albero.left) + contaFoglie(albero.right);
|
||||
}
|
||||
}
|
||||
static Nodo insOrd(int val, Nodo albero) { //Inserimento ordinato
|
||||
if(albero==null) return new Nodo(val, null, null);
|
||||
if(val>albero.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) { //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){ //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){ //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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Nodo n1 = new Nodo(10, null, null);
|
||||
Nodo n2 = new Nodo(5, null, null);
|
||||
Nodo n3 = new Nodo(30, null, null);
|
||||
|
||||
n1.left = n2;
|
||||
n1.right = n3;
|
||||
|
||||
// Nodo.stampa(n1,0);
|
||||
|
||||
Nodo n4 = Nodo.insOrd(23, n1);
|
||||
n4 = Nodo.insOrd(1, n4);
|
||||
Nodo.stampa(n4,0,"");
|
||||
System.out.println("Nodi: " + Nodo.conta(n4));
|
||||
System.out.println("Foglie: " + Nodo.contaFoglie(n4));
|
||||
System.out.println("Somma: " + Nodo.somma(n4));
|
||||
System.out.println("Trovato 24? " + Nodo.trova(n4,24));
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
class Nodo{
|
||||
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;i<livello-1;i++)
|
||||
System.out.print("\t");
|
||||
if(livello!=0) System.out.print("+------->");
|
||||
System.out.println(n.dato+lr);
|
||||
stampa(n.left, livello+1,"L");
|
||||
stampa(n.right, livello+1,"R");
|
||||
}
|
||||
|
||||
/*
|
||||
0) fissate l'intestazione della funzione e
|
||||
pensate che esista già e che funzioni
|
||||
1) caso base, trovare un caso in cui la risposta
|
||||
è ovvia e non serve computazione
|
||||
2) cosa fare col dato attuale e cosa fare con i rimanenti
|
||||
|
||||
*/
|
||||
|
||||
static int somma(Nodo albero) {
|
||||
if(albero==null) return 0;
|
||||
return albero.dato+somma(albero.left)+somma(albero.right);
|
||||
}
|
||||
|
||||
static int conta(Nodo albero) {//conta quanti sono i nodi
|
||||
if(albero==null) return 0;
|
||||
return 1+conta(albero.left)+conta(albero.right);
|
||||
}
|
||||
|
||||
static int contaFoglie(Nodo albero) {//conta quanti sono le foglie (nodi senza figli)
|
||||
if(albero==null) return 0;
|
||||
if (albero.left == null && albero.right == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return contaFoglie(albero.left) + contaFoglie(albero.right);
|
||||
}
|
||||
}
|
||||
|
||||
static Nodo insOrd(int val, Nodo albero) {
|
||||
if(albero==null) return new Nodo(val, null, null);
|
||||
if(val>albero.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) {
|
||||
if(albero==null) return false;
|
||||
else if(albero.dato==valore) return true;
|
||||
else return trova(albero.left, valore) || trova(albero.right, valore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class NodoMain {
|
||||
public static void main(String[] args) {
|
||||
Nodo n1 = new Nodo(10, null, null);
|
||||
Nodo n2 = new Nodo(5, null, null);
|
||||
Nodo n3 = new Nodo(30, null, null);
|
||||
|
||||
n1.left = n2;
|
||||
n1.right = n3;
|
||||
|
||||
// Nodo.stampa(n1,0);
|
||||
|
||||
Nodo n4 = Nodo.insOrd(23, n1);
|
||||
n4 = Nodo.insOrd(1, n4);
|
||||
Nodo.stampa(n4,0,"");
|
||||
System.out.println("Nodi: " + Nodo.conta(n4));
|
||||
System.out.println("Foglie: " + Nodo.contaFoglie(n4));
|
||||
System.out.println("Somma: " + Nodo.somma(n4));
|
||||
System.out.println("Trovato 24? " + Nodo.trova(n4,24));
|
||||
}
|
||||
|
||||
}
|
||||
30
LabirintoGUI/.gitignore
vendored
Normal file
30
LabirintoGUI/.gitignore
vendored
Normal file
@@ -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
|
||||
8
LabirintoGUI/.idea/.gitignore
generated
vendored
Normal file
8
LabirintoGUI/.idea/.gitignore
generated
vendored
Normal file
@@ -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
|
||||
6
LabirintoGUI/.idea/misc.xml
generated
Normal file
6
LabirintoGUI/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
LabirintoGUI/.idea/modules.xml
generated
Normal file
8
LabirintoGUI/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/LabirintoGUI.iml" filepath="$PROJECT_DIR$/LabirintoGUI.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
LabirintoGUI/.idea/vcs.xml
generated
Normal file
6
LabirintoGUI/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
LabirintoGUI/LabirintoGUI.iml
Normal file
11
LabirintoGUI/LabirintoGUI.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
276
LabirintoGUI/src/MazeGame.java
Normal file
276
LabirintoGUI/src/MazeGame.java
Normal file
@@ -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<int[]> 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<int[]> 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);
|
||||
}
|
||||
}
|
||||
30
LabirintoTest/.gitignore
vendored
Normal file
30
LabirintoTest/.gitignore
vendored
Normal file
@@ -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
|
||||
8
LabirintoTest/.idea/.gitignore
generated
vendored
Normal file
8
LabirintoTest/.idea/.gitignore
generated
vendored
Normal file
@@ -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
|
||||
6
LabirintoTest/.idea/misc.xml
generated
Normal file
6
LabirintoTest/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
LabirintoTest/.idea/modules.xml
generated
Normal file
8
LabirintoTest/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/LabirintoTest.iml" filepath="$PROJECT_DIR$/LabirintoTest.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
LabirintoTest/.idea/vcs.xml
generated
Normal file
6
LabirintoTest/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
LabirintoTest/LabirintoTest.iml
Normal file
11
LabirintoTest/LabirintoTest.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
127
LabirintoTest/src/MazeSolver.java
Normal file
127
LabirintoTest/src/MazeSolver.java
Normal file
@@ -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<int[]> 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<int[]> 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<int[]> 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<int[]> 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<int[]> 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();
|
||||
}
|
||||
}
|
||||
30
TrisMiniMax/.gitignore
vendored
Normal file
30
TrisMiniMax/.gitignore
vendored
Normal file
@@ -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
|
||||
8
TrisMiniMax/.idea/.gitignore
generated
vendored
Normal file
8
TrisMiniMax/.idea/.gitignore
generated
vendored
Normal file
@@ -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
|
||||
6
TrisMiniMax/.idea/misc.xml
generated
Normal file
6
TrisMiniMax/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
TrisMiniMax/.idea/modules.xml
generated
Normal file
8
TrisMiniMax/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/TrisMiniMax.iml" filepath="$PROJECT_DIR$/TrisMiniMax.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
TrisMiniMax/.idea/vcs.xml
generated
Normal file
6
TrisMiniMax/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
TrisMiniMax/TrisMiniMax.iml
Normal file
11
TrisMiniMax/TrisMiniMax.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
221
TrisMiniMax/src/TrisGame.java
Normal file
221
TrisMiniMax/src/TrisGame.java
Normal file
@@ -0,0 +1,221 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class TrisGame extends JFrame {
|
||||
private final JButton[][] buttons = new JButton[3][3];
|
||||
private final char[][] board = new char[3][3];
|
||||
private final char humanPlayer = 'X';
|
||||
private final char aiPlayer = 'O';
|
||||
private final JLabel statusLabel;
|
||||
private boolean gameOver = false;
|
||||
|
||||
public TrisGame() {
|
||||
setTitle("Tris - Minimax AI");
|
||||
setSize(400, 450);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
// Pannello di gioco
|
||||
JPanel gamePanel = new JPanel(new GridLayout(3, 3, 5, 5));
|
||||
gamePanel.setBackground(Color.BLACK);
|
||||
|
||||
// Inizializza la board e i bottoni
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
board[i][j] = ' ';
|
||||
buttons[i][j] = new JButton("");
|
||||
buttons[i][j].setFont(new Font("Arial", Font.BOLD, 60));
|
||||
buttons[i][j].setFocusPainted(false);
|
||||
buttons[i][j].setBackground(Color.WHITE);
|
||||
|
||||
final int row = i;
|
||||
final int col = j;
|
||||
|
||||
buttons[i][j].addActionListener(e -> playerMove(row, col));
|
||||
gamePanel.add(buttons[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Pannello di stato
|
||||
JPanel statusPanel = new JPanel();
|
||||
statusLabel = new JLabel("Il tuo turno! (X)");
|
||||
statusLabel.setFont(new Font("Arial", Font.BOLD, 16));
|
||||
statusPanel.add(statusLabel);
|
||||
|
||||
// Bottone reset
|
||||
JButton resetButton = new JButton("Nuova Partita");
|
||||
resetButton.addActionListener(e -> resetGame());
|
||||
statusPanel.add(resetButton);
|
||||
|
||||
add(gamePanel, BorderLayout.CENTER);
|
||||
add(statusPanel, BorderLayout.SOUTH);
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void playerMove(int row, int col) {
|
||||
if (gameOver || board[row][col] != ' ') return;
|
||||
|
||||
// Mossa del giocatore
|
||||
board[row][col] = humanPlayer;
|
||||
buttons[row][col].setText("X");
|
||||
buttons[row][col].setForeground(Color.BLUE);
|
||||
|
||||
if (checkWinner(humanPlayer)) {
|
||||
statusLabel.setText("Hai vinto! 🎉");
|
||||
gameOver = true;
|
||||
highlightWinner(humanPlayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBoardFull()) {
|
||||
statusLabel.setText("Pareggio!");
|
||||
gameOver = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Mossa dell'AI
|
||||
statusLabel.setText("L'AI sta pensando...");
|
||||
Timer timer = new Timer(500, e -> {
|
||||
aiMove();
|
||||
|
||||
if (checkWinner(aiPlayer)) {
|
||||
statusLabel.setText("L'AI ha vinto!");
|
||||
gameOver = true;
|
||||
highlightWinner(aiPlayer);
|
||||
} else if (isBoardFull()) {
|
||||
statusLabel.setText("Pareggio!");
|
||||
gameOver = true;
|
||||
} else {
|
||||
statusLabel.setText("Il tuo turno! (X)");
|
||||
}
|
||||
});
|
||||
timer.setRepeats(false);
|
||||
timer.start();
|
||||
}
|
||||
|
||||
private void aiMove() {
|
||||
int[] bestMove = findBestMove();
|
||||
board[bestMove[0]][bestMove[1]] = aiPlayer;
|
||||
buttons[bestMove[0]][bestMove[1]].setText("O");
|
||||
buttons[bestMove[0]][bestMove[1]].setForeground(Color.RED);
|
||||
}
|
||||
|
||||
private int[] findBestMove() {
|
||||
int bestScore = Integer.MIN_VALUE;
|
||||
int[] bestMove = new int[2];
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (board[i][j] == ' ') {
|
||||
board[i][j] = aiPlayer;
|
||||
int score = minimax(0, false);
|
||||
board[i][j] = ' ';
|
||||
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
bestMove[0] = i;
|
||||
bestMove[1] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestMove;
|
||||
}
|
||||
|
||||
private int minimax(int depth, boolean isMaximizing) {
|
||||
if (checkWinner(aiPlayer)) return 10 - depth;
|
||||
if (checkWinner(humanPlayer)) return depth - 10;
|
||||
if (isBoardFull()) return 0;
|
||||
|
||||
int bestScore;
|
||||
if (isMaximizing) {
|
||||
bestScore = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (board[i][j] == ' ') {
|
||||
board[i][j] = aiPlayer;
|
||||
int score = minimax(depth + 1, false);
|
||||
board[i][j] = ' ';
|
||||
bestScore = Math.max(score, bestScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bestScore = Integer.MAX_VALUE;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (board[i][j] == ' ') {
|
||||
board[i][j] = humanPlayer;
|
||||
int score = minimax(depth + 1, true);
|
||||
board[i][j] = ' ';
|
||||
bestScore = Math.min(score, bestScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestScore;
|
||||
}
|
||||
|
||||
private boolean checkWinner(char player) {
|
||||
// Righe e colonne
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (board[i][0] == player && board[i][1] == player && board[i][2] == player) return true;
|
||||
if (board[0][i] == player && board[1][i] == player && board[2][i] == player) return true;
|
||||
}
|
||||
// Diagonali
|
||||
if (board[0][0] == player && board[1][1] == player && board[2][2] == player) return true;
|
||||
return board[0][2] == player && board[1][1] == player && board[2][0] == player;
|
||||
}
|
||||
|
||||
private void highlightWinner(char player) {
|
||||
Color winColor = new Color(144, 238, 144);
|
||||
|
||||
// Righe
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (board[i][0] == player && board[i][1] == player && board[i][2] == player) {
|
||||
for (int j = 0; j < 3; j++) buttons[i][j].setBackground(winColor);
|
||||
}
|
||||
}
|
||||
// Colonne
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (board[0][i] == player && board[1][i] == player && board[2][i] == player) {
|
||||
for (int j = 0; j < 3; j++) buttons[j][i].setBackground(winColor);
|
||||
}
|
||||
}
|
||||
// Diagonali
|
||||
if (board[0][0] == player && board[1][1] == player && board[2][2] == player) {
|
||||
for (int i = 0; i < 3; i++) buttons[i][i].setBackground(winColor);
|
||||
}
|
||||
if (board[0][2] == player && board[1][1] == player && board[2][0] == player) {
|
||||
for (int i = 0; i < 3; i++) buttons[i][2-i].setBackground(winColor);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBoardFull() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (board[i][j] == ' ') return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void resetGame() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
board[i][j] = ' ';
|
||||
buttons[i][j].setText("");
|
||||
buttons[i][j].setBackground(Color.WHITE);
|
||||
}
|
||||
}
|
||||
gameOver = false;
|
||||
statusLabel.setText("Il tuo turno! (X)");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(TrisGame::new);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user