Tris MiniMax

This commit is contained in:
2025-12-04 09:36:41 +01:00
parent 89421ac1c4
commit 33bc3d76c6
7 changed files with 290 additions and 0 deletions

View 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);
}
}