You are on page 1of 10

Universidad Simón Bolívar

Departamento de Computación y T.I.
CI2615 – Algoritmos y Estructuras I
Abril – Junio 2004

Proyecto Rompecabezas

Planteamiento del problema.

El rompecabezas es una figura dividida en piezas que debe ensamblarse. Se trata de un
tablero de MxN casillas y (MxN)-1 fichas que pueden deslizarse horizontal y verticalmente
hacia el espacio vacío restante. Por ejemplo:

Donde el rectángulo en negro representa la casilla vacía. El mecanismo es el siguiente:
dado un tablero desordenado, mover las fichas hasta encontrar un patrón prestablecido, con
la restricción de que el único tipo de movimiento permitido es el desplazamiento hacia la
casilla vacía de una de las fichas adyacentes a la misma, excluyendo las diagonales. Sin
embargo, podrán realizarse simultáneamente varios de estos movimientos, siempre que el
grupo de fichas a desplazar pertenezca a la misma fila o (exclusivo) columna de la casilla
vacía, por ejemplo:

El tamaño del patrón puede ser menor que el del tablero, por lo que su ubicación en el
mismo puede variar. Dado el patrón (a), en los estados (b) y (c) ya se ha armado el
rompecabezas:

a) b) c)

1

if movimiento es válido → mover ficha(s)  movimiento no es valido y jugador decidió no abandonar→ dar mensaje de error  jugador decidió abandonar → skip fi od if Patrón detectado → felicitar y resaltar  jugador decidió abandonar → skip fi od 2 .Se desea que usted diseñe e implemente un programa en GCL que permita armar un rompecabezas. Podemos aplicar análisis descendente para obtener una primera versión: do se desea armar un nuevo rompecabezas→ obtener patrón y tablero inicial. 5. 3. El programa debe tener la siguiente funcionalidad: 1. do patrón no detectado y jugador no abandona → obtener jugada. El tablero debe desplegarse en modo gráfico. Cuando el patrón es encontrado. Lo primero que debemos hacer es tener una visión general de la solución. con estados iniciales aleatorios. Al comenzar. Comenzamos con el componente lógico. Solución general El proyecto involucra dos componentes: uno de lógica y uno de interfaz. 6. El jugador puede decidir abandonar el juego en cualquier momento. 4. 2. resaltarlo en el tablero y felicitar al jugador. Debe permitir armar varios rompecabezas consecutivamente. Las fichas estarán representadas por círculos de colores. debe preguntar el nombre del jugador y generar aleatoriamente el patrón que desea armar (especificando las dimensiones del patrón). El patrón a armar debe mostrarse gráficamente. donde jugada es abandonar o dar un movimiento.

Sub-problema de verificar si un movimiento es válido. El problema puede descomponerse de la siguiente manera: compararArea . En el caso de un movimiento múltiple se indican fila y columna de la ficha mas alejada a mover hacia la casilla vacía.. Este tiene la siguiente forma: 3 . indique si el patrón se encuentra en algún sitio del tablero actual y si ese es el caso. como fue especificado en el aparte 3.. que indicarán el número de filas y columnas del arreglo. Para verificarlo.que desplaza el chequeo por todo el tablero..} donde vaciaX y vaciaY indican las coordenadas de la posición actual de la ficha vacía y fila. nos suministre las coordenadas del mismo. Los patrones para armar estarán representados por arreglos bidimensionales tales que: # F i _lPa as ≤t #rF o i _nlT a as b∧ #lCe or ol _uP m a ≤nt #rCa o son l _uT ma bn la e s r o Un movimiento está representado por las coordenadas fila y columna de la ficha que se va a desplazar hacia la casilla vacía. fila.. Según la descripción del problema....Estructuras de datos Un tablero podemos considerarlo como un arreglo de arreglos o arreglo bidimensional de colores. Al momento de especificar un procedimiento o función que reciba como parámetro un arreglo representando un tablero. Ambas acciones deben trabajar conjuntamente. Sub-problema de verificar si se ha armado el patrón. Un sub-problema derivado del análisis descendente es el de determinar si un movimiento suministrado por el usuario es válido.una función booleana que devuelve verdadero si el área examinada se corresponde con el patrón buscado y el procedimiento detectarPatron . de tal manera que el procedimiento detectarPatron. se deben examinar todas las submatrices del tablero que son de tamaño igual al patrón buscado.PostEsValido.} { Post: . el objetivo se logra cuando se ensambla el patrón dado en algún sitio del tablero. La forma de la función de validación es la siguiente booleano func esValido (entrada vaciaX. columna : entero) { Pre: .. donde área es una submatriz del tablero del tamaño del patrón. se incluirán dos parámetros adicionales. Cada casilla estará representada por un elemento del arreglo y contendrá el color correspondiente a la ficha que la ocupa (El negro representa la casilla vacía). vaciaY. columna las coordenadas de la ficha que indica la movida.PreEsValido.

