Autor Tema: Java dibujar rectángulo en un lienzo en consola utilizando caracteres coordenada  (Leído 8727 veces)

ana_docal@hotmail.com

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
La verdad llevo días dandole vueltas a este ejercicio sobre dibujar en un lienzo de caracteres en Java, y estoy atascada, he estado buscando informacion sobre Point en java pero es poco, por ejemplo yo puse el código con una matriz haciendo de lienzo... pero ahora ya estoy viendo que no es buena idea que sea de booleanos,estoy liada, no sé, es posible crear un lienzo vacio representado por guiones a partir de dos Point? y recorrerlos con bucles o algo así? es que la informacion que encuento es muy escasa...agradecería que alguien me guiase(disculpadme si no posteo en el lugar correcto aunque creo que si lo hice)



ENUNCIADO DEL EJERCICIO

Dados los siguientes recursos de JavaEE: clases java (normales, abstractas, interfaces), sobrecargas, herencia, sobrescritura, colecciones, polimorfismo, excepciones, javadoc...

Utiliza libremente los recursos que creas conveniente para estructurar la solución al siguiente problema:

Necesitamos poder imprimir en consola un lienzo de 60x30 caracteres (por defecto), en el que una celda vacía es representada por "-" y una rellena por "#" (por defecto). En este lienzo deseamos pintar figuras geométricas. De momento sólo necesitamos pintar rectángulos, pero sabemos que en un futuro podríamos necesitar incluir nuevas figuras. Los rectángulos pueden estar en cualquier posición del lienzo y de cualquier tamaño, siendo un rectángulo de especial interés el cuadrado.

Tras programar las clases oportunas en sus respectivos .java, debemos poder desde el método main() usando poco código: preparar un lienzo, añadir y eliminar figuras de este, e imprimirlo. Ejemplo de salida (ignora el hecho de que un cuadrado puede verse rectangular en la consola, según la fuente elegida):



Código: [Seleccionar]
/*
 To change this license header, choose License Headers in Project Properties.
 To change this template file, choose Tools | Templates
 and open the template in the editor.
 */
package EjercicioExamen;

/**

 @author ana
 */
public class Pinta
{

    /**
     @param args the command line arguments
     */
    public static void main(String[] args)
    {
        char inputChar = '-';

     
        // Primero creamos nuestra matriz
boolean[][] islleno = new boolean [30][60];
// Ahora instanciamos un entero para
// poder agregarle valores a la matriz.

                int n=0;
// Este ciclo anidado nos funciona
// para agregarle valores a la matriz.
for (int x = 0; x < islleno.length;x++) {
for (int y = 0; y < islleno[x].length; y++) {
n++;
islleno[x][y] = ((inputChar=='#'));
//                                  System.out.println(""+islleno[x][y]);
}   
}

// Este ciclo anidado nos permite pintar
// la matriz en consola.
for (int x = 0; x < islleno.length;x++) {
for (int y = 0; y < islleno[x].length; y++) {
                           
                            if(islleno[x][y] = (inputChar=='#'))
                            {
                               
                                System.out.print(inputChar);
                            }else{
                                inputChar='-';
                                System.out.print(inputChar);
                            }
// System.out.print("["+islleno[x][y]+"]");
}
System.out.println();
}

// Por ultimo solo pintamos las filas y
// columnas de nuestra matriz.
System.out.println("Número de fila: "+islleno.length);
System.out.println("Número de columnas: "+islleno[0].length);
         
    }
   
}
« Última modificación: 04 de Junio 2020, 18:27 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Java :dibujar rectangulo en un lienzo en consola. Necesito ayuda
« Respuesta #1 en: 07 de Octubre 2018, 02:35 »
Hola.
Me ha parecido interesante este ejercicio y he hallado una solución. La explico aquí a ver si te sirve.

Sobre la matriz que representa el lienzo
Usar booleanos no es mala idea del todo.
Tambien se podría usar directamente char y llenar la matriz con '-' y '#'

