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

miércoles, 14 de septiembre de 2022

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)


domingo, 28 de agosto de 2022

Generación de números primos.

Código (Limit.java):

package limit;

public class Limit {

    public static void main(String[] args) {
        boolean p;
        int limit = 100;
        String aux = "";
        for (int n = 3; n < limit; n++) {
            p = esPrimo(n);
            aux += p ? n : "·";
        }
        System.out.println(aux);        
    }

    private static boolean esPrimo(int n) {
        //es numero par?
        if (n % 2 == 0) {
            return false;
        }
        //es numero multiplo del resto de numeros impares?
        for (int i = 3; i * i <= n; i += 2) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

}


Resultado:

run:
3·5·7···11·13···17·19···23·····29·31·····37···41·43···47·····53·····59·61·····67···71·73·····79···83·····89·······97··
BUILD SUCCESSFUL (total time: 0 seconds)

martes, 23 de agosto de 2022

Generación de laberintos IV. Formato final 1024x768.


Código 1 (Blogspot_Laberinto_final.java):

package blogspot_laberinto_final;

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

public class Blogspot_Laberinto_final {

    public static void main(String[] args) {

        //tamaño laberinto (núm. bloques)
        int x = 21;
        int y = 29;

        //generar laberinto aleatorio
        String strMaze = new LineMaze(new BinMaze(new Maze(y - 2, x - 2).toString(), x, y).toMatrix(), x, y).toString();

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

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

    }

}


Código 2 (Maze.java):

package blogspot_laberinto;

import java.util.LinkedList;
import java.util.Random;

public class Maze {

    public static final char PASSAGE_CHAR = ' ';
    public static final char WALL_CHAR = '█';
    public static final boolean WALL = false;
    public static final boolean PASSAGE = !WALL;

    private final boolean map[][];
    private final int width;
    private final int height;

    public Maze(final int width, final int height) {
        this.width = width;
        this.height = height;
        this.map = new boolean[width][height];

        final LinkedList<int[]> frontiers = new LinkedList<>();
        final Random random = new Random();
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        frontiers.add(new int[]{x, y, x, y});

        while (!frontiers.isEmpty()) {
            final int[] f = frontiers.remove(random.nextInt(frontiers.size()));
            x = f[2];
            y = f[3];
            if (map[x][y] == WALL) {
                map[f[0]][f[1]] = map[x][y] = PASSAGE;
                if (x >= 2 && map[x - 2][y] == WALL) {
                    frontiers.add(new int[]{x - 1, y, x - 2, y});
                }
                if (y >= 2 && map[x][y - 2] == WALL) {
                    frontiers.add(new int[]{x, y - 1, x, y - 2});
                }
                if (x < width - 2 && map[x + 2][y] == WALL) {
                    frontiers.add(new int[]{x + 1, y, x + 2, y});
                }
                if (y < height - 2 && map[x][y + 2] == WALL) {
                    frontiers.add(new int[]{x, y + 1, x, y + 2});
                }
            }
        }

    }

    @Override
    public String toString() {
        final StringBuffer b = new StringBuffer();
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        for (int y = 0; y < height; y++) {
            b.append(WALL_CHAR);
            for (int x = 0; x < width; x++) {
                b.append(map[x][y] == WALL ? WALL_CHAR : PASSAGE_CHAR);
            }
            b.append(WALL_CHAR);
            b.append('\n');
        }
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        return b.toString();
    }

}


Código 3 (BinMaze.java):

package blogspot_laberinto_final;

public class BinMaze {

    char[] vMaze;
    boolean[][] mMaze;

    public BinMaze(String strMaze, int x, int y) {
        vMaze = strMaze.replace("\n", "").toCharArray();
        mMaze = new boolean[x + 2][y + 2]; //se suma 2 para los bordes (ahorrar codigo)
        int cont = 0;
        for (int i = 1; i < x + 1; i++) {
            for (int j = 1; j < y + 1; j++) {
                mMaze[i][j] = vMaze[cont] == '█';
                cont++;
            }
        }
    }

    public boolean[][] toMatrix() {
        return mMaze;
    }

