• No se han encontrado resultados

Listas, Pilas y Colas. Puzle de Imágenes UHU.

N/A
N/A
Protected

Academic year: 2022

Share "Listas, Pilas y Colas. Puzle de Imágenes UHU."

Copied!
12
0
0

Texto completo

(1)

Dpto. Tecnología de la Información 1

Práctica 1-B

Listas, Pilas y Colas.

Puzle de Imágenes UHU.

(2)

Dpto. Tecnología de la Información 2

PRACTICA 1-B. LISTAS, PILAS Y COLAS (PUZLE DE IMÁGENES EN FORMATO UHU)

1.- Introducción

Esta práctica versa sobre la construcción de un juego de puzle que utiliza las imágenes de formato UHU que se dieron en la práctica primera.

Para realizar el juego se necesita el código integro de la práctica primera para poder leer y ordenar los datos de las distintas imágenes UHU.

Un ejemplo de cómo quedaría la práctica final sería exactamente como la imagen que se muestra a continuación.

Como es obvio, queda fuera del ámbito de la práctica y de la asignatura que el que el alumno se especialice en temas gráficos, todo lo contrario. Lo que se pretende con esta práctica es que el alumno:

a) Entienda completamente el concepto de programación modular.

b) Sepa construir y manejar estructuras de datos lineales.

Para ello, al alumno se le entregará todos los módulos (estructuras y juego) de manera que solo tendrá que implementar los métodos relacionados con la construcción y manejo de las estructuras de datos. El resto de código que se entrega ya está realizado.

(3)

Dpto. Tecnología de la Información 3

Como es natural, el código referente a la primera práctica es necesario incluirlo en esta práctica, por lo que el alumno incorporará los módulos de la primera práctica (ttabla.h, ttabla.cpp y prac1.cpp) utilizando para ello el siguiente botón .

2.- Menú Principal

Al menú principal se le ha añadido una nueva opción que es la utilizada para jugar.

Antes de jugar, se debe cargar una imagen, ordenarla por uno de los métodos de ordenación y finalmente escoger la opción 4 (jugar).

En la nueva opción de menú, el alumno deberá cargar la imagen ordenada previamente en el juego y lanzar el método Jugar().

Tablero.ObtenerDibujo(dibujo);

Tablero.Jugar();

Donde:

Tablero: pertenece a la clase Juego (que se le proporciona inplementada).

Dibujo: Es el objeto de tipo ttabla que contiene la imagen cargada y ordenada.

3.- Tipos static

Esta práctica junto con la anterior adolece del problema de la limitación de memoria suficiente para cargar imágenes demasiado grades o de no poder tener definidas más de un objeto de tipo ttabla en la memoria.

Esto es debido a que en Windows la zona dedicada a la creación de variables locales y parámetros (la pila del programa) es de un tamaño limitado, entorno a dos megas, suficiente para la mayoría de programa pero que en nuestro caso ya que al utilizar imágenes se queda muy corta y totalmente insuficiente con los nuevos tipos de datos incluidos en esta práctica.

Un ejemplo clarificador:

• El sizeof(ttabla) nos devuelve 1923208bytes = 1.83Mbytes

• El sizeof(Juego) nos devuelve 3360060bytes = 3.2Mbytes

En total esta práctica necesita del entorno a 5 Mega bytes solo para poder empezar. Para solucionar este problema existen varias soluciones:

a) Utilizar variables globales. Solución que como sabéis es inviable por los problemas de efectos colaterales que tiene.

******************** MENU PRINCIPAL****************

1.- Leer fichero de una imagen.

2.- Visualizar la imagen.

3.- Ordenar la imagen.

4.- Jugar 5.- Salir

******************************************************

Elije la opción deseada :

(4)

Dpto. Tecnología de la Información 4

b) Utilizar estructuras de datos dinámicas cuya limitación de memoria es la propia limitación del ordenador.

c) Utilizar estructuras de datos estáticas (static).

Veamos un ejemplo antes de explicar qué son:

long fun(int v) {

static int datos[5000000];

...

...

}

Como podemos ver en el código anterior, la función tiene declarado una tabla de unos 10Mbytes. Esto en condiciones normales sería imposible, pero al tener la palabra static precediendo la declaración, hace que estos 10Mb no los coja de la Pila del programa sino de la memoria asignada a las variables globales que es infinitamente mayor que la memoria asignada a las variables locales y parámetros.

Al estar declarada en la zona de variables globales, esta tabla siempre existe y no se destruye aunque la función termine, pero tiene la propiedad de que sólo puede ser modificada dentro de la función y no fuera por lo que se evita el problema de los efectos colaterales.

En nuestra práctica, tendréis que anteceder la palabra static a la declaración de los tipos ttabla y Juego, y en aquellos métodos que necesitéis estructuras de datos lineales temporales como colas y pilas.

El uso y/o abuso de los tipos static no es recomendable ya que dicha memoria siempre está reservada eliminándola del resto de programas, independientemente de que se esté o no utilizando. Para esta práctica y debido a que aún no se han impartido los conocimientos sobre las estructuras de datos dinámicas, su uso está obligado.

4.- Tipos de datos

Además del tipo ttabla implementado en la práctica 1, se necesitan los siguientes tipos de datos que explicamos de menor a mayor complejidad. Hay que indicar que sólo los métodos señalados en negrita son lo que el alumno debe implementar.

4.1 Tipo Pz_Linea

Cada una de las imágenes almacenadas en la memoria, se va a dividir en un conjunto de trozos o pedazos de un tamaño de 100x100 puntos de color. Esta clase se encarga de almacenar una sola línea de 100 puntos de color.

En esta clase no hay que implementar ningún método (se da todo implementado).

#ifndef _Pz_Linea

#define _Pz_Linea

#include "ttabla.h"

(5)

Dpto. Tecnología de la Información 5 //Define el tamaño de los pedazos

#define LADO_PEDAZO_MAXIMO 100

//Contiene la información sobre una sola línea de 100 puntos de ancho class Pz_Linea {

tpunto Puntos[LADO_PEDAZO_MAXIMO]; //Puntos de color.

public:

//Constructor que inicializa la línea a 100 puntos negros Pz_Linea();

//Añade un punto a la línea

void PutPunto(int x,tpunto p) {Puntos[x]=p;};

//Devuelve un punto de la linea

tpunto GetPunto(int x) {return Puntos[x];};

//Devuelve true si dos líneas tienen los mismos colores bool operator==(Pz_Linea &L);

//Devuelve true si no son iguales las dos líneas de colores.

bool operator!=(Pz_Linea &L) {return !operator==(L);};

//Pinta una línea en la pantalla a partir de la posición (x,y) void Pinta(int x, int y);

};

#endif

4.2.- Tipo Pedazo

Almacena un total de 100 líneas de 100 puntos de color. Este tipo nos será muy útil como elemento de las estructuras de datos siguientes (Listas, Pilas y Colas) así como para el juego ya que permite pintar un pedazo de imagen en cualquier parte de la pantalla.

En esta clase no hay que implementar ningún método (se da implementado).

#ifndef _Pedazo

#define _Pedazo

#include "Pz_Linea.h"

class Pedazo {

Pz_Linea Lineas[LADO_PEDAZO_MAXIMO];//Contiene 100 Líneas de 100 puntos

public:

//Añadir una línea al Pedazo

void PutLinea(int y, Pz_Linea L) {Lineas[y]=L;};

//Pinta un Pedazo de imagen en la posiciones (x,y) void Pintar(int x,int y);

//Devuelve true si ambos trozos tienen los mismos colores.

bool operator==(Pedazo &P);

//Devuelve true ambos pedazos son distintos

bool operator!=(Pedazo &P){return !operator==(P);};

};

#endif

(6)

Dpto. Tecnología de la Información 6

4.3.- Tipo ColaPedazos

Almacena en una cola circular de tamaño fijo todos los pedazos (de 100x100) de una imagen.

El tamaño máximo de la cola se define en la macro MAX_PEDAZOS_COLA y se calcula de manera automática mediante la macro LADO_PEDAZO_MAXIMO, suponiendo que las imágenes tienen un tamaño máximo de 800x700 puntos.

Mediante este calculo, el programa determina cual es el tamaño máximo de la cola para que pueda almacenar todos los trozos de cualquier imagen. Si cambiamos el tamaño de los pedazos mediante la macro LADO_PEDAZO_MAXIMO, el tamaño de la cola aumentará o disminuirá para adaptarse al nuevo tamaño.

La implantación de la cola es la misma que se ha dado en clase, teniendo en cuenta que su representación interna es circular y que el tipo de dato que contiene es el tipo Pedazo.

No se proporciona la documentación de los métodos a implementar ya que la podéis obtener del temario de la asignatura.

#ifndef _ColaPedazos

#define _ColaPedazos

#include "Pedazo.h"

#define MAX_PEDAZOS_COLA (int)(800/LADO_PEDAZO_MAXIMO * 700/LADO_PEDAZO_MAXIMO)

class ColaPedazos{

//Contiene un nº limitado de trozos de imagen Pedazo Trozos[MAX_PEDAZOS_COLA];

int inicio, fin; //Inicio y fin de la cola circular int ne; //Nº de elementos de la cola

public:

//Constructor de la clae ColaPedazos();

//Añade un pedazo a la cola void encolar(Pedazo p);

//Desencolo un elemento de la cola void desencolar();

//Devuelve 0 si no es vacía 1 si es vacía.

int esvacia();

//Consulta la cabeza de la cola.

Pedazo primero();

//Devuelve el nº de entradas que existen en la estructura int longitud();

};

#endif

(7)

Dpto. Tecnología de la Información 7

4.4.- Tipo ListaPedazos

Almacena en lista todos los pedazos que forman una línea horizontal del puzle. Su tamaño se define mediante la macro MAX_PEDAZOS_LISTA que se calcula de manera automática mediante la macro LADO_PEDAZO_MAXIMO y suponiendo que las imágenes tienen un ancho máximo de 800 puntos.

La implantación de la lista es la misma que se ha dado en clase (no se implementan todos los métodos), teniendo en cuenta que el tipo de dato que contiene es el tipo Pedazo.

No se proporciona la documentación de los métodos a implementar ya que la podéis obtener del temario de la asignatura.

#ifndef _ListaPedazos

#define _ListaPedazos

#include "Pedazo.h"

#define MAX_PEDAZOS_LISTA (int)(800/LADO_PEDAZO_MAXIMO)

//Contiene una línea horizontal del tablero de pedazos de imagen class ListaPedazos {

Pedazo Trozos[MAX_PEDAZOS_LISTA]; //Pedazos que forman una línea int n;

public:

//Constructor de la clase ListaPedazos();

//Insertar un pedazo de imagen en la lista void insertar(int i, Pedazo p);

//Elimina un pedazo de imagen de la lista void eliminar(int i);

//Modifica un pedazo de imagen de la lista por otro pedazo de imagen void modificar(int i, Pedazo p);

//Devuelve 1 si la lista de pedazos de imagen está vacía int esvacia();

//Devuelve el pedazo de imagen que está en la posición i de la lista Pedazo observar(int i);

//Dado un pedazo de imagen nos dice donde está situado en la lista int posicion(Pedazo e);

//Devuelve el nº de pedazos de imagen que contiene la lista int longitud();

};

#endif

(8)

Dpto. Tecnología de la Información 8

4.5.- Tipo PilaPedazos

Almacena en pila todas las líneas horizontales de pedazos de imagen que forman el puzle. Su tamaño se define mediante la macro MAX_PEDAZOS_PILA que se calcula de manera automática mediante la macro LADO_PEDAZO_MAXIMO y suponiendo que las imágenes tienen una altura máxima de 700 puntos.

La implantación de la pila es la misma que se ha dado en clase, teniendo en cuenta que el tipo de dato que contiene es el tipo ListaPedazos.

No se proporciona la documentación de los métodos a implementar ya que la podéis obtener del temario de la asignatura.

#ifndef _PilaPedazos

#define _PilaPedazos

#include "ListaPedazos.h"

#define MAX_PEDAZOS_PILA (int)(700/LADO_PEDAZO_MAXIMO)

//Contiene todas las líneas del tablero de pedazos de imagen class PilaPedazos {

ListaPedazos Filas[MAX_PEDAZOS_PILA]; //Líneas del tablero int tope; //tope de la pila

public:

//Constructor de la clase PilaPedazos();

//Añade una linea horzontal al tablero (apila líneas horizontales) void apilar(ListaPedazos L);

//Elimina una línea horizontal del tablero.

void desapilar();

//Devuelve la línea del tablero que está en el tope de la pila ListaPedazos cima();

//Devuelve 1 si la pila está vacía int esvacia();

//Devuelve el nº de líneas del tablero almacenadas en la pila int longitud();

};

#endif

4.6.- Tipo Juego

El tipo Juego es la clase que aglutina el conjunto de métodos necesarios para jugar al puzzle.

Esta clase contiene dos estructuras principales, una PilaPedazos para almacenar los pedazos de imágenes que forman el tablero y una ColaPedazos para almacenar las fichas del juego (pedazos de imágenes) a colocar en el tablero.

El conjunto de métodos que se encargan de la representación gráfica de juego y del control del teclado se dan implementados y el alumno deberá implementar aquellos métodos que se encargan de manejar directamente las estructuras de datos antes mencionadas.

(9)

Dpto. Tecnología de la Información 9

En este tipo se proporciona la documentación de los métodos que tenéis que implementar, del resto se explica brevemente lo que hace.

#ifndef _Juego

#define _Juego

#include "PilaPedazos.h"

#include "ColaPedazos.h"

#define RESOLUCION_ANCHO 1124

#define RESOLUCION_ALTO 768

//Clase que permite jugar al puzzle de imágenes class Juego

{

PilaPedazos Tablero; //Tablero de juego (Pila de líneas de pedazos de //imagen)

ColaPedazos Fichas; //Cola de pedazos de imagen para pegar en el tablero int Columnas,Filas; //Nº de filas y Columnas del tablero

int ActX,ActY; //Posición (Columna y Fila) del tablero donde se inserta

//Pinta el trozo del tablero que está en una fila y columna dada void PintarTrozoTablero(int Fila, int Columna);

//Pinta todo el tablero de juego void PintarTablero();

//Pinta los trozos de imagen a insertar en el tablero void PintarFichas();

//Pinta el dibujo que forma del puzle de manera reducida void PintaDibujoReducido(ttabla &Dibujo, int Zoom);

//Muestra el menu del juego void MostrarMenu();

/*Mezcla el contenido de la estructura Fichas colocando sus Pedazos en distinto lugar.*/

void DesordenarFichas();

/*Mueve elementos desde la pila origen a la pila destino. El nº De

elementos a mover de una pila a la otra lo indica el Parámetro NVeces.

En caso de querer mover todos los datos, indicamos -1. Partimos de la base de que el valor de NVeces deber ser correcto

(- 1<=NVeces<=POrigen.longitud()) */

void MoverDatosEntrePilas(PilaPedazos &POrigen, PilaPedazos &PDestino, int NVeces);

/* Pone el trozo de imagen que está en la cabeza de la cola en la posición que indican los parámetros Fila y Columna (se parte de la base de que 0<=Fila<Filas y 0<=Columna<Columnas). Tenga en cuenta que la estructura Matriz es una pila y que cada elemento es un lista de trozos de imágenes. El nuevo trozo no se inserta en la lista sino que se

actualiza su posición.*/

void PonerFicha(int Fila, int Columna);

void CrearMatrizEnBlanco();

(10)

Dpto. Tecnología de la Información 10

/*La estructura de datos Tablerofichas a la que se aplica debe estar vacía. Este método lo que hace es Crear una matriz con pedazos de imágenes en blanco. Tenga en cuenta que la estructura tablerofichas es una pila de listas de pedazos de imagen. El tamaño del tablero lo da los atributos de la clase Columnas y Filas.*/

void EliminarDatosJuego();

/*Elimina los datos de las estructuras Tablerofichas y Fichas. Tenga en el tipo de datos de estas estructuras y también que se debe dejar el resto de atributos de la clase en el mismo estado que los deja el constructor

*/

void UltimaFicha_PrimeraPosicion();

/* Para usar este método debemos partir de que la estructura de datos Fichas debe contener pedazos de imágenes. Su tarea es colocar el último pedazo de imagen de la cola Fichas en la Primera posición de la cola. */

void PrimeraFicha_UltimaPosicion();

/*

Para usar este método debemos partir de que la estructura de datos Fichas debe contener pedazos de imágenes. Su tarea es colocar el primer pedazo de imagen de la cola Fichas en la última posición de la cola. */

void QuitarFicha(int Fila, int Columna);

/*

Pone el trozo de imagen que está en tablero en la posición Indicada al principio de la cola (se parte de la base de que se cumple 0<=Fila<Filas y 0<=Columna<Columnas). Tenga en cuenta que la estructura Tablero es una pila y que cada elemento es un lista de trozos de imágenes. Se actualiza el lugar donde se a quitado la ficha con un pedazo de imagen vacio (en negro).

*/

public:

//Constructor que se encarga de inicializar el juego Juego();

//Obtiene los pedazos de la imagen para jugar al puzzle del tipo ttabla void ObtenerDibujo(ttabla &Dibujo);

//Juega al puzzle void Jugar();

};

#endif

7.- Cómo se Juega

Como se puede observar en la figura de la página 2, la pantalla está dividida en tres partes. En la parte inferior una cola circular de pedazos de imágenes (Fichas del tablero) que se pueden desplazar a la izquierda y derecha mediante las teclas de función F1 y F2.

En la parte central izquierda el tablero que depende del tamaño de la imagen. Este tablero pinta los bordes de la casilla en azul, menos aquella en la que se colocará un pedazo de imagen en color rojo. Esta casilla en rojo se puede desplazar en sentido vertical y horizontal utilizando para ello las teclas del cursor.

(11)

Dpto. Tecnología de la Información 11

En la parte derecha encontramos un ejemplo reducido de la imagen que tenemos que construir en el tablero con las fichas de la cola circular situada en la parte inferior de la pantalla. Más debajo de la imagen reducida nos encontramos el menú del juego.

Cuando se pulsa la tecla Insertar del teclado, se mueve el pedazo de imagen de la cabecera de la cola (señalado con un recuadro rojo) al tablero en la posición señalada también con un contorno en rojo. Si el lugar donde queremos insertar un pedazo de imagen, no estuviera vacio, no se inserta nada.

Si se pulsa la tecla suprimir, se realiza el proceso contrario es decir, el trozo de imagen del tablero rodeado de un borde en rojo se moverá a la cola de pedazos pero quedándose en la cabecera, no en el fin de la cola. Si el lugar del tablero donde queremos eliminar un pedazo, no estuviera lleno, no se elimina nada.

Si queremos terminar el juego, pulsamos la tecla Fin del teclado.

6.- Fichero que se proporcionan

Se proporcionan los siguientes ficheros:

1) Practica1com.dev: Proyecto principal. Hay que añadirle nuestro ttabla.h y tabla.cpp así como el fichero .cpp que contenga el programa principal (prac1.cpp).

2) Practica1Ejemplo.exe: Para que observemos como funciona la práctica.

3) Pz_Linea.h y Pz_Linea.cpp: Ficheros que implementan una clase para manejar una sola línea de un pedazo de imagen.

4) Pedazo.h y Pedazo.cpp: Clase para manejar un pedazo de imagen.

5) ListaPedazos.h y ListaPedazos.cpp: Ficheros que implementan una clase para manejar una fila del tablero de juego.

6) PilaPedazos.h y PilaPedazos.cpp: Ficheros que implementan una clase que maneja un conjunto de elementos del tipo estructurado ListaPedazos.

7) ColaPedazos.h y ColaPedazoz.cpp: Ficheros que implementan una clase que maneja una cola circular de pedazos de imagen.

8) Juego.h y Juego.cpp: Ficheros que implementan una clase para jugar con un puzle.

9) Los mismos ficheros imagen con extensión uhu.

7.- Notas adicionales

Es aconsejable que el alumno siga las siguientes notas:

1) Aunque las estructuras de datos están preparadas para trabajar con pedazos de imágenes de distinto tamaño, aconsejamos que no se cambie la macro LADO_PEDAZO_MAXIMO y por ningún motivo se cambie las macros MAX_PEDAZOS_PILA, MAX_PEDAZOS_LISTA y MAX_PEDAZOS_COLA.

2) A la hora de abrir una ventana gráfica, utilice las resoluciones definidas en las macros RESOLUCION_ANCHO y RESOLUCION_ALTO. Estas macros nos permitirán crear una ventana de 1124x768 puntos.

3) Si no sale la práctica, recuerde que no será por culpa del código que se le entrega de las distintas clases, por lo tanto no lo modifique o parchee.

4) El formato de los ficheros es el mismo que para la práctica 1.

5) No olvide utilizar el modificador static dentro del código de los métodos y/o funciones, y solo para los tipos ttabla y PilaPedazos.

(12)

Dpto. Tecnología de la Información 12

6) Si tiene que utilizar estos tipos como parámetros de funciones o métodos no olvide de utilizar el paso por referencia y no el de copia.

8.- Fecha de Finalización

Dado que la prueba de modificación de la práctica 1 se realizará en la semana del 2 del Mayo, la práctica deberá estar finalizada con anterioridad al día concreto de dicha semana donde el alumno tenga su prueba de modificación.

Referencias

Documento similar