Pero ambos casos presentan un problemita.

El enunciado no lo especifica, pero supongo que las figuras NO se pueden solapar. Es decir, no se podría dibujar un rectangulo encima de otro. O tal vez si...

Pero en el caso de que NO se pueda, aunque se utilicen solo dos símbolos para representar el lienzo, en realidad cada "punto" del lienzo tiene tres posibles estados.
  • Vacio, porque no hay nada. Se representa con '-'
  • Ocupado, si es el borde de la figura, se representa con '#'
  • Ocupado, pero si es el area interna de la figura, no el borde, se representa tambien con '-'

Este tercer estado es el que complica un poco la cosa. El char '-' en realidad no implica que el espacio este vacío, puede tratarse del area interna de una figura ya dibujada.
Así que puesto que tenemos tres posibles estados: vacio, ocupado por borde u ocupado por area interna.... no nos va a servir rellenar la matriz con boolean ni tampoco directamente con los dos char usados para dibujar.

Necesitamos idear otra forma que nos indique las tres posibilidades.
Por ejemplo, podemos usar un valor numerico, un int o un byte, para rellenar la matriz.
Y podemos establecer que solo tenga tres posibles valores: 0, 1 y 2
0 -> Espacio libre, se representa en pantalla con "-"
1 -> Area interior de la figura, espacio ocupado, pero se representa tambien con "-"
2 -> Borde exterior de la figura, espacio ocupado, se representa con "#"


Así ya solucionamos el como representar los tres posibles estados.

Bueno, dicho esto. Para separar código, he escrito una clase llamada Lienzo (luego la mostraré) cuyo atributo es precisamente la matriz que representa el lienzo.
Esta clase tiene métodos que se encargan de dibujar en pantalla el lienzo y otro, el más importante y un pelín complicado, el método que se encarga de insertar un rectángulo en el lienzo a partir de dos puntos.
Cada punto, requiere de dos coordenados, una X para la vertical y otra Y para la horizontal.

Es decir, el usuario para "pintar" un rectángulo tendrá que proporcionar cuatro valores.
El X e Y del punto de "inicio" y el X e Y del punto de "fin"
Con ese inicio y ese fin, podemos dibujar un rectangulo dentro del lienzo.

Bien, aunque no es del todo necesario, para que el programa sea más legible he escrito una clase llamada Punto. Es posiblemente la clase más simplona de la historia de la programación xD , pero ayuda a que luego el programa se entienda mejor que está haciendo.
Es basicamente dos atributos X e Y, y sus correspondientes getters
Punto
Código: [Seleccionar]
package pintaLienzo;

public final class Punto {

private byte puntoX;
private byte puntoY;

public Punto(byte x, byte y) {
puntoX = x;
puntoY = y;
}

public byte getX() {
return puntoX;
}

public byte getY() {
return puntoY;
}

}


A continuacion explico la clase Lienzo.

-Tiene tres atributos, una matriz de byte y dos constantes para fijar los limites horizontales y verticales de la matriz/lienzo.

- El constructor, lo que hace es inicalizar la matriz y rellenarla con el valor 0, es decir, el lienzo se inicia completamente vacio

- el metodo mostrarLienzo() es muy simple. Recorre la matriz y si encuentra el valor 2, dibuja el char '#' que es el que representa el borde de las figuras.
Si no, dibujará un char '-', ya sea espacio vacio o area interna de alguna figura.

- el metodo insertarRectangulo() es un pelin complicado.
Recibe por parametros dos Puntos, el de inicio y el de fin.
Se podría haber simplificado si hubieramos decidido que el punto de inicio siempre va a representar la esquina superior izquierda del rectangulo, y el punto de fin siempre será la esquina inferior derecha.
Por ejemplo, inicio = 1,1 ; fin = 10,10
De este modo, siempre recorreriamos la matriz, desde las coordenadas indicadas, de izquierda a derecha y de arriba a abajo.

