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

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:



Con la tecnología de Blogger.