.PostRealizarM. realizarMovimiento se puede apoyar en los procedimientos: moverAbajo. posY las coordenadas de la esquina superior izquierda del patrón encontrado cuando la variable esta es verdadero. N: entero.. arriba etc. entrada M. podemos completar el conjunto de instrucciones necesarias para realizar varias sesiones de juego : 4 .PostDetectarP. El procedimiento detectarPatron como fue descrito anteriormente es ineficiente. vaciaY: entero) { Pre: .} { Post: .PreRealizarM...... salida posX. entrada M. columna... entrada fila..Post Mover?.. Se sugiere que piense al respecto y trate de plantear sus propias mejoras. Se sugiere implementar este procedimiento como una función cuyo valor de retorno corresponda al parámetro esta y que posX y posY se implementen mediante un parámetro de entrada-salida de tipo arreglo de tamaño 2. vaciaY: entero) { Pre: .PreDetectarP. moverDerecha.} { Post: ... R: entero. realizarMovimiento – actualiza la estructura de datos del tablero. posY: entero) { Pre: . Sub-problema de mover una ficha... A su vez. proc realizarMovimiento (entrada-salida tablero : arreglo de arreglos de colores. vaciaX. entrada fila. columna. esta es una variable que indica el estado de la detección y posX.} proc mover??? (entrada-salida tablero : arreglo de arreglos de colores. booleano proc detectarPatron (entrada tablero : arreglo de arreglos de colores.} { Post: .. N: entero. entrada patron: arreglo de arreglos de colores.. vaciaX... podemos introducir optimizaciones que mejoren sustancialmente su eficiencia. moverArriba.} El juego Con los sub-problemas hasta ahora definidos. N: entero. salida esta: booleano.. entrada Q. Si se analiza mejor el problema y se usan sus características particulares.} donde. entrada M..PreMover?. moverIzquierda según se requiera desplazar la(s) ficha(s) indicadas por el usuario hacia abajo.... Posiblemente no siempre sea necesario recorrer todo el tablero para encontrar el patrón. La solución a este sub-problema.

patron. columna: entero. Q. N. detectado := detectarPatron(tablero. fila. fila. fila. fila. patron : arreglo de arreglos de colores. Q. R: entero. posX. 5 . otro := verdad. otro: booleano. fila. if esValido(vaciaX. R. columna. N. detectado := detectarPatron(tablero. La interfaz Con las actividades anteriores hemos diseñado un programa que captura la parte lógica o de cálculo del problema del Rompecabezas. esta. vaciaY. M. Q. columna) → realizarMovimiento(tablero. para que el programa pueda ser utilizado efectivamente. abandona: booleano. vaciaX. de acuerdo con esto. columna. patron. dar valores a fila. do otro → tomar patron y tablero inicial. Necesitamos ahora instrucciones que manejen la parte de interfaz. En esta parte introduciremos los elementos de interfaz requeridos. N. M.[ var tablero : arreglo de arreglos de colores. od ] 3. M. detectado: booleano. columna. do ¬detectado ∧¬abandona → solicitar al usuario su próxima jugada. vaciaY. posY). R. posY). abandona := falso.  ¬esValido(vaciaX. columna) → dar mensaje de error  abandona → skip fi od if detectado → felicitar y resaltar  abandona → skip fi preguntar al usuario si quiere armar otro rompecabezas y almacenar respuesta en “otro”. fila. posX. M. dibujar tablero inicial. columna y abandona. vaciaY) dibujar el movimiento. donde jugada es abandonar o dar un movimiento y. esta. N.

N: entero) Análogamente. se requiere un procedimiento dibujar_patrón que despliegue el patrón generado. que dibuja un tablero vacío para colocar el rompecabezas. se puede utilizar el nombre del jugador para preguntar si se desea jugar de nuevo. fila. se puede desplegar un mensaje como: Por favor <NombreJugador> . y si ese es el caso. Para el despliegue de información utilizaremos dos modos de manera conjunta: modo texto y modo gráfico. necesitamos preguntar al usuario si desea armar un nuevo rompecabezas. El procedimiento correspondiente tendrá la siguiente forma: proc obtenerMovimiento(salida abandona: booleano. N. Luego. salida fila. entrada M. Esto lo podemos hacer usando instrucciones provistas por el lenguaje para tal fin y almacenar el nombre en una variable NombreJugador de tipo secuencia de caracteres. Por otra parte necesitamos obtener del usuario el movimiento que desea realizar. vaciaX. preguntarle el nombre del patrón que desea armar. entrada tablero : arreglo de arreglos de colores. incluida la posibilidad de abandonar. El procedimiento podemos declararlo de la siguiente manera: proc otraSesion(salida otro: booleano. vemos que inicialmente el programa debe solicitar del jugador su nombre. columna: entero) Cada vez que se realice un movimiento. columna. cada vez que se requiera. El primer procedimiento necesario es dibujarTablero . Al final de cada sesión. hay que actualizar el tablero. Tiene la siguiente forma: proc dibujarTablero(entrada-salida mt: Maquina de trazados. 6 . introduzca un movimiento: También podríamos dar mensajes en caso de que una jugada no sea válida. entrada M. vaciaY: entero) Finalmente. El procedimiento correspondiente es como sigue: proc dibujarMovimiento(entrada-salida mt: Maquina de trazados. entrada tablero : arreglo de arreglos de colores.Para facilitar la programación vamos a limitar las operaciones de entrada de información por teclado en modo texto. con la que es posible dibujar las diferentes figuras geométricas requeridas por el programa. El tamaño del tablero puede establecerse a conveniencia. Repasando los requerimientos del programa. Para la salida gráfica del programa se utilizará la Maquina de Trazados.

fila. fila. fila. R: entero. posY). se recomienda seguir la sugerencia indicada en el aparte 5 para detectarPatron. Q. vaciaY. patron. vaciaY) dibujarMovimiento(mt. M. fila. N). vaciaX. M. N. posX. esta. M. columna. Q. nombrePatron). salida nombrePatron: secuencia de caracteres) Para implementar los procedimientos con varias variables de salida. N. R. dibujarTablero(mt. fila. columna. N. columna. detectado := detectarPatron(tablero. fila. Q. mt: MaquinaTrazados. vaciaY. fila. otro := verdad. detectado := detectarPatron(tablero. patron : arreglo de arreglos de colores. do otro → tomar patron y tablero inicial. otro: booleano. M. columna. detectado: booleano. posX. M. vaciaY). do ¬detectado ∧¬abandona → obtenerMovimiento(abandona. R. A continuación la versión final de nuestra solución incluyendo los procedimientos de interfaz: [ var tablero : arreglo de arreglos de colores. columna) → realizarMovimiento(tablero. tablero. columna: entero. esta. N. tablero. posY)  ¬esValido(vaciaX. N. if esValido(vaciaX. columna) → dar mensaje de error  abandona → skip fi od if detectado → felicitar y resaltar  abandona → skip fi otro := otraSesion(otro. columna). fila. patron. od ] 7 . abandona: booleano. vaciaX. M. abandona := falso.

b) Especificación formal (incluidos los invariantes). 8 .4. se quiere que se entregue un informe que contenga las siguientes secciones: • Portada. Material de apoyo Cualquier material requerido para la realización del proyecto estará disponible en la pagina web del curso. Segunda entrega (Semana 11) a) Traducción a GCL de los procedimientos realizarMovimiento y dibujarMovimiento. En este sentido. Entrega final (Semana 12) Para el día de la revisión usted deberá llevar una versión operativa del programa en GCL que permita armar rompecabezas según las especificaciones indicadas en el planteamiento del problema. El informe no se debe limitar a reportar las actividades indicadas en este enunciado. las actividades deben servir de guía para elaborar el informe. Entregas Primera entrega (Semana 10) a) Traducción a GCL del programa de la sección 8. Este programa debe mostrar el tablero inicial. b) Especificación formal (incluidos los invariantes) y cuerpo del procedimiento para compararArea. utilizando procedimientos y funciones dummy o stubs. 5. Además. La versión operativa del programa deberá ser entregada al profesor en un disquete debidamente identificado. para probar el flujo de control de un programa principal. o Abajo a la izquierda: nombre del profesor de laboratorio. cuerpo del procedimiento y prueba de correctitud para el procedimiento MoverAbajo. carrera y materia. los cuales simplemente retornan un valor arbitrario del tipo correcto o un mensaje indicando la operación que realizan. Es importante que el equipo trabaje de manera integrada. deberá entregar un informe que describa en detalle todo el proceso de diseño y desarrollo de la solución. Durante la revisión se verificará el funcionamiento del programa y se hará un corto interrogatorio particular a ambos miembros del equipo. Una hoja que contenga: o Arriba a la izquierda el nombre de la universidad. o Centrado: nombre del proyecto.