Pero no he podido resistirme ha dar cierta libertad al usuario para que el decida que esquina representará el punto de inicio y fin.
Así que puede ocurrir que los puntos sean, por ejemplo, inicio 10,1; fin = 1,10
EStas coordenadas en realidad van a dibujar exactamente el mismo rectangulo que las coordenadas del ejemplo anterior, solo que habrá que empezar a dibujar desde una esquina distinta.

Y averiguar donde esta la esquina de inicio, donde la de fin y decidir que direccion van a tomar los bucles que recorren la matriz, ha de hacerlo el código.

Por eso este metodo tiene varios if else anidados. Porque comparo los valores X e Y de ambos puntos, para discernir si inicio esta arriba o abajo respecto a fin, y si además está a la derecha o a la izquierda de este.
Esto significa cuatro posibilidades,  y para cada posibilidad, los bucles harán el recorrido en un sentido o en otro.

Otra cosa importante que hace este método es, antes de insertar la figura y modificar ningún valor, comprueba que realmente el area que va a ocupar la figura está libre y no se va a solapar con ninguna otra figura.
Es un metodo de tipo booleano, así que si no puede insertar la figura, devolverá FALSE.
Si no hubo problema en insertar, devolverá TRUE

Lienzo
Código: [Seleccionar]
package pintaLienzo;

public final class Lienzo {

private final int VERTICAL = 30;
private final int HORIZONTAL = 60;
private byte[][] lienzo;
/*
* La matriz que representa el lienzo tendrá 3 posibles valores.
* 0 -> Espacio libre, se representa en pantalla con "-"
* 1 -> Area interior de la figura, espacio ocupado, pero se representa tambien con "-"
* 2 -> Borde exterior de la figura, espacio ocupado, se representa con "#"
*/

public Lienzo() {
lienzo = new byte[VERTICAL][HORIZONTAL];
for (int i = 0; i < VERTICAL; i++)
for (int j = 0; j < HORIZONTAL; j++)
lienzo[i][j] = 0;
}

/**
* Muestra el lienzo en pantalla segun los valores de la matriz
*/
public void mostrarLienzo() {
for (int i = 0; i < VERTICAL; i++) {
for (int j = 0; j < HORIZONTAL; j++)
System.out.print(lienzo[i][j] == 2?"#":"-");//Si es borde, pintamos "#", sino pintamos "-"
System.out.println();
}
}

public boolean insertarRectangulo(Punto inicio, Punto fin) {
/*
* Nos han proporcionado dos Puntos entre los que debemos crear un rectangulo.
* Lo logico sería que el Punto inicio represente la esquina superior izquierda de la figura y
* el Punto fin represente la esquina inferior derecha.
* Pero no tiene por que ser así, podemos dar libertad para que el usuario proporcione los Puntos
* como quiera y el programa se encargue de discenir como orientar la figura
*/
if (inicio.getX() < fin.getX())//Punto de inicio esta por ENCIMA del Punto fin
if (inicio.getY() < fin.getY()) {//Punto de inicio esta a la IZQUIERDA del Punto fin

//inicio es esquina sup-izq, fin es esquina inf-der
/*
* Antes de insertar, comprobamos que el area que va a ocupar el rectangulo
* no está ocupada ya por otra figura
*/
for (int i = inicio.getX(); i <= fin.getX(); i++)
for (int j = inicio.getY(); j <= fin.getY(); j++)
if (lienzo[i][j] != 0) return false;//Se ha encontrado algun espacio ocupado, no se puede insertar figura

//Comprobado que el area esta libre, insertamos la figura
for (int i = inicio.getX(); i <= fin.getX(); i++)
for (int j = inicio.getY(); j <= fin.getY(); j++)
//Si es borde insertamos 2, si es area interior insertamos 1
if (j == inicio.getY() || j == fin.getY() || i == inicio.getX() || i == fin.getX())
lienzo[i][j] = 2;//Es un borde
else
lienzo[i][j] = 1;//Es area interna
}
else {//Punto de inicio esta a la DERECHA del Punto fin

//inicio es esquina sup-der, fin es esquina inf-izq
for (int i = inicio.getX(); i <= fin.getX(); i++)
for (int j = inicio.getY(); j >= fin.getY(); j--)
if (lienzo[i][j] != 0) return false;
//Insertamos
for (int i = inicio.getX(); i >= fin.getX(); i--)
for (int j = inicio.getY(); j <= fin.getY(); j++)
if (j == inicio.getY() || j == fin.getY() || i == inicio.getX() || i == fin.getX())
lienzo[i][j] = 2;
else
lienzo[i][j] = 1;
}
else//Punto de inicio esta por DEBAJO del Punto fin
if (inicio.getY() < fin.getY()) {
//inicio es esquina inf-izq, fin es sup-der
for (int i = inicio.getX(); i >= fin.getX(); i--)
for (int j = inicio.getY(); j <= fin.getY(); j++)
if (lienzo[i][j] != 0) return false;
//Insertamos
for (int i = inicio.getX(); i >= fin.getX(); i--)
for (int j = inicio.getY(); j <= fin.getY(); j++)
if (j == inicio.getY() || j == fin.getY() || i == inicio.getX() || i == fin.getX())
lienzo[i][j] = 2;
else
lienzo[i][j] = 1;
}
else {
//inicio es esquina inf-der, fin es sup-izq
for (int i = inicio.getX(); i >= fin.getX(); i--)
for (int j = inicio.getY(); j >= fin.getY(); j--)
if (lienzo[i][j] != 0) return false;
//Insertamos
for (int i = inicio.getX(); i >= fin.getX(); i--)
for (int j = inicio.getY(); j >= fin.getY(); j--)
if (j == inicio.getY() || j == fin.getY() || i == inicio.getX() || i == fin.getX())
lienzo[i][j] = 2;
else
lienzo[i][j] = 1;
}
//Llegados a este punto, es que la insercion ha sido correcta
return true;
}


}

