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, 22 de julio de 2024

Juegos V.2: Approximate(GUI): El Juego de Números y Operaciones.

Este algoritmo proporciona una interfaz clara y funcional para la aplicación 'Approximate', permitiendo al usuario ingresar o generar números, realizar cálculos y ver los resultados de manera intuitiva mediante interfaz de usuario (GUI).

Desde NetBeans y en modo "Design" creamos la interfaz de usuario (GUI) siguiendo la siguiente nomenclatura:


Estructura GUI:

MainApproximate

└─── jPanel_Main
    │
    ├─── jPanel_Botonera
    │    ├─── jButtonRandom
    │    ├─── jButtonLimpiar
    │    └─── jButtonCalcular
    │
    ├─── jPanel_NumeroObjetivo
    │    └─── jTextField_NumObjetivo
    │
    ├─── jPanel_NumerosDisponibles
    │    ├─── jTextField1
    │    ├─── jTextField2
    │    ├─── jTextField3
    │    ├─── jTextField4
    │    ├─── jTextField5
    │    └─── jTextField6
    │
    ├─── jSeparator1
    │
    ├─── jPanel_MejorAproximacion
    │    └─── jTextField_MejorAproximacion
    │
    └─── jPanel_Expresion
         └─── jTextField_Expresion




Código Java (MainApproximate.java):

package approximategui;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.swing.JOptionPane;

public class MainApproximate extends javax.swing.JFrame {

    private static final char[] OPERADORES = {'+', '-', '*', '/'};
    private static int mejorResultado;
    private static String mejorExpresion;
    private static final int OBJETIVO_NO_ALCANZADO = Integer.MAX_VALUE;
    private final Random random = new Random();