    public char[] toArray() {
        return vMaze;
    }

}


Código 4 (LineMaze.java):

package blogspot_laberinto_final;

public class LineMaze {

    String styleMap;

    public LineMaze(boolean[][] mMaze, int x, int y) {

        this.styleMap = "";
        String strMuro = " ├┬┌┤─┐┬┴└│├┘┴┤┼";
        boolean[][] mCod = combina();
        for (int i = 1; i < x + 1; i++) {
            for (int j = 1; j < y + 1; j++) {
                if (mMaze[i][j]) { // si hay muro
                    for (int k = 0; k < 16; k++) {
                        if (mMaze[i - 1][j] == mCod[k][0] && mMaze[i][j - 1] == mCod[k][1] && mMaze[i + 1][j] == mCod[k][2] && mMaze[i][j + 1] == mCod[k][3]) {
                            styleMap += strMuro.charAt(k);
                        }
                    }
                } else {
                    styleMap += " ";
                }
            }
            styleMap += "\n";
        }

    }    
    
    @Override
    public String toString() {        
        return styleMap;
    }

    private boolean[][] combina() {
        String cod;
        boolean[][] mCod = new boolean[16][4];
        for (int i = 0; i < 16; i++) {
            cod = Integer.toBinaryString(i);
            while (cod.length() < 4) {
                cod = "0" + cod;
            }
            for (int j = 0; j < cod.length(); j++) {
                mCod[i][j] = cod.charAt(j) == '1';
            }
        }
        return mCod;
    }

}


Código 5 (Lienzo.java):

package blogspot_laberinto_final;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, String strMaze) {

        //tamaño bloque 32x32
        int bloque_x = 32;
        int bloque_y = 32;

        String[] arrMaze = strMaze.split("\n");

        //grosor muro
        Stroke stroke5 = new BasicStroke(15f);

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

        //color muro
        g.setColor(Color.BLUE);
        int x0, y0;
        for (int j = 0; j < arrMaze.length; j++) {
            for (int i = 0; i < arrMaze[0].length(); i++) {
                if (arrMaze[j].charAt(i) != ' ') {
                    x0 = ((i + 1) * bloque_x) + bloque_x / 2;
                    y0 = ((j + 1) * bloque_y) + bloque_y / 2;
                    g.setStroke(stroke5);

                    switch (arrMaze[j].charAt(i)) {
                        case '─':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            break;
                        case '│':
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + bloque_y);
                            break;
                        case '┼':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + bloque_y);
                            break;
                        case '┬':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + bloque_y);
                            break;
                        case '┴':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 - bloque_y);
                            break;
                        case '├':
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + bloque_y);
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            break;
                        case '┤':
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + bloque_y);
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + (bloque_y / 2));
                            break;
                        case '┌':
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + bloque_y);
                            break;
                        case '┐':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + bloque_y);
                            break;
                        case '└':
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0 + (bloque_y / 2), x0 + bloque_x, y0 + (bloque_y / 2));
                            break;
                        case '┘':
                            g.drawLine(x0, y0 + (bloque_y / 2), x0 + (bloque_x / 2), y0 + (bloque_y / 2));
                            g.drawLine(x0 + (bloque_x / 2), y0, x0 + (bloque_x / 2), y0 + (bloque_y / 2));
                            break;
                        default:
                            break;
                    }

                }
            }
        }
    }

}


Resultado:



domingo, 21 de agosto de 2022

Generación de laberintos III. Guardar en formato .png (mini)

Generación de laberintos aleatorios con formato .png. Comprimido al máximo posible. Un pixel equivale a un bloque de muro (█).


Código 1 (Blogspot_Laberinto_png):

package blogspot_laberinto_png;

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

public class Blogspot_Laberinto_png {

    public static void main(String[] args) {

        // tamaño laberinto
        int x = 97;
        int y = 97;

        String strMaze = new Maze(y - 2, x - 2).toString();

        // resolucion de imagen .png
        int res_x = 99;
        int res_y = 99;

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

    }
}


Código 2 (Lienzo.java):