Y por ultimo, una pequeña clase Test para comprobar si funciona.

Muestra un pequeño menu para que el usuario escoja entre mostrar el Lienzo, insertar un Rectangulo o finalizar el programa.

Para insertar el Rectangulo, se le piden los valores X e y para el Punto inicio y el Punto fin. Para pedir estos valores uso un par de metodos que solo aceptan valores acordes a las dimensiones del lienzo.
Una vez obtenido los Puntos, se los paso a la clase Lienzo para que intente insertar la figura y me devolverá TRUE o FALSE segun si pudo insertarla o no.

Test
Código: [Seleccionar]
package pintaLienzo;

import java.util.Scanner;

public final class Test {

static Lienzo lienzo = new Lienzo();
static Scanner teclado = new Scanner(System.in);

static byte pedirX() {
byte x = -1;
do {
System.out.print("\nInserte coordenada X entre 0 y 29: ");
x = teclado.nextByte();
} while(x < 0 || x > 29);
return x;
}

static byte pedirY() {
byte y = -1;
do {
System.out.print("\nInserte coordenada Y entre 0 y 59: ");
y = teclado.nextByte();
} while(y < 0 || y > 59);
return y;
}

static void mostrarMenu() {
System.out.println("\n\n\t\tMENU LIENZO JAVA");
System.out.println("-1- Mostrar lienzo actual");
System.out.println("-2- Insertar un RECTANGULO");
System.out.println("-0- FIN DE PROGRAMA");
System.out.print("Elija opcion: ");
}

static void dibujarRectangulo() {
System.out.println("\n\tPUNTO DE INICIO");
byte inicioX = pedirX();
byte inicioY = pedirY();
System.out.println("\n\tPUNTO DE FIN");
byte finX = pedirX();
byte finY = pedirY();

Punto inicio = new Punto(inicioX, inicioY);
Punto fin = new Punto(finX, finY);

System.out.println(lienzo.insertarRectangulo(inicio, fin)?"\nRECTANGULO insertado":"NO se pudo insertar, pruebe otras coordenadas");
}

public static void main(String[] args) {

int opcion = -1;
do {
mostrarMenu();
opcion = teclado.nextInt();
switch (opcion) {
case 0:
System.out.println("\n\n\t\tFIN DE PROGRAMA");
break;
case 1:
lienzo.mostrarLienzo();
break;
case 2:
dibujarRectangulo();
break;
default:
System.out.println("\nOpcion invalida");
}
}while(opcion != 0);
}
}

Creo que esto cumple con el enunciado.
Siempre y cuando, NO se permita el solapamiendo de figuras.
Si no hubiera problema en dibujar figuras una encima de otras, todo sería más simple y no necesitariamos controlar tres posibles estados.

Echale un ojo y pregunta lo que no entiendas.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re: Java :dibujar rectangulo en un lienzo en consola. Necesito ayuda
« Respuesta #2 en: 07 de Octubre 2018, 02:36 »
Te muestro aqui el resultado que obtengo en consola al ejecutar el programa

Código: [Seleccionar]

MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 1
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 2

PUNTO DE INICIO

Inserte coordenada X entre 0 y 29: 1

Inserte coordenada Y entre 0 y 59: 89

Inserte coordenada Y entre 0 y 59: 1

PUNTO DE FIN

Inserte coordenada X entre 0 y 29: 15

Inserte coordenada Y entre 0 y 59: 15

RECTANGULO insertado


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 1
------------------------------------------------------------
-###############--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-###############--------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 2

PUNTO DE INICIO

Inserte coordenada X entre 0 y 29: 4

Inserte coordenada Y entre 0 y 59: 4

PUNTO DE FIN

Inserte coordenada X entre 0 y 29: 40

Inserte coordenada X entre 0 y 29: 20

Inserte coordenada Y entre 0 y 59: 40
NO se pudo insertar, pruebe otras coordenadas


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 2

PUNTO DE INICIO

Inserte coordenada X entre 0 y 29: 16

Inserte coordenada Y entre 0 y 59: 16

PUNTO DE FIN

Inserte coordenada X entre 0 y 29: 8

Inserte coordenada Y entre 0 y 59: 40

RECTANGULO insertado


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 1
------------------------------------------------------------
-###############--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------##########################-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-################-----------------------#-------------------
----------------#########################-------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 2

PUNTO DE INICIO

Inserte coordenada X entre 0 y 29: 29

Inserte coordenada Y entre 0 y 59: 59

PUNTO DE FIN

Inserte coordenada X entre 0 y 29: 24

Inserte coordenada Y entre 0 y 59: 10

RECTANGULO insertado


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 1
------------------------------------------------------------
-###############--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------#--------------------------------------------
-#-------------##########################-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-#-------------##-----------------------#-------------------
-################-----------------------#-------------------
----------------#########################-------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
----------##################################################
----------#------------------------------------------------#
----------#------------------------------------------------#
----------#------------------------------------------------#
----------#------------------------------------------------#
----------##################################################


MENU LIENZO JAVA
-1- Mostrar lienzo actual
-2- Insertar un RECTANGULO
-0- FIN DE PROGRAMA
Elija opcion: 0


FIN DE PROGRAMA
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

ana_docal@hotmail.com

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 2
    • Ver Perfil
Re: Java :dibujar rectangulo en un lienzo en consola. Necesito ayuda
« Respuesta #3 en: 07 de Octubre 2018, 10:30 »
Muchisimas gracias, intentare ver tus explicaciones sin copiar el codigo ;D ;D ;D ;D porque me han ayudado a verlo de otro modo, que es justo lo que necesitaba

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".