Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

Archivo del blog

lunes, 8 de julio de 2024

Juegos IV.2. Tres en Raya (GUI).

Esta versión del código crea una interfaz gráfica para el juego de tres en raya con las siguientes características:

1- Usa una imagen para representar el tablero.
2- Los jugadores hacen clic directamente en las casillas para realizar sus jugadas.
3- Las X's y O's se dibujan en el tablero con diferentes colores.
4- Detecta automáticamente cuando hay un ganador o un empate.
5- Muestra mensajes de victoria o empate y reinicia el juego.


Código Java (TresEnRayaGUI.java):

package tresenrayagui;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class TresEnRayaGUI extends JFrame {

    private static final int CELL_SIZE = 100;
    private static final int BOARD_SIZE = 3;
    private static final int WINDOW_WIDTH = CELL_SIZE * BOARD_SIZE + 40;
    private static final int WINDOW_HEIGHT = CELL_SIZE * BOARD_SIZE + 160;

    private final char[][] tablero = new char[BOARD_SIZE][BOARD_SIZE];
    private char jugadorActual = 'X';
    private final JPanel boardPanel;
    private final JLabel turnoLabel;
    private final JLabel puntajeLabel;
    private int puntosX = 0, puntosO = 0;

    public TresEnRayaGUI() {
        setTitle("Tres en Raya");
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);

        // Panel de información mejorado
        JPanel infoPanel = new JPanel(new GridLayout(2, 1, 0, 5));
        infoPanel.setBackground(new Color(230, 230, 250));
        infoPanel.setBorder(new CompoundBorder(
                new LineBorder(new Color(100, 100, 100), 2),
                new EmptyBorder(10, 10, 10, 10)
        ));

        Font mathFont = new Font("Cambria Math", Font.BOLD, 18);
        if (mathFont.getFamily().equals("Dialog")) {
            mathFont = new Font("Arial", Font.BOLD, 18);
        }

        turnoLabel = new JLabel("Turno del jugador: X", SwingConstants.CENTER);
        turnoLabel.setFont(mathFont);
        puntajeLabel = new JLabel("X: 0 | O: 0", SwingConstants.CENTER);
        puntajeLabel.setFont(mathFont);

        infoPanel.add(turnoLabel);
        infoPanel.add(puntajeLabel);
        add(infoPanel, BorderLayout.NORTH);

        inicializarTablero();

        boardPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                dibujarTablero(g);
            }
        };
        boardPanel.setPreferredSize(new Dimension(CELL_SIZE * BOARD_SIZE, CELL_SIZE * BOARD_SIZE));
        boardPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int col = e.getX() / CELL_SIZE;
                int row = e.getY() / CELL_SIZE;
                realizarJugada(row, col);
            }
        });

        JPanel centerPanel = new JPanel(new GridBagLayout());
        centerPanel.setBackground(new Color(230, 230, 250));
        centerPanel.add(boardPanel);

        add(centerPanel, BorderLayout.CENTER);
    }

    private void inicializarTablero() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                tablero[i][j] = ' ';
            }
        }
    }

    private void dibujarTablero(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Dibujar fondo degradado
        GradientPaint gp = new GradientPaint(0, 0, new Color(200, 220, 240), CELL_SIZE * BOARD_SIZE, CELL_SIZE * BOARD_SIZE, new Color(220, 240, 255));
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, CELL_SIZE * BOARD_SIZE, CELL_SIZE * BOARD_SIZE);

        // Dibujar líneas del tablero
        g2d.setColor(new Color(100, 100, 100));
        g2d.setStroke(new BasicStroke(2));
        for (int i = 1; i < BOARD_SIZE; i++) {
            g2d.drawLine(i * CELL_SIZE, 0, i * CELL_SIZE, BOARD_SIZE * CELL_SIZE);
            g2d.drawLine(0, i * CELL_SIZE, BOARD_SIZE * CELL_SIZE, i * CELL_SIZE);
        }

        // Dibujar X y O
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (tablero[i][j] == 'X') {
                    dibujarX(g2d, j * CELL_SIZE, i * CELL_SIZE);
                } else if (tablero[i][j] == 'O') {
                    dibujarO(g2d, j * CELL_SIZE, i * CELL_SIZE);
                }
            }
        }
    }

    private void dibujarX(Graphics2D g2d, int x, int y) {
        g2d.setColor(new Color(220, 20, 60));
        g2d.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2d.draw(new Line2D.Double(x + 20, y + 20, x + CELL_SIZE - 20, y + CELL_SIZE - 20));
        g2d.draw(new Line2D.Double(x + CELL_SIZE - 20, y + 20, x + 20, y + CELL_SIZE - 20));
    }

    private void dibujarO(Graphics2D g2d, int x, int y) {
        g2d.setColor(new Color(30, 144, 255));
        g2d.setStroke(new BasicStroke(4));
        g2d.draw(new Ellipse2D.Double(x + 20, y + 20, CELL_SIZE - 40, CELL_SIZE - 40));
    }

    private void realizarJugada(int row, int col) {
        if (tablero[row][col] == ' ') {
            tablero[row][col] = jugadorActual;
            boardPanel.repaint();
            if (verificarGanador(row, col)) {
                if (jugadorActual == 'X') {
                    puntosX++;
                } else {
                    puntosO++;
                }
                JOptionPane.showMessageDialog(this, "¡El jugador " + jugadorActual + " ha ganado!");
                reiniciarJuego();
            } else if (tableroLleno()) {
                JOptionPane.showMessageDialog(this, "¡Empate!");
                reiniciarJuego();
            } else {
                jugadorActual = (jugadorActual == 'X') ? 'O' : 'X';
                actualizarInfoLabel();
            }
        }
    }

    private boolean verificarGanador(int row, int col) {
        return (tablero[row][0] == jugadorActual && tablero[row][1] == jugadorActual && tablero[row][2] == jugadorActual)
                || (tablero[0][col] == jugadorActual && tablero[1][col] == jugadorActual && tablero[2][col] == jugadorActual)
                || (row == col && tablero[0][0] == jugadorActual && tablero[1][1] == jugadorActual && tablero[2][2] == jugadorActual)
                || (row + col == 2 && tablero[0][2] == jugadorActual && tablero[1][1] == jugadorActual && tablero[2][0] == jugadorActual);
    }

    private boolean tableroLleno() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (tablero[i][j] == ' ') {
                    return false;
                }
            }
        }
        return true;
    }

    private void reiniciarJuego() {
        inicializarTablero();
        jugadorActual = 'X';
        actualizarInfoLabel();
        boardPanel.repaint();
    }

    private void actualizarInfoLabel() {
        turnoLabel.setText("Turno del jugador: " + jugadorActual);
        puntajeLabel.setText("X: " + puntosX + " | O: " + puntosO);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new TresEnRayaGUI().setVisible(true));
    }
}


Resultado:



Con la tecnología de Blogger.