package blogspot_laberinto;

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

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, String strMaze) {
        
        //tamaño bloque (1x1 pixels)
        int tCuadroX = 1;

        String[] arrMaze = strMaze.split("\n");

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

        //dibujar bloques muro
        g.setColor(Color.BLUE);
        for (int j = 0; j < arrMaze.length; j++) {
            for (int i = 0; i < arrMaze.length; i++) {
                if (arrMaze[j].charAt(i) != ' ') {
                    g.fillRect(tCuadroX * (i + 1), tCuadroX * (j + 1), tCuadroX, tCuadroX);
                }
            }
        }
    }

}


Código 3 (Maze.java):

package blogspot_laberinto_png;

import java.util.LinkedList;
import java.util.Random;

public class Maze {

    public static final char PASSAGE_CHAR = ' ';
    public static final char WALL_CHAR = '█';
    public static final boolean WALL = false;
    public static final boolean PASSAGE = !WALL;

    private final boolean map[][];
    private final int width;
    private final int height;

    public Maze(final int width, final int height) {
        this.width = width;
        this.height = height;
        this.map = new boolean[width][height];

        final LinkedList<int[]> frontiers = new LinkedList<>();
        final Random random = new Random();
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        frontiers.add(new int[]{x, y, x, y});

        while (!frontiers.isEmpty()) {
            final int[] f = frontiers.remove(random.nextInt(frontiers.size()));
            x = f[2];
            y = f[3];
            if (map[x][y] == WALL) {
                map[f[0]][f[1]] = map[x][y] = PASSAGE;
                if (x >= 2 && map[x - 2][y] == WALL) {
                    frontiers.add(new int[]{x - 1, y, x - 2, y});
                }
                if (y >= 2 && map[x][y - 2] == WALL) {
                    frontiers.add(new int[]{x, y - 1, x, y - 2});
                }
                if (x < width - 2 && map[x + 2][y] == WALL) {
                    frontiers.add(new int[]{x + 1, y, x + 2, y});
                }
                if (y < height - 2 && map[x][y + 2] == WALL) {
                    frontiers.add(new int[]{x, y + 1, x, y + 2});
                }
            }
        }

    }

    @Override
    public String toString() {
        final StringBuffer b = new StringBuffer();
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        for (int y = 0; y < height; y++) {
            b.append(WALL_CHAR);
            for (int x = 0; x < width; x++) {
                b.append(map[x][y] == WALL ? WALL_CHAR : PASSAGE_CHAR);
            }
            b.append(WALL_CHAR);
            b.append('\n');
        }
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        return b.toString();
    }

}


Resultado:




sábado, 20 de agosto de 2022

Conversión decimal > binario > boleano


Código (Conversiones.java):

package conversiones;

import java.util.Arrays;

public class Conversiones {
    public static void main(String[] args) {
        System.out.println("Dec\tBin\tBoolean");
        String cod;
        boolean[] mCod;
        for (int i = 0; i < 16; i++) {
            cod = Integer.toBinaryString(i);
            while (cod.length() < 4) {
                cod = "0" + cod;
            }
            mCod = new boolean[cod.length()];
            for (int j = 0; j < cod.length(); j++) {
                mCod[j] = cod.charAt(j) == '1';
            }
            System.out.println(i + "\t" + cod + "\t" + Arrays.toString(mCod));
        }
    }
}


Resultado:

run:
Dec  Bin     Boolean
0    0000    [false, false, false, false]
1    0001    [false, false, false, true]
2    0010    [false, false, true, false]
3    0011    [false, false, true, true]
4    0100    [false, true, false, false]
5    0101    [false, true, false, true]
6    0110    [false, true, true, false]
7    0111    [false, true, true, true]
8    1000    [true, false, false, false]
9    1001    [true, false, false, true]
10   1010    [true, false, true, false]
11   1011    [true, false, true, true]
12   1100    [true, true, false, false]
13   1101    [true, true, false, true]
14   1110    [true, true, true, false]
15   1111    [true, true, true, true]
BUILD SUCCESSFUL (total time: 0 seconds)

Generación de laberintos II. Cambio de formato.

Ejemplo de tranformación


Código 1 (Blogspot_Laberinto.java):

package blogspot_laberinto;

public class Blogspot_Laberinto {

    public static void main(String[] args) {

        // Tamaño laberinto
        int x = 15;
        int y = 27;

        String strMaze = new Maze(y - 2, x - 2).toString();
        boolean[][] map0 = new StructMaze(strMaze, x, y).mMaze;
        StyleMaze sm = new StyleMaze(map0, x, y);

        // mostrar resultados
        System.out.println("\nLaberinto formato 1:\n");
        System.out.println(strMaze);
        System.out.println("\nLaberinto formato 2:\n");
        System.out.println(sm.map1);

    }

    private static class StructMaze {

        char[] vMaze;
        boolean[][] mMaze;

        public StructMaze(String strMaze, int x, int y) {
            vMaze = strMaze.replace("\n", "").toCharArray();
            mMaze = new boolean[x + 2][y + 2]; //se suma 2 para los bordes (ahorrar codigo)
            int cont = 0;
            for (int i = 1; i < x + 1; i++) {
                for (int j = 1; j < y + 1; j++) {
                    mMaze[i][j] = vMaze[cont] == '█';
                    cont++;
                }
            }
        }
    }

}


Código 2 (Maze.java):

package blogspot_laberinto;

import java.util.LinkedList;
import java.util.Random;

public class Maze {

    public static final char PASSAGE_CHAR = ' ';
    public static final char WALL_CHAR = '█';
    public static final boolean WALL = false;
    public static final boolean PASSAGE = !WALL;

    private final boolean map[][];
    private final int width;
    private final int height;

    public Maze(final int width, final int height) {
        this.width = width;
        this.height = height;
        this.map = new boolean[width][height];

        final LinkedList<int[]> frontiers = new LinkedList<>();
        final Random random = new Random();
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        frontiers.add(new int[]{x, y, x, y});

        while (!frontiers.isEmpty()) {
            final int[] f = frontiers.remove(random.nextInt(frontiers.size()));
            x = f[2];
            y = f[3];
            if (map[x][y] == WALL) {
                map[f[0]][f[1]] = map[x][y] = PASSAGE;
                if (x >= 2 && map[x - 2][y] == WALL) {
                    frontiers.add(new int[]{x - 1, y, x - 2, y});
                }
                if (y >= 2 && map[x][y - 2] == WALL) {
                    frontiers.add(new int[]{x, y - 1, x, y - 2});
                }
                if (x < width - 2 && map[x + 2][y] == WALL) {
                    frontiers.add(new int[]{x + 1, y, x + 2, y});
                }
                if (y < height - 2 && map[x][y + 2] == WALL) {
                    frontiers.add(new int[]{x, y + 1, x, y + 2});
                }
            }
        }

    }

    @Override
    public String toString() {
        final StringBuffer b = new StringBuffer();
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        for (int y = 0; y < height; y++) {
            b.append(WALL_CHAR);
            for (int x = 0; x < width; x++) {
                b.append(map[x][y] == WALL ? WALL_CHAR : PASSAGE_CHAR);
            }
            b.append(WALL_CHAR);
            b.append('\n');
        }
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        return b.toString();
    }

}


Código 3 (StyleMaze.java):

package blogspot_laberinto;

public class StyleMaze {

    public String map1;

    public StyleMaze(boolean[][] p0, int x, int y) {
        this.map1 = "";
        String strMuro = " ├┬┌┤─┐┬┴└│├┘┴┤┼";
        boolean[][] mCod = combina();
        for (int i = 1; i < x + 1; i++) {
            for (int j = 1; j < y + 1; j++) {
                if (p0[i][j]) { // si hay muro
                    for (int k = 0; k < 16; k++) {
                        if (p0[i - 1][j] == mCod[k][0] && p0[i][j - 1] == mCod[k][1] && p0[i + 1][j] == mCod[k][2] && p0[i][j + 1] == mCod[k][3]) {
                            map1 += strMuro.charAt(k);
                        }
                    }
                } else {
                    map1 += " ";
                }
            }
            map1 += "\n";
        }
    }

    private boolean[][] combina() {
        String cod;
        boolean[][] mCod = new boolean[16][4];
        for (int i = 0; i < 16; i++) {
            cod = Integer.toBinaryString(i);
            while (cod.length() < 4) {
                cod = "0" + cod;
            }
            for (int j = 0; j < cod.length(); j++) {
                mCod[i][j] = cod.charAt(j) == '1';
            }
        }
        return mCod;
    }

}


Resultado:

run:

Laberinto formato 1:

███████████████████████████
█ █       █ █ █         █ █
█ █████ ███ █ █ █ █ █████ █
█       █   █   █ █       █
███████ ███ █ ███ █ █ █████
█       █   █ █ █ █ █ █ █ █
███ ███ ███ ███ █ █████ █ █
█   █     █ █ █   █ █ █   █
█████████ █ █ ███ █ █ █ ███
█               █     █ █ █
███████ ███ ███ █ █████ █ █
█   █   █   █             █
███ █████ █ █ █ █████ █ ███
█         █ █ █     █ █   █
███████████████████████████


Laberinto formato 2:

┌─┬───────┬─┬─┬─────────┬─┐
│ │       │ │ │         │ │
│ └───┤ ┌─┘ │ ┴ ┬ ┬ ├───┘ │
│       │   │   │ │       │
├─────┤ ├─┤ │ ┌─┤ │ ┬ ┌─┬─┤
│       │   │ │ │ │ │ │ │ │
├─┤ ┌─┤ └─┐ ├─┤ ┴ ├─┼─┤ ┴ │
│   │     │ │ │   │ │ │   │
├───┴───┤ ┴ ┴ └─┐ ┴ ┴ │ ┌─┤
│               │     │ │ │
├───┬─┤ ┌─┤ ┌─┤ ┴ ├───┘ ┴ │
│   │   │   │             │
├─┤ └───┘ ┬ │ ┬ ├───┐ ┬ ├─┤
│         │ │ │     │ │   │
└─────────┴─┴─┴─────┴─┴───┘

BUILD SUCCESSFUL (total time: 0 seconds)


jueves, 11 de agosto de 2022

Generación de laberintos I.1. Algoritmo de Prim's 2.

Código 1 (Prime2.java):

package prime2;

public class Prime2 {

    public static void main(String[] args) {

        String laberinto = new Maze(31, 13).toString();
        System.out.println(laberinto);

    }

}


Código 2 (Maze.java):

package prime2;

import java.util.LinkedList;
import java.util.Random;

public class Maze {

    public static final char PASSAGE_CHAR = ' ';
    public static final char WALL_CHAR = '▓';
    public static final boolean WALL = false;
    public static final boolean PASSAGE = !WALL;

    private final boolean map[][];
    private final int width;
    private final int height;

    public Maze(final int width, final int height) {
        this.width = width;
        this.height = height;
        this.map = new boolean[width][height];

        final LinkedList<int[]> frontiers = new LinkedList<>();
        final Random random = new Random();
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        frontiers.add(new int[]{x, y, x, y});

        while (!frontiers.isEmpty()) {
            final int[] f = frontiers.remove(random.nextInt(frontiers.size()));
            x = f[2];
            y = f[3];
            if (map[x][y] == WALL) {
                map[f[0]][f[1]] = map[x][y] = PASSAGE;
                if (x >= 2 && map[x - 2][y] == WALL) {
                    frontiers.add(new int[]{x - 1, y, x - 2, y});
                }
                if (y >= 2 && map[x][y - 2] == WALL) {
                    frontiers.add(new int[]{x, y - 1, x, y - 2});
                }
                if (x < width - 2 && map[x + 2][y] == WALL) {
                    frontiers.add(new int[]{x + 1, y, x + 2, y});
                }
                if (y < height - 2 && map[x][y + 2] == WALL) {
                    frontiers.add(new int[]{x, y + 1, x, y + 2});
                }
            }
        }
    }

    @Override
    public String toString() {
        final StringBuffer b = new StringBuffer();
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        for (int y = 0; y < height; y++) {
            b.append(WALL_CHAR);
            for (int x = 0; x < width; x++) {
                b.append(map[x][y] == WALL ? WALL_CHAR : PASSAGE_CHAR);
            }
            b.append(WALL_CHAR);
            b.append('\n');
        }
        for (int x = 0; x < width + 2; x++) {
            b.append(WALL_CHAR);
        }
        b.append('\n');
        return b.toString();
    }
}


