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

domingo, 25 de septiembre de 2022

Almacenar información alfanumérica en matriz gráfica. Tipo código Qr.

Código 1 (CodigoQR.java):

package codigoqr;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import javax.imageio.ImageIO;

public class CodigoQR {

    public static void main(String[] args) {

        //QR Bin
        String xyn = " abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789!#$%&'()*+,-./:;<=>?@[]^_`{|}~";
        List<String> miLista = new ArrayList<>(Arrays.asList(xyn.split("")));
        String binaryString;
        String strCodigo;
        int pos;

        //input código de 8 caracteres        
        System.out.println("Introduce código (8 caracteres mínimo): ");
        Scanner input = new Scanner(System.in);
        strCodigo = input.nextLine();
        if (strCodigo.length() < 8) {
            strCodigo = "        " + strCodigo;
        } else if (strCodigo.length() > 8) {
            System.out.println("Sólo se registrarán los 8 primeros caracteres.");
        }

        //limitar a 8 carácteres máximo.
        strCodigo = strCodigo.substring(0, 8);
        System.out.println("Código registrado <" + strCodigo + ">");

        //generar código QR *** se puede eliminar Lista y Arrays?
        Boolean map[][] = new Boolean[8][8];
        for (int i = 0; i < map.length; i++) {
            pos = miLista.indexOf("" + strCodigo.charAt(i));

            //pasar a formato "binario"
            binaryString = "00000000" + Integer.toString(pos, 2);

            //pasar a formato 00000ABC
            binaryString = binaryString.substring(binaryString.length() - 8);

            //pasar a matriz boleana
            for (int j = 0; j < map.length; j++) {
                map[i][j] = binaryString.charAt(j) != '0';
            }
        }

        //dibujar código pre-QR (.png)
        int res_x = 256;
        int res_y = 256;
        BufferedImage imagen = new BufferedImage(res_x, res_y, BufferedImage.TYPE_INT_RGB);
        Lienzo.Dibujar((Graphics2D) imagen.getGraphics(), res_x, res_y, map);
        try {
            ImageIO.write(imagen, "png", new File("CodigoQR.png"));
        } catch (IOException e) {
        }
        
    }
}


Código 2 (Lienzo.java):

package codigoqr;

import java.awt.Color;
import java.awt.Graphics2D;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, Boolean[][] map) {

        //tamaño bloque
        int tCuadroX = x / 8;

        //fondo blanco
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, x, y);

        //dibujar bloques muro
        g.setColor(Color.black);
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                if (map[j][i]) {
                    g.fillRect(tCuadroX * i, tCuadroX * j, tCuadroX, tCuadroX);
                }
            }
        }

        //rejilla
        g.setColor(Color.blue);
        for (int i = 0; i < x; i = i + tCuadroX) {
            g.drawLine(0, i, x, i); //horizontal
            g.drawLine(i, 0, i, x); //vertical
        }

    }
    
}


Resultado:

run:
Introduce código (8 caracteres mínimo):
E*7r@yHj0yHvwRI
Sólo se registrarán los 8 primeros caracteres.
Código registrado <E*7r@yHj>
BUILD SUCCESSFUL (total time: 3 seconds)




miércoles, 14 de septiembre de 2022

Circular a plano. Algoritmo sin uso práctico conocido.

Este algoritmo no tiene ningún uso práctico, sólo sirve para fines didácticos y apredizaje.
La premisa consiste en dibujar un máximo de dos pixeles por línea horizontal, línea vertical y línea diagonal.


Código 1 (Circular_a_Plano.java):