    public MainApproximate() {
        initComponents();
        setLocationRelativeTo(null);
        limpiarDatos();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
                         
    private void initComponents() { ... } // Código generado por Netbeans desde modo "Design"                      

    private void jButtonCalcularActionPerformed(java.awt.event.ActionEvent evt) {                                                
        calcularMejorAproximacion();
    }                                               

    private void jButtonRandomActionPerformed(java.awt.event.ActionEvent evt) {                                              
        generarNumerosAleatorios();
        // Limpiar los resultados
        jTextField_MejorAproximacion.setText("");
        jTextField_Expresion.setText("");
    }                                             

    private void jButtonLimpìarActionPerformed(java.awt.event.ActionEvent evt) {                                               
        limpiarDatos();
    }                                              

    private void limpiarDatos() {
        // Limpiar el número objetivo
        jTextField_NumObjetivo.setText("");

        // Limpiar los números disponibles
        jTextField1.setText("");
        jTextField2.setText("");
        jTextField3.setText("");
        jTextField4.setText("");
        jTextField5.setText("");
        jTextField6.setText("");

        // Limpiar los resultados
        jTextField_MejorAproximacion.setText("");
        jTextField_Expresion.setText("");

        // Resetear las variables globales si es necesario
        mejorResultado = OBJETIVO_NO_ALCANZADO;
        mejorExpresion = "";
    }

    private void generarNumerosAleatorios() {
        int objetivo = random.nextInt(999) + 1;
        jTextField_NumObjetivo.setText(String.valueOf(objetivo));

        Set<Integer> numerosSet = new HashSet<>();
        while (numerosSet.size() < 6) {
            int nuevoNumero = random.nextInt(100) + 1;
            if (nuevoNumero != objetivo) {
                numerosSet.add(nuevoNumero);
            }
        }

        Integer[] numeros = numerosSet.toArray(new Integer[0]);
        jTextField1.setText(String.valueOf(numeros[0]));
        jTextField2.setText(String.valueOf(numeros[1]));
        jTextField3.setText(String.valueOf(numeros[2]));
        jTextField4.setText(String.valueOf(numeros[3]));
        jTextField5.setText(String.valueOf(numeros[4]));
        jTextField6.setText(String.valueOf(numeros[5]));
    }

    private void calcularMejorAproximacion() {
        try {
            int objetivo = Integer.parseInt(jTextField_NumObjetivo.getText());
            Integer[] numeros = new Integer[6];
            numeros[0] = Integer.parseInt(jTextField1.getText());
            numeros[1] = Integer.parseInt(jTextField2.getText());
            numeros[2] = Integer.parseInt(jTextField3.getText());
            numeros[3] = Integer.parseInt(jTextField4.getText());
            numeros[4] = Integer.parseInt(jTextField5.getText());
            numeros[5] = Integer.parseInt(jTextField6.getText());

            mejorResultado = OBJETIVO_NO_ALCANZADO;
            mejorExpresion = "";

            generarCombinaciones(numeros, objetivo);

            if (mejorResultado != OBJETIVO_NO_ALCANZADO) {
                jTextField_MejorAproximacion.setText(String.valueOf(mejorResultado));
                jTextField_Expresion.setText(mejorExpresion);
            } else {
                jTextField_MejorAproximacion.setText("No encontrado");
                jTextField_Expresion.setText("N/A");
            }
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "Por favor, ingrese números válidos en todos los campos.", "Error de entrada", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void generarCombinaciones(Integer[] numeros, int objetivo) {
        for (int i = 1; i <= numeros.length; i++) {
            generarPermutaciones(Arrays.asList(numeros), new ArrayList<>(), i, objetivo);
        }
    }

    private void generarPermutaciones(List<Integer> numeros, List<Integer> permutacion, int longitud, int objetivo) {
        if (permutacion.size() == longitud) {
            generarOperaciones(permutacion, new ArrayList<>(), objetivo);
            return;
        }

        for (int i = 0; i < numeros.size(); i++) {
            List<Integer> nuevaPermutacion = new ArrayList<>(permutacion);
            nuevaPermutacion.add(numeros.get(i));

            List<Integer> nuevosNumeros = new ArrayList<>(numeros);
            nuevosNumeros.remove(i);

            generarPermutaciones(nuevosNumeros, nuevaPermutacion, longitud, objetivo);
        }
    }

    private void generarOperaciones(List<Integer> numeros, List<Character> operadores, int objetivo) {
        if (operadores.size() == numeros.size() - 1) {
            evaluarExpresion(numeros, operadores, objetivo);
            return;
        }

        for (char operador : OPERADORES) {
            List<Character> nuevosOperadores = new ArrayList<>(operadores);
            nuevosOperadores.add(operador);
            generarOperaciones(numeros, nuevosOperadores, objetivo);
        }
    }

    private void evaluarExpresion(List<Integer> numeros, List<Character> operadores, int objetivo) {
        String expresion = construirExpresion(numeros, operadores);

        try {
            int resultado = evaluarExpresionAritmetica(expresion);
            int diferencia = Math.abs(resultado - objetivo);

            if (diferencia < Math.abs(mejorResultado - objetivo)) {
                mejorResultado = resultado;
                mejorExpresion = expresion;
            }
        } catch (ArithmeticException e) {
            // Ignorar divisiones inválidas
        }
    }

    private String construirExpresion(List<Integer> numeros, List<Character> operadores) {
        StringBuilder expresion = new StringBuilder();
        expresion.append(numeros.get(0));

        for (int i = 0; i < operadores.size(); i++) {
            expresion.append(operadores.get(i));
            expresion.append(numeros.get(i + 1));
        }

        return expresion.toString();
    }

    private int evaluarExpresionAritmetica(String expresion) {
        List<String> tokens = tokenizarExpresion(expresion);
        return evaluarTokens(tokens);
    }

    private List<String> tokenizarExpresion(String expresion) {
        List<String> tokens = new ArrayList<>();
        StringBuilder numeroActual = new StringBuilder();

        for (char c : expresion.toCharArray()) {
            if (Character.isDigit(c)) {
                numeroActual.append(c);
            } else {
                if (numeroActual.length() > 0) {
                    tokens.add(numeroActual.toString());
                    numeroActual = new StringBuilder();
                }
                tokens.add(String.valueOf(c));
            }
        }

        if (numeroActual.length() > 0) {
            tokens.add(numeroActual.toString());
        }

        return tokens;
    }

    private int evaluarTokens(List<String> tokens) {
        // Primero, evaluamos multiplicaciones y divisiones
        for (int i = 1; i < tokens.size() - 1; i += 2) {
            String operador = tokens.get(i);
            if (operador.equals("*") || operador.equals("/")) {
                int a = Integer.parseInt(tokens.get(i - 1));
                int b = Integer.parseInt(tokens.get(i + 1));
                int resultado;
                if (operador.equals("*")) {
                    resultado = a * b;
                } else {
                    if (b == 0 || a % b != 0) {
                        throw new ArithmeticException("División inválida");
                    }
                    resultado = a / b;
                }
                tokens.set(i - 1, String.valueOf(resultado));
                tokens.remove(i);
                tokens.remove(i);
                i -= 2;
            }
        }

        // Luego, evaluamos sumas y restas
        int resultado = Integer.parseInt(tokens.get(0));
        for (int i = 1; i < tokens.size(); i += 2) {
            String operador = tokens.get(i);
            int numero = Integer.parseInt(tokens.get(i + 1));
            if (operador.equals("+")) {
                resultado += numero;
            } else if (operador.equals("-")) {
                resultado -= numero;
            }
        }

        return resultado;
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(() -> {
            new MainApproximate().setVisible(true);
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButtonCalcular;
    private javax.swing.JButton jButtonLimpìar;
    private javax.swing.JButton jButtonRandom;
    private javax.swing.JPanel jPanel_Botonera;
    private javax.swing.JPanel jPanel_Expresion;
    private javax.swing.JPanel jPanel_Main;
    private javax.swing.JPanel jPanel_MejorAproximacion;
    private javax.swing.JPanel jPanel_NumeroObjetivo;
    private javax.swing.JPanel jPanel_NumerosDisponibles;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JTextField jTextField4;
    private javax.swing.JTextField jTextField5;
    private javax.swing.JTextField jTextField6;
    private javax.swing.JTextField jTextField_Expresion;
    private javax.swing.JTextField jTextField_MejorAproximacion;
    private javax.swing.JTextField jTextField_NumObjetivo;
    // End of variables declaration                   
}


Resultado:


Con la tecnología de Blogger.