Resultado:




Generación de laberintos I. Algoritmo de Prim's 1.

Autor algoritmo: J. Zong en "Maze Generation with Prim's Algorithm"

 

Código (Prim.java):

package prim;

import java.util.ArrayList;

public class Prim {

    public static void main(String[] args) {  // dimensions of generated maze
        int r = 13, c = 31;

        // build maze and initialize with only walls
        StringBuilder s = new StringBuilder(c);
        for (int x = 0; x < c; x++) {
            s.append('█');
        }
        char[][] maz = new char[r][c];
        for (int x = 0; x < r; x++) {
            maz[x] = s.toString().toCharArray();
        }

        // select random point and open as start node
        Point st = new Point((int) (Math.random() * r), (int) (Math.random() * c), null);
        maz[st.r][st.c] = 'S';

        // iterate through direct neighbors of node
        ArrayList< Point> frontier = new ArrayList< Point>();
        for (int x = -1; x <= 1; x++) {
            for (int y = -1; y <= 1; y++) {
                if (x == 0 && y == 0 || x != 0 && y != 0) {
                    continue;
                }
                try {
                    if (maz[st.r + x][st.c + y] == ' ') {
                        continue;
                    }
                } catch (Exception e) { // ignore ArrayIndexOutOfBounds
                    continue;
                }
                // add eligible points to frontier
                frontier.add(new Point(st.r + x, st.c + y, st));
            }
        }

        Point last = null;
        while (!frontier.isEmpty()) {

            // pick current node at random
            Point cu = frontier.remove((int) (Math.random() * frontier.size()));
            Point op = cu.opposite();
            try {
                // if both node and its opposite are walls
                if (maz[cu.r][cu.c] == '█' && maz[op.r][op.c] == '█') {

                    // open path between the nodes
                    maz[cu.r][cu.c] = ' ';
                    maz[op.r][op.c] = ' ';

                    // store last node in order to mark it later
                    last = op;

                    // iterate through direct neighbors of node, same as earlier
                    for (int x = -1; x <= 1; x++) {
                        for (int y = -1; y <= 1; y++) {
                            if (x == 0 && y == 0 || x != 0 && y != 0) {
                                continue;
                            }
                            try {
                                if (maz[op.r + x][op.c + y] == ' ') {
                                    continue;
                                }
                            } catch (Exception e) {
                                continue;
                            }
                            frontier.add(new Point(op.r + x, op.c + y, op));
                        }
                    }
                }
            } catch (Exception e) { // ignore NullPointer and ArrayIndexOutOfBounds
            }

            // if algorithm has resolved, mark end node
            if (frontier.isEmpty()) {
                maz[last.r][last.c] = 'E';
            }
        }

        // print final maze
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                System.out.print(maz[i][j]);
            }
            System.out.println();
        }
    }

    static class Point {

        Integer r;
        Integer c;
        Point parent;

        public Point(int x, int y, Point p) {
            r = x;
            c = y;
            parent = p;
        }

        // compute opposite node given that it is in the other direction from the parent
        public Point opposite() {
            if (this.r.compareTo(parent.r) != 0) {
                return new Point(this.r + this.r.compareTo(parent.r), this.c, this);
            }
            if (this.c.compareTo(parent.c) != 0) {
                return new Point(this.r, this.c + this.c.compareTo(parent.c), this);
            }
            return null;
        }
    }
}



Resultado:



miércoles, 10 de agosto de 2022

Distancia entre 2 puntos en un espacio n-dimensional.


Fórmula:

 
d(P,Q) = SQRT[ (Q1-P1)^2 + (Q2-P2)^2 + (Q3-P3)^2 + ... + (Qn-Pn)^2 ]


Código java (Distancia2p.java)

package distancia2p;

import java.util.Arrays;

public class Distancia2p {