package circular_a_plano;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Circular_a_Plano {

    public static void main(String[] args) {

        Boolean[][] map = new Boolean[32][32];

        //inicializar matrix
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                map[j][i] = false;
            }
        }

        map[0][0] = true;
        map[1][1] = true;

        boolean X_libre = true, Y_libre = true;
        boolean Dx_libre = true;
        for (int y = 0; y < map.length; y++) {
            for (int x = 0; x < map.length; x++) {
                X_libre = comprobarX(y, map);
                Y_libre = comprobarY(x, map);
                Dx_libre = comprobarDx(x, y, map);

                if (X_libre && Y_libre && Dx_libre) {
                    map[x][y] = true;
                }
            }
        }
        
        Resultados(map);

        //tamaño lienzo
        int res_x = 1024;
        int res_y = 1024;

        BufferedImage imagen = new BufferedImage(res_x, res_y, BufferedImage.TYPE_INT_RGB);
        Lienzo.Dibujar((Graphics2D) imagen.getGraphics(), res_x, res_y, map);
        try {
            ImageIO.write(imagen, "png", new File("Laberinto.png"));
        } catch (IOException e) {
        }
    }

    private static boolean comprobarX(int y, Boolean[][] map) {
        //comprobación i
        int cont = 0;
        boolean libre = true;
        for (int i = 0; i < map.length; i++) {
            if (map[i][y]) {
                cont++;
            }
            if (cont >= 2) {
                libre = false;
                break;
            }
        }
        return libre;
    }

    private static boolean comprobarY(int x, Boolean[][] map) {
        //comprobación j
        int cont = 0;
        boolean libre = true;
        for (int i = 0; i < map.length; i++) {
            if (map[x][i]) {
                cont++;
            }
            if (cont >= 2) {
                libre = false;
                break;
            }
        }
        return libre;
    }

    private static boolean comprobarDx(int x, int y, Boolean[][] map) {
        //comprobación j
        int cont = 0;
        boolean libre = true;
        int aux = 0;
        if (x <= y) {
            aux = y - x;
            for (int i = 0; i < map.length - aux; i++) {
                if (map[i][aux + i]) {
                    cont++;
                }
            }
            if (cont >= 2) {
                libre = false; //¿funciona?
            }
        }
        if (x >= y) {
            aux = x - y;
            for (int i = 0; i < map.length - aux; i++) {
                if (map[aux + i][i]) {
                    cont++;
                }
            }
            if (cont >= 2) {
                libre = false; //¿funciona?
            }
        }
        return libre;
    }

    private static boolean comprobarDy(int x, int y, Boolean[][] map) {
        int cont = 0;
        int aux = 0;
        boolean libre = true;
        if (x < y) { //if x<y parcial resolve...
            for (int i = x - aux; i < map.length; i++) {
                if (map[i][(y + aux - cont)] || map[y - cont][i]) {
                    cont++;
                }
                if (cont >= 2) {
                    libre = false;
                    break;
                }
            }
        }
        return libre;
    }

    private static void Resultados(Boolean[][] map) {
        System.out.println("Resultado:\n");
        String libre = "";
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                if (map[j][i]) {
                    libre = libre + "█";
                } else {
                    libre = libre + "·";
                }
            }
            libre = libre + ("\n");
        }
        System.out.println(libre);
    }

}


Código 2 (Lienzo.java):

package circular_a_plano;

import java.awt.Color;
import java.awt.Graphics2D;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, Boolean[][] map) {

        //tamaño bloque
        int tCuadroX = x / map.length;

        //fondo blanco
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, x, y);

        //rejilla
        g.setColor(Color.blue);
        for (int i = 0; i < x; i = i + tCuadroX) {
            g.drawLine(0, i, x, i); //horizontal
            g.drawLine(i, 0, i, x); //vertical
        }

        //dibujar bloques muro
        g.setColor(Color.black);
        for (int j = 0; j < map.length; j++) {
            for (int i = 0; i < map.length; i++) {
                if (map[i][j]) {
                    g.fillRect(tCuadroX * i, tCuadroX * j, tCuadroX, tCuadroX);
                }
            }
        }
    }

}


Resultado:


Mastermind 2. Uso de expresión regular para validar entrada de datos.

Siguiendo el post anterior sobre el juego Mastermind, se mejora método de validación de entradas de datos usando expresiones regulares. También se realizan leves cambios de código.


Código (Mastermind.java):

package mastermind;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Mastermind {

    public static void main(String[] args) {

        //presentación e instrucciones juego
        System.out.println(""
                + "-------------\n"
                + " MASTER-MIND\n"
                + "-------------\n\n"
                + "Se trata de adivinar un número, si adivinas el número y el lugar correcto es un muerto, si aciertas el número pero no el lugar es un herido.\n"
                + "EJEMPLO: El número a decifrar es el <1234>\n"
                + "Si introduces el <2136>. Esto te dará:\n"
                + "1 muerto(el 3) y 2 heridos(1 y 2). El 6 al no estar no cuenta.\n\n"
        );

        //inicializar variables
        List<String> valores = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
        int i_hallar[] = new int[4];
        int i_buscar[] = new int[4];
        int muerto, herido, cont = 1;
        String hallar = "", buscar;
        Scanner input;

        //generar código aleatorio        
        Collections.shuffle(valores); //mezclar valores
        for (int i = 0; i < 4; i++) {
            hallar += valores.get(i);
            i_hallar[i] = Integer.parseInt("" + hallar.charAt(i));
        }

        //iniciar partida
        System.out.println("Escriba número de 4 cifras (ej: 1234):\n");
        do {
            muerto = 0;
            herido = 0;

            //introducir y validar
            do {
                System.out.println(cont + "º intento:");
                input = new Scanner(System.in);
                buscar = input.nextLine();
            } while (!ValidarNum(buscar));

            for (int i = 0; i < 4; i++) {
                i_buscar[i] = Integer.parseInt("" + buscar.charAt(i));
            }


            //búsqueda muertos y heridos
            for (int i = 0; i < i_hallar.length; i++) {
                for (int j = 0; j < i_buscar.length; j++) {
                    if (i_buscar[j] == i_hallar[i]) {
                        herido++;
                        if (j == i) {
                            herido--;
                            muerto++;
                        }
                    }
                }
            }
            System.out.println(muerto + " muerto/s y " + herido + " herido/s\n");
        } while (cont++ < 10 && muerto != 4);

        //resultado final
        if (muerto > 3) {
            System.out.println("\nCódigo descifrado! " + Arrays.toString(i_hallar));
            System.out.println("Has ganado!\n");
        } else {
            System.out.println("\nHas perdido!");
            System.out.println("Código era " + Arrays.toString(i_hallar) + "\n");
        }
    }

    private static boolean ValidarNum(String buscar) {
        Boolean valido;
        Pattern pat = Pattern.compile("^\\d{4}$");
        Matcher mat = pat.matcher(buscar);
        valido = mat.find();
        if (!valido) {
            System.out.println("\nCódigo <" + buscar + "> no válido, intente de nuevo.\n");
        }
        return valido;
    }


}