o Página Web: autor(es). o Manual de operación: nombre del archivo a ejecutar y modo de operar el programa. o Recomendaciones. o Operatividad del programa: decir si funciona perfectamente o no. D.sun. • Conclusiones. nombre. Electronic Musician 9(6). Una referencia bibliográfica debe incluir la siguiente información: o Libro: autor(es). o Dificultades presentadas. p. o Resultados obtenidos. o Código fuente documentado. Los siguientes son ejemplos de referencias bibliográficas: • Libro: Blair. • Estado actual. http://java. • Revista: Isaacson.: Language and Representation in Information Retrieval. nombre.: What is SMDI?. M. • Diseño: o Resultado del análisis descendente del problema (Diferencias con el análisis presentado en este instructivo).79-82 • Página Web: Sun Microsystems: The Java Tutorial. revista. fecha última visita. Al inicio de la clase de la semana 12. o Optimizaciones. revistas o cualquier recurso bibliográfico consultado. o Demostraciones de correctitud (De las entregas). o Contenido del informe. describir las anomalías. editorial y año. • Bibliografía. Noviembre 2000. o Abajo a la derecha: nombre y carnet de los integrantes del equipo • Introducción: o Breve descripción del problema atacado en el proyecto. Elsevier Science Publisher. En caso negativo. url. 1990. nombre.com. usted deberá entregar en un sobre sellado y debidamente identificado (nombre y carnet de los integrantes del equipo y nombre del proyecto): 9 . o Artículo: autor(es). número y año. volumen. Libros. o Estructuras de datos (Diferencias con el análisis presentado en este instructivo). • Detalles de implementacion.

• El listado del programa debidamente documentado. Los sobres deberán ser entregados a las 12:30pm (3:30pm) en punto en el laboratorio de clases. El disquette debe estar libre de defectos físicos y de virus. • Un disquete debidamente identificado (nombre y carnet de los integrantes del equipo y nombre del proyecto) que contenga en el directorio raíz los archivos . No se recibirán proyectos después de las 12:30pm (3:30pm). • Un informe según la estructura sugerida anteriormente. 10 . En caso de que el disquete no tenga la información requerida o presente algún tipo de defecto se asignará una nota de cero (0) a la revisión de la corrida.gcl de su proyecto.