    public static void main(String[] args) {

        int n = 6;  //numero de dimensiones
        int[] A = new int[n];
        int[] B = new int[n];

        //posición cartesiana n coordenadas
        int maximo = 100;
        int minimo = 1;
        for (int i = 0; i < n; i++) {
            //numero aleatoria entre 1 (minimo) y 100 (maximo)
            A[i] = (int) Math.floor(Math.random() * (maximo - minimo + 1)) + minimo;
            B[i] = (int) Math.floor(Math.random() * (maximo - minimo + 1)) + minimo;
        }

        double aux = 0;
        double distancia;

        for (int i = 0; i < n; i++) {
            aux = aux + Math.pow((A[i] - B[i]), 2);
        }
        distancia = Math.sqrt(aux);

        //mostrar resultados
        System.out.println("*Distancia entre 2 puntos en un espacio de " + n + "-dimensiones:");
        System.out.println("coordenadas punto A: " + Arrays.toString(A));
        System.out.println("coordenadas punto B: " + Arrays.toString(B));
        System.out.println("Distancia entre punto A y B: " + distancia);

    }

}


Resultado:

run:
*Distancia entre 2 puntos en un espacio de 6-dimensiones:
coordenadas punto A: [29, 89, 69, 33, 18, 22]
coordenadas punto B: [76, 93, 41, 53, 43, 91]
Distancia entre punto A y B: 93.78166132032425
BUILD SUCCESSFUL (total time: 0 seconds)


miércoles, 3 de agosto de 2022

Gráficos 2D. Creación de un fractal 2 (árbol).

Código 1: (Blogspot_Fractal.java):

package blogspot_fractal;

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

public class Blogspot_Fractal {

    public static void main(String[] args) {

        int x = 300;
        int y = 256;
        int angulo = -90;
        int depth = 9;

        BufferedImage imagen = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
        Dibujo.Dibujar((Graphics2D) imagen.getGraphics(), x / 2, y, angulo, depth);

        try {
            ImageIO.write(imagen, "png", new File("Arbol.png"));
        } catch (IOException e) {
            System.out.println("Error de escritura");
        }

    }

}


Código 2: (Dibujo.java):

package blogspot_fractal;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

class Dibujo {

    public static void Dibujar(Graphics2D g, int x1, int y1, double angle, int depth) {

        if (depth == 0) {
            return;
        }
        
        g.setColor(Color.GREEN);
        
        // grosor rama dependiendo de la profundidad
        g.setStroke(new BasicStroke((float) depth));

        //Filtro antialiasing       
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 5.0);
        int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 6.0);
        g.drawLine(x1, y1, x2, y2);
        Dibujar(g, x2, y2, angle - 30, depth - 1);
        Dibujar(g, x2, y2, angle + 30, depth - 1);

    }

}


Resultado:


martes, 2 de agosto de 2022

Graficos 2D. Curva de Hilbert 2 (4K)

Código 1: (Blogspot_Curvahilbert.java)

package blogspot_curvahilbert;

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

public class Blogspot_CurvaHilbert {

    public static void main(String[] args) {

        // resolucion 4K
        int x = 2160;
        int y = 2160;
        int depth = 8;

        BufferedImage imagen = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);

        Dibujo.Dibujar((Graphics2D) imagen.getGraphics(), x / 2, y / 2, depth, y / 2);

        try {
            ImageIO.write(imagen, "png", new File("CurbaHilbert.png"));
        } catch (IOException e) {
            System.out.println("Error de escritura");
        }

    }

}


Código 2: (Dibujo.java):

package blogspot_curvahilbert;

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

class Dibujo {

    public static void Dibujar(Graphics2D g, int x, int y, int n, int size) {

        if (n == 0) {
            return;
        }

        int x0 = x - size / 2;
        int x1 = x + size / 2;
        int y0 = y - size / 2;
        int y1 = y + size / 2;
        g.setColor(Color.GREEN);
        g.drawLine(x0, y0, x0, y1);
        g.drawLine(x1, y0, x1, y1);
        g.drawLine(x0, y, x1, y);
        Dibujar(g, x0, y0, n - 1, size / 2);
        Dibujar(g, x0, y1, n - 1, size / 2);
        Dibujar(g, x1, y0, n - 1, size / 2);
        Dibujar(g, x1, y1, n - 1, size / 2);

    }

}


Resultado:





Con la tecnología de Blogger.