Resultado:

run:
-------------
 MASTER-MIND
-------------

Se trata de adivinar un número, si adivinas el número y el lugar correcto es un muerto, si aciertas el número pero no el lugar es un herido.
EJEMPLO: El número a decifrar es el <1234>
Si introduces el <2136>. Esto te dará:
1 muerto(el 3) y 2 heridos(1 y 2). El 6 al no estar no cuenta.


Escriba número de 4 cifras (ej: 1234):

1º intento:
d34456

Código <d34456> no válido, intente de nuevo.

1º intento:
3458
1 muerto/s y 1 herido/s

2º intento:


domingo, 11 de septiembre de 2022

Mastermind. Crear un juego sencillo.

Código (Mastermid.java):

package mastermind;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Mastermind {

    public static void main(String[] args) {

        //presentación e instrucciones juego
        System.out.println("\n"
                + "-------------\n"
                + " MASTER-MIND\n"
                + "-------------\n\n"
                + "Se trata de adivinar un número, si adivinas el número y el lugar correcto es un muerto, si aciertas el número pero no el lugar es un herido.\n"
                + "EJEMPLO: El número a decifrar es el <1234>\n"
                + "Si tu introduces el <2136>. Esto te dará:\n"
                + "1 muerto(el 3) y 2 heridos(1 y 2). El 6 al no estar no cuenta.\n\n"
        );

        //inicializar variables
        List<String> valores = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
        int i_hallar[] = new int[4];
        int i_buscar[] = new int[4];
        int muerto, herido, cont = 1;
        String hallar = "", buscar;
        Scanner input;

        //generar código aleatorio        
        Collections.shuffle(valores); //mezclar valores
        for (int i = 0; i < 4; i++) {
            hallar += valores.get(i);
            i_hallar[i] = Integer.parseInt("" + hallar.charAt(i));
        }
        //System.out.println("Código decifrado: " + hallar);

        //iniciar partida
        System.out.println("Escriba número de 4 cifras (ej: 1234):\n");
        do {
            muerto = 0;
            herido = 0;
            do {
                System.out.println(cont + "º intento:");
                input = new Scanner(System.in);
                buscar = input.nextLine();
                if (buscar.length() != 4) {
                    System.out.println("Código no válido!\n");
                }
            } while (buscar.length() != 4);
            for (int i = 0; i < 4; i++) {
                i_buscar[i] = Integer.parseInt("" + buscar.charAt(i));
            }

            //búsqueda muertos y heridos
            for (int i = 0; i < i_hallar.length; i++) {
                for (int j = 0; j < i_buscar.length; j++) {
                    if (i_buscar[j] == i_hallar[i]) {
                        herido++;
                        if (j == i) {
                            herido--;
                            muerto++;
                        }
                    }
                }
            }
            System.out.println(muerto + " muerto/s y " + herido + " herido/s\n");
        } while (cont++ < 10 && muerto != 4);

        //resultado final
        if (muerto > 3) {
            System.out.println("\nCódigo descifrado! " + Arrays.toString(i_hallar));
            System.out.println("Has ganado!\n");
        } else {
            System.out.println("\nHas perdido!");
            System.out.println("Código era " + Arrays.toString(i_hallar) + "\n");
        }
    }

}


Resultado:

run:

-------------
 MASTER-MIND
-------------

Se trata de adivinar un número, si adivinas el número y el lugar correcto es un muerto, si aciertas el número pero no el lugar es un herido.
EJEMPLO: El número a decifrar es el <1234>
Si tu introduces el <2136>. Esto te dará:
1 muerto(el 3) y 2 heridos(1 y 2). El 6 al no estar no cuenta.


Escriba número de 4 cifras (ej: 1234):
 
1º intento:
4237
1 muerto/s y 1 herido/s

2º intento:
324
Código no válido!

2º intento:
6453
0 muerto/s y 1 herido/s

3º intento:
4712
2 muerto/s y 1 herido/s

4º intento:
4710
2 muerto/s y 2 herido/s

5º intento:
4701
4 muerto/s y 0 herido/s


Código descifrado! [4, 7, 0, 1]
Has ganado!

BUILD SUCCESSFUL (total time: 1 minute 12 seconds)


Con la tecnología de Blogger.