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, 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.