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:
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
-
►
2012
(38)
- ► septiembre (3)
-
►
2020
(12)
- ► septiembre (1)
-
▼
2024
(29)
-
▼
agosto
(17)
- Problema del Viajante de Comercio TSP (V.1). Métod...
- Problema del Viajante de Comercio TSP (V.2). Métod...
- Problema del Viajante de Comercio TSP (V.3). Métod...
- Problema del viajante de Comercio TSP (IV.2). Méto...
- Problema del Viajante de Comercio TSP (V.3.1). Aná...
- Matriz de conectividad circular.
- Problema del viajante de Comercio TSP (VI). Método...
- Problema del viajante de Comercio TSP (VII). Métod...
- Problema del viajante de Comercio TSP (VIII). Méto...
- Problema del viajante de Comercio TSP (IX). Método...
- Problema del viajante de Comercio TSP (X). Método ...
- Problema del viajante de Comercio TSP (XI). Método...
- Problema del viajante de Comercio TSP (XII). Métod...
- Problema del viajante de Comercio TSP (XIII). Méto...
- Problema del viajante de Comercio TSP (XIV). Métod...
- Problema del viajante de Comercio TSP (XV). Método...
- Juegos VII. La Mansión Misteriosa: Un juego de tex...
-
▼
agosto
(17)
domingo, 21 de agosto de 2022
Generación de laberintos III. Guardar en formato .png (mini)
sábado, 20 de agosto de 2022
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: