Fecha y hora actual: Viernes 26 Abr 2019 12:07
Índice del Foro

Foros de programación informática, diseño gráfico y Web

En esta comunidad intentaremos dar soporte de programación a todos los niveles, desde principiantes a profesionales de la informática, desarrollo de programas, programación web y mucho más.

Proyecto Final: Juego Buscaminas

Responder al Tema Ir a página 1234Siguiente

Índice del Foro > Programación en general > Proyecto Final: Juego Buscaminas

Autor Mensaje
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Miércoles 31 Ago 2011 18:30

Título del mensaje: Proyecto Final: Juego Buscaminas

Responder citando

Proyecto Final - Juego Buscaminas

Les propondré aquí el trabajo con lo que fue la segunda tarea de Programación 1 en la Facultad de Ingeniería donde estudio, corresponde al año 2009. Estos proyectos están diseñados para que apliquen todo lo dado aquí y para que piensen de forma estructurada, la misma forma que he enseñado a lo largo de este curso. Es de alto nivel pero podrán hacerla con mi ayuda, yo estaré abierto a que pregunten todas y cada una de las dudas que tengan al respecto ya que por lo general estos trabajos se acompañan con alguna clase de consulta.

Deben leer todo antes de continuar, ya que luego de la letra del problema existen las instrucciones para implementarlo ya que se les brindará un archivo con el código ya escrito para la interfaz gráfica y un archivo con el cual deberán trabajar ustedes creando el motor del juego. Aquí ven un ejemplo de un programa donde un archivo se encarga de realizar la interfaz gráfica y otro de hacer las tareas del programa, luego ambos trabajan juntos.

Reitero, lean toda la letra antes de intentar hacer algo.

1. Introducción

Este problema fue presentado como tarea para los estudiantes de Programación 1, asignatura de primer año donde se intenta enseñar a programar desde la nada a los estudiantes. Claro está que en un curso formal esto tenía plazos de entrega y estaba sujeto a los rigurosos test del equipo del Instituto de Computación de la facultad, de modo que si el programa no funcionaba perfectamente uno perdía el curso directamente sin posibilidad de dar exámenes, por más bien que le haya ido en las pruebas escritas.
Aquí ustedes no manejarán plazos porque esto es voluntario y personal, cada uno ve si toma esta oportunidad o la deja. Saludos.
__________________________________________________________

2. Información general

Aquí se redactaban las reglas para los estudiantes, tales como cuál compilador utilizar, qué pasa si se copian el código fuente o parte del mismo, etc. Ustedes no tienen restricciones en esto, usen lo que más cómodo les quede para trabajar, y por supuesto, si comparte código no hay problema, al contrario.
___________________________________________________________

3.  Presentación

El buscaminas es un conocido juego de computadora que simula un campo de minas que debe ser despejado por el jugador, marcando la posición de todas las minas sin pisar ninguna.

Incluímos una descripción de las reglas tomada de la Wikipedia

(http://es.wikipedia.org/wiki/Buscaminas)



El juego consiste en despejar todas las casillas de una pantalla que no oculten una mina.

Algunas casillas tienen un número, este número indica las minas que suman todas las casillas circundantes. Así si una casilla tiene el número 3 significa que de las ocho casillas que hay alrededor (si no está en una esquina o borde) hay 3 con minas y 5 sin minas. Si se descubre una casilla sin número indica que ninguna de las casillas vecinas tiene mina y estas se descubren automáticamente.
Si se descubre una casilla con una mina se pierde la partida.

3.1  Acciones Básicas

Existen muchas versiones del buscaminas que pueden diferir en algunos aspectos. La mayoría de ellas incluye los siguientes movimientos por parte del jugador:

Descubrir una celda: Esta acción se realiza sobre una celda oculta. El resultado depende del contenido de la celda:

  • Si la celda contiene una mina el juego se pierde.
  • Si la celda está libre pero hay minas en las celdas circundantes, aparece un número (entre 1 y 8) que indica la cantidad de celdas circundantes que contienen una mina.
  • Si la celda está libre y no hay minas en ninguna de las celdas circundantes, la celda se descubre y también se descubren automáticamente todas las casillas circundantes, aplicando el mismo procedimiento para cada una de ellas. Este procedimiento deja al descubierto toda un área de casillas libres adyacentes.


Marcar una celda: Esta acción se realiza sobre una celda oculta que el jugador supone que contiene una mina; suposición que puede ser correcta o no. Independientemente de ello, el sistema muestra la celda como marcada e incrementa el contador de celdas marcadas.

Desmarcar una celda: Esta acción se realiza sobre una celda marcada. El resultado es desmarcar la celda y dejarla como oculta. y decrementar el número de celdas marcadas

3.2  Acciones complementarias

Varias versiones del buscaminas también incorporan las siguientes facilidades:

Despejar circundantes de una celda: Esta acción se realiza sobre una celda ya descubierta. El resultado es descubrir todas las celdas circundantes que no estén marcadas. Por “descubrir” entendemos ejecutar la acción descubrir una celda explicada más arriba. La acción se lleva a cabo, solamente si el número que contiene la celda es igual a la cantidad de celdas circundantes marcadas.

Marcar circundantes de una celda: Esta acción se realiza sobre una celda ya descubierta. El resultado es marcar todas las celdas circundantes no descubiertas. La acción se lleva a cabo, solamente si el número que contiene la celda es igual a la suma de la cantidad de celdas circundantes ya marcadas más las celdas circundantes no descubiertas sin marcar.

Descubrir una celda segura: Es una ayuda que solicita el jugador. El resultado es que una celda sin bomba se descubre. En general la solicitud de esta ayuda es penalizada de alguna manera por ejemplo sumando segundos (en este proyecto no tendremos en cuenta el tiempo empleado por el jugador)

3.3  Terminación


El juego termina cuando se da alguna de las dos siguientes situaciones:

Se descubre una celda que contiene una mina. En este caso el jugador pierde el juego.

Se descubrieron todas las celdas que no contienen minas. No importa si se marcaron o no todas las celdas con minas. En este caso el jugador gana el juego.
___________________________________________________________

4.  Arquitectura del sistema

El sistema que implementa el juego se construirá de acuerdo con la siguiente arquitectura:




Este es un modelo simple donde tenemos dos capas o módulos: la interfaz y el motor.

La interfaz se encarga de realizar el diálogo con el usuario (el jugador), capturar sus entradas e invocar las operaciones asociadas. La interfaz también maneja la imagen del juego en pantalla actualizándola cada vez que hay cambios. En resumen, se encarga de todo lo que tenga que ver con entrada y salida. La interfaz no realiza ninguna modificación directa sobre la estructura de datos.

El motor es el módulo que trata con la estructura de datos que representa el juego en un estado determinado. Este módulo estará compuesto por todos los subprogramas necesarios para ejecutar las acciones del jugador y reflejar estas en la estructura de datos. El motor no realiza ninguna operación de entrada y salida.

En este proyecto, el estudiante implementará solamente el motor. La interfaz será provista por los docentes, en este caso, por mí, que les daré los mismos archivos que dieron los docentes en su momento. En las siguientes secciones explicamos los detalles del módulo a ser implementado.
___________________________________________________________

5.  La estructura

La estructura de datos que representa el juego de buscaminas es la siguiente:

Código:
type
  TipoEstadoJuego = (jugando,ganado,perdido);
  TipoJuego = record
      estado       : TipoEstadoJuego; 
      tablero      : TipoTablero;
      bombas,                    (* cantidad de bombas en el tablero *)
      marcadas,                  (* cantidad de celdas marcadas *)
      descubiertas : integer;    (* cantidad de celdas descubiertas *)
  end;


El juego es un registro con los siguientes campos:

  • estado: Contiene el estado del juego en un momento dado.
  • tablero: el tablero con las celdas
  • bombas: cantidad de bombas en total en el tablero
  • marcadas: cantidad de bombas ya marcadas por el usuario
  • descubiertas: cantidad de celdas que están descubiertas


El tablero

El tablero se respresenta con la siguiente estructura:

Código:
RangoFila    = 1..MAX_FILAS;
   RangoColumna = 1..MAX_COLUMNAS;
   TipoTablero = record
      celdas  : array[RangoFila,RangoColumna] of TipoCelda;
      topeFila    : RangoFila;
      topeColumna : RangoColumna;
   end;


Esta estructura es una matriz (ver Arreglos Bidimensionales) con dos topes (ver array con tope). De esta manera se pueden representar tableros de diferentes tamaños. Las celdas válidas de la matriz son aquellas cuyas coordenadas (i,j) son tales:

• 1<= i <= topeFila
• 1<= j <= topeColumna

Las constantes MAX_FILAS y MAX_COLUMNAS se suponen definidas con valores apropiados. Estos valores están definidos en la interfaz, de manera que el estudiante no necesita conocerlos.

La celda

La celda se representa con la siguiente estructura:

Código:
TipoEstadoCelda = (oculta,marcada,descubierta);
   TipoCelda = record
      estado : TipoEstadoCelda;
      case tieneBomba :Boolean of
         True  : ();
         False : (bombasCircundantes :integer)
      end;


La información que tiene una celda es la siguiente:

  • estado : indica si la celda fue marcada, descubierta o continúa
  • oculta (cuando decimos oculta nos referimos a oculta y sin marca).
  • tieneBomba: es un booleano que vale true si y sólo si la celda contiene una mina.
  • bombasCircundantes: indica la cantidad de bombas que hay en las celdas circundantes. Este valor puede ser 0.


___________________________________________________________

6.  Los subprogramas

El motor del juego está constituido por un conjunto de subprogramas que trabajan sobre la estructura definida. En varios de los subrogramas se utiliza un parámetro que representa la posición de una celda dentro del tablero. Para ello necesitamos definir el siguiente tipo:

Código:
TipoPosicion = record
        fila   : RangoFila;
        columna:  RangoColumna;
   end;


Cualquiera de los subprogramas pedidos más abajo retorna sin ejecutar nada cuando recibe una posición no válida.

A continuación se describen los subprogramas que constituyen el motor del buscaminas:

Inicialización

Este subprograma es invocado al comienzo del juego para generar el tablero inicial.

Código:
procedure IniciarJuego(var juego: TipoJuego; cuantas_filas: RangoFila; cuantas_columnas: RangoColumna; cuantas_bombas: integer);


Los parámetros que recibe son:

  • cuantas_filas: cantidad de filas que va a tener el tablero
  • cuantas_columnas : cantidad de columnas que va a tener el tablero
  • cuantas_bombas: cantidad de bombas que va a tener el tablero


Este procedimiento debe retornar el parámetro juego configurado para iniciar el juego:

  • Todas las celdas quedan ocultas.
  • Las bombas se colocan al azar en tantas celdas como lo indique el parámetro cuantas_bombas. La colocación al azar se realiza utilizando la función random ya explicada en este curso.
  • Las celdas sin bombas deben tener el campo bombasCircundantes con el valor apropiado.
  • Los demás campos del juego (estados, contadores, topes, etcétera) se deben inicializar apropiadamente


En caso que el parámetro cuantas_bombas tenga un valor negativo o sea mayor que el número de celdas, el estudiante puede decidir el comportamiento del procedimiento.

___________________________________________________________

Descubrir una celda

Código:
procedure Descubrir(var juego: TipoJuego; posicion: TipoPosicion);


Esta operación realiza sobre el parámetro juego la acción de descubrir una celda tal como se describe más arriba. La celda a descubrir es la indicada por el parámetro posicion. En caso de que la celda ya esté descubierta, o la posición no sea válida, el procedimiento no hace nada.

Tener en cuenta que cuando se descubre una celda con 0 bombas circundantes, se produce automáticamente el descubrimiento de las celdas adyacentes para las cuales a su vez se aplica el mismo criterio. Esto puede provocar el descubrimiento de toda un área de celdas adyacentes, situación seguramente muy apreciada por el jugador.

En las versiones clásicas del buscaminas, esta operación se realiza con un clic con el botón principal sobre una celda no descubierta.

Marcar y Desmarcar

Código:
procedure Marcar(var juego: TipoJuego; posicion: TipoPosicion);
procedure DesMarcar(var juego: TipoJuego; posicion: TipoPosicion);


Estos dos procedimientos corresponden a las acciones de marcado y desmarcado de una celda tal como se describió en la sección Acciones Básicas.

En las versiones clásicas del buscaminas, esta operación se realiza con un clic con el botón secundario del ratón sobre una celda no descubierta.

Despejar Celdas Circundantes

Código:
procedure DespejarCircundantes(var juego: TipoJuego; posicion: TipoPosicion);


Este procedimiento corresponde a la acción Despejar Circundantes de una celda tal como se explicó en la sección Acciones Complementarias.

En las versiones clásicas del buscaminas, esta operación se realiza con un clic con el botón principal del ratón sobre una celda descubierta.

Marcar Celdas Circundantes

Código:
procedure MarcarCircundantes(var juego: TipoJuego; posicion: TipoPosicion);


Este procedimiento corresponde a la acción Marcar Circundantes de una Celda tal como se explicó más arriba.

Esta operación no está implementada en las versiones clásicas del buscaminas.

Descubrir Celda Segura

Código:
procedure DescubrirSegura(var juego: TipoJuego);


Este procedimiento corresponde a la acción Descubrir Celda Segura tal como se explicó más arriba.

Este operación no está implementada en las versiones clásicas del buscaminas.
___________________________________________________________

7.  Se pide

Escribir un archivo con todos los subprogramas que forman el motor del juego.

Los cabezales de los subprogramas deben coincidir exactamente con los que aparecen en esta letra. Si el estudiante realiza algún cambio se considerará que el subprograma no fue implementado.

Se puede utilizar todo en este curso y nada más.

La compilación y la ejecución se realizarán en línea de comandos. El comando de compilación se invocará de la siguiente manera:

Código:
fpc -Co -Cr programa.pas


Si trabaja con el IDE, asegúrese de configurarlo para que compile de la misma manera que el comando anterior (habilitación de range checking e Integer Overflow Checking).

No está permitido utilizar facilidades de Free Pascal que no forman parte del estándar y no se dan en el curso. Así por ejemplo, no se pueden utilizar ninguna de las palabras siguientes: uses, crlscr, gotoxy, crt, readkey, longint, string, break, etcétera.

Uses y ClrScr fueron mostradas por mí en este curso, sin embargo la interfaz gráfica se encarga del trabajo con la pantalla, por lo cual ustedes no necesitan usarlas.

En esta tarea como en todos los problemas de este curso, se valorará además de la lógica correcta, la utilización de un buen estilo de programación de acuerdo a los criterios impartidos en el curso. De esta manera, se hará énfasis en buenas prácticas de programación que lleven a un código legible, bien documentado y mantenible, tales como:

  • indentación adecuada
  • utilización correcta y apropiada de las estructuras de control
  • código claro y legible
  • algoritmos razonablemente eficientes
  • utilización de comentarios que documenten y complementen el código
  • utilización de constantes simbólicas
  • nombres mnemotécnicos para variables, constantes, etcétera.


_________________________________________________________

8.  Apéndices

Números randómicos

En free pascal se pueden generar números al azar utilizando la función random la cual ya fue explicada en este curso.

Guía para descubrir celda

El procedimiento Descubrir tiene algunas complejidades algorítmicas que requieren pensarlo con cuidado. En este apéndice damos algunas sugerencias para su implementación.

Si la celda a descubir contiene una bomba el juego termina. Si la celda a descubrir no contiene bomba y la cantidad de circundantes con bomba es mayor que cero, se descubre sólo esta celda y continúa el juego.

La situación más compleja surge cuando la celda no contiene bomba y la cantidad de circundantes con bomba es igual a 0. Para este caso sugerimos un algoritmo que permite explorar exhaustivamente el área circundante a descubrir.

Se utiliza una lista de posiciones de celdas que llamaremos la lista de pendientes. En esta estructura guardamos un conjunto de posiciones de celdas que aún nos resta procesar en el proceso de descubrir toda el área circundante. La implementación de esta estructura la dejamos a consideración del estudiante.

El algoritmo es el siguiente:

  • Poner el estado de la celda inicial como descubierta
  • Guardar posición de esta celda en lista de pendientes.
  • Repetir mientras la lista de pendientes no sea vacía.
    • Elegir una celda cualquiera de la lista de pendientes. Quitarla de la lista
    • Para cada una de sus celdas circundantes aún no descubiertas (pueden ser hasta 8) hacer lo siguiente:
      • Poner el estado en descubierta
      • Si el número de circundantes con bomba es 0, agregar la posición de esta celda a la lista de pendientes.



__________________________________________________________

Interfaz para el buscaminas

Introducción

Con el fin de poder probar en forma interactiva los procedimientos que se piden en este proyecto, se les brinda el siguiente código: buscaminas.pas, al cual le faltan los procedimientos que se piden implementar.

Ud. deberá implementar dichos procedimientos en el archivo motor.pas. Para que esto funcione, dentro del archivo buscaminas.pas se encuentra la siguiente directiva:

Código:
{$INCLUDE motor.pas}


Esto tiene el mismo efecto que copiar y pegar el contenido del archivo motor.pas dentro de buscaminas.pas en el lugar de dicha directiva.

Restricciones

El programa final que implemente el juego debería funcionar sin que Ud. tenga que modificar el archivo buscaminas.pas. Todos los procedimientos que se piden implementar en la letra del proyecto, como cualquier función, procedimiento, tipo, etc. extra que Ud. necesite definir deberá ser implementado en el archivo motor.pas.

Las directivas, procedimientos y funciones no estándar usadas en el archivo buscaminas.pas, fueron utilizadas con el fin de que Ud. tenga una interfaz más amigable. Sin embargo como es regla en este curso Ud. no puede utilizar facilidades de Free Pascal que no forman parte del estándar y que no se dan en el curso para implementar los procedimientos se piden, o cualquier otro subprograma extra que necesite.

Ud. no debe usar variable globales, toda la comunicación con la interfaz debe ser a través de los parámetros de los procedimientos.


Descripción de la interfaz

La interfaz básicamente tiene un cabezal, un tablero y una barra de estado. En el cabezal está el nombre del juego y se despliegan mensajes cuando el jugador ha ganado o perdido. En el tablero se pueden ver las celdas, que pueden estar ocultas (‘ # ‘), marcadas (‘ B ‘), o descubiertas vacías (‘ ‘), o indicando el número de bombas en las celdas circundantes (‘ 1′, ‘ 2 ‘, …, ‘ 8 ‘).

En la barra de estado se puede ver el nro. de fila y columna donde esta posicionado el jugador, la cantidad de celdas con bombas, cuantas están marcadas, cuantas están descubiertas, y la totalidad de las bombas que tiene el tablero.

Usando las flechas del teclado y algunas teclas se consigue probar y jugar al buscaminas. Por más información ver la ayuda que trae la interfaz, presionando la tecla “h” (de help en inglés).

Comunicación interfaz-motor

Invocación a IniciarJuego(…)

Cuando se inicia un juego nuevo seleccionando el nivel (fácil, intermedio, difícil), la interfaz invoca al procedimiento IniciarJuego(…) pasando como parámetros cierta cantidad de filas, columnas y bombas dependiendo de cada nivel.

Invocación a los procedimientos del motor

Cuando el usuario se posiciona sobre una celda determinada y presiona algunas de las teclas correspondientes a marcar, desmarcar, descubrir, etc. la interfaz invoca al procedimiento correspondiente pasando como parámetro el juego y la posición, salvo para “descubrir segura” en que se pasa sólo el juego.

Por lo tanto la comunicación entre la interfaz y el motor es usando sólo los parámetros de los procedimientos.

Funcionalidades

Aparte de poder jugar al buscaminas en forma interactiva, esta interfaz ofrece otras funcionalidades que le permitirán encontrar y corregir errores más fácilmente, por ejemplo:

  • Ver el tablero en “modo debug”. Presionando la tecla correspondiente muestra información oculta (bombas, cantidad de bombas en celdas circundantes) que un usuario jugando normalmente no puede ver. Luego cuando quiera puede volver al “modo normal”.
  • Volver atrás (o deshacer) una acción.
  • Guardar la configuración actual del juego en un archivo de texto.
  • Cargar la configuración de un juego desde un archivo de texto.
  • Guardar en un archivo texto el historial de las sucesivas configuraciones del juego y las acciones que se realizaron.



Recomendaciones

Para compilar

Cree una carpeta (o directorio) donde va a trabajar, descargue los archivos buscaminas.pas (que contiene la interfaz) y el motor.pas (que solo contiene los encabezados de los procedimientos) y cópielos a dicha carpeta.

Compile el archivo buscaminas.pas desde la línea de comandos con:

Código:
fpc -Co -Cr buscaminas.pas


o desde el IDE teniendo abierta la ventana con el archivo buscaminas.pas. El compilador se da cuenta automáticamente que tiene que incluir el código del archivo motor.pas donde está la directiva mencionada antes.

Esto ya va a generar una interfaz sencilla que no permite crear juegos nuevos, ni realizar acciones, pero sí cargar archivos con juegos de pruebas, como se explica a continuación. A medida que implemente los procedimientos, podrá realizar más acciones del juego.

Para probar usando la interfaz

Hasta que usted no implemente el procedimiento IniciarJuego(…), no va a poder generar sus propios tableros. Pero sí puede ir probando los otros procedimientos, por ejemplo cargando el juego desde uno de los archivo de ejemplo que le proporcionamos, e ir mirando en “modo debug” que todo funcione bien, o generando un historial y revisando el archivo del historial.

Al final habrá un enlace para descargar un archivo RAR que contiene todos los archivos que se mencionan a continuación incluyendo también el archivo buscaminas.pas y motor.pas.

A continuación se proporcionan algunos archivos generados desde la interfaz, los cuales se pueden cargar sin necesidad de implementar los procedimientos del motor.

  • juego1.txt
  • juego2.txt
  • juego3.txt
  • juego3-empezado.txt


A continuación se proporcionan algunos archivos con historiales de ejemplo. Los historiales contienen la secuencia de juegos que se generan a partir de un juego inicial y la aplicación sucesiva de acciones (como marcar, desmarcar, descubrir, etc.)

  • historial1.txt
  • historial2.txt
  • historial3.txt


Además Ud. puede probar los procedimientos implementando su propia interfaz, y/o pequeños programas para probar cada procedimiento por separado. Recuerde que lo que Ud. debe realizar son los procedimientos, la interfaz es simplemente una ayuda para probar y jugar con su motor.


Descarga de archivos

Para bajar los archivos necesarios para realizar este proyecto deben hacer click en el siguiente enlace:

DESCARGAR ARCHIVOS DEL PROYECTO.

Serán dirigidos a un servidor externo llamado NetLoad. Seleccionen la opción de descarga gratuita y podrán bajar el archivo RAR que contienen todo lo ya mencionado.

__________________________________________________________

1.  Introducción

Como parte de un proceso industrial, la fase de pruebas añade valor al producto generado. Todos los programas tienen errores (somos humanos) y la fase de pruebas los descubre. Ese es uno de los principales valores que añade. Recuerden que probar un programa es ejercitarlo con la peor intención con el fin de encontrarle fallas.

Además de las sugerencias en la definición de la Interfaz para el buscaminas referente a las pruebas, en este documento se les brindará una guía de cómo efectuar sus pruebas. ¡¡Así que a hincarle los dientes a esto que será de gran ayuda para ustedes!!

2.  ¿Cómo arman un puzzle?

En general, uno empieza por el borde, luego arma las partes más fáciles, las difíciles, y siempre, para cada parte, uno se va cerciorando que se está uniendo las piezas correctamente. Luego juntamos las partes prearmadas hasta llegar a la figura final.

2.1  ¿Por qué estamos viendo cómo armar un puzzle?

La idea de cómo armar un puzzle e implementar y probar el buscaminas tiene muchas similitudes. El borde y algunas partes ya están prearmados y testeados (buscamina.pas) y le pedimos que armen y testeen las partes faltantes (motor.pas) para completar el juego o “puzzle”. Parece una tarea fácil, ¿no?

Por lo tanto para probar su tarea deben tener en cuenta 3 puntos de prueba y en este orden:

  • Probar cada una de las partes armadas por ustedes por separado. O sea, cada subprograma o procedimiento por separado.
  • Probar que las partes encajan correctamente en lo que ya está armado. O sea, que al unir los subprogramas implementados por ustedes con los implementados por nosotros no generen errores.
  • Probar finalmente que todas las partes junto con el borde funcionan correctamente. O sea, nuestro puzzle es el que está en la imagen de la caja. Esto se hace probando desde la interfaz. Acá es dónde se pone más divertido, es hora de jugar.


Como bien dice la letra de la tarea “Ud. puede probar los procedimientos implementando su propia interfaz, y/o pequeños programas para probar cada procedimiento por separado. Recuerde que lo que Ud. debe realizar son los procedimientos, la interfaz es simplemente una ayuda para probar y jugar con su motor.

3.  Indicaciones y pautas a seguir para las pruebas

3.1  En los procedimientos:

Prueben todos los procedimientos por separado. Esta técnica les será de gran ayuda al momento de hacer la prueba desde la interfaz. Es decir, disminuirá significativamente la cantidad de errores que encontrarán y su gravedad. Pueden armarse un programa principal auxiliar que simplemente haga la llamada al procedimiento bajo prueba y luego imprima el resultado en pantalla para que puedan verificar la correctitud de su resultado. Recomendamos que piensen los casos de pruebas antes de empezar a probar y que los anoten en una planilla.

Recuerden que un caso de prueba se puede decir que está formado por entradas (en este caso, parámetros del procedimiento), un resultado esperado y un resultado obtenido. Además se puede agregar una descripción para entender rápidamente qué se está atacando.

La idea es que prueben lo que se les sugiere abajo. Si tienen algunas ideas más, no las descarten, úsenlas para probar, incluso en combinación con estas.

Pautas para los casos de prueba:

IniciarJuego

  • Diferentes dimensiones de tableros, chicos, medianos, grandes.
  • Casos límites en las dimensiones: máximo tablero (max_filas * max_columnas), mínimo tablero (1 x 1)
  • Diferentes densidades de bombas: muchas, pocas, etc.
  • Casos límites en bombas: tablero lleno, tablero vacío.
  • Verificar que todas las celdas quedan ocultas
  • Verificar que los contadores están bien calculados.



Descubrir

  • Diferentes estados de celda: oculta, descubierta, marcada.
  • Diferentes situaciones de celda oculta: con bomba, sin bomba, con 0 o más bombas circundantes.
  • Para el caso 0 circundantes probar diferentes áreas a despejar, con diferentes tamaños y formas.
  • Diferentes posiciones: bordes, esquinas, centrales. No olvidar posiciones inválidas.


DespejarCircundantes

  • Diferentes estados, situaciones, posiciones (como en el caso anterior)
  • Celdas que cumplen la condición para que se aplique el despeje y celdas que no la cumplen.
  • Situación que provoca pérdida del juego.
  • Situación que provoca despejar un área más grande por efecto de descubrir celdas con 0 circundantes.


Los otros procedimientos se deben verificar en situaciones similares.


3.2  Al integrar el motor.pas con el buscamina.pas:

Además de manejar bien las estructuras ya definidas, deben estar seguros que los datos que les llegan son los esperados por ustedes y los datos que devuelven son los esperados por el buscamina.pas. En otras palabras deben verificar que están tomando correctamente los datos que les pasan por parámetro y devolviéndolos correctamente también.

3.3  En el juego, desde la interfaz:

Esta es la última. Si hicieron bien las pruebas anteriores no deberían tener muchos errores en esta etapa. Les sugerimos que para esta parte lo que más deben hacer es jugar. Recuerden que la intención debe ser encontrar fallas y no salteárselas. Lo mejor es enfocarse en buscar cierto tipo de errores durante varias partidas seguidas. Piensen que tienen una misión, encontrar errores, entonces por varias partidas ponen el foco en buscar ciertos errores, por ejemplo, descubrir casillas sin bombas y ver que se descubren toda la zona que se debe descubrir. Es importante que se guarden los historiales de cada partida, así cuando ocurre un error, pueden reproducirlo. Esto les servirá al momento de verificar que hayan arreglado el error. Les podrá ser útil anotar en una planilla la correspondencia entre los errores y los archivos de historial. En las misiones, pueden intercalar los distintos niveles de tablero de la interfaz, o alguno armado por ustedes.

4.  Indicaciones útiles

Cuando utilicen casos de prueba:

  • Ejecuten todos los casos de prueba y anoten sus resultados antes de comenzar la revisión de los que fallaron. Esto les facilitará el trabajo.
  • A la hora de empezar la revisión de los casos que fallaron. Se puede seguir estos pasos:
    • Revisar la formulación del caso de prueba. Puede que esté mal el caso y no sea el programa.
    • Si el caso de prueba es correcto, se pasa a detectar qué parte del código está generando la falla. Esto lo pueden hacer Debugueando por ejemplo.

  • Cuando hayan arreglado todos los errores, ejecuten los casos de prueba que en un principio no dieron error. Esto es para asegurarse que los cambios hechos no introdujeron errores en lo que andaba bien.


Algunas indicaciones más para cuando prueben desde la interfaz:

  • Al igual que con los casos de prueba, ejecuten varias misiones, las que ustedes crean convenientes, antes de empezar a corregir las fallas.


_________________________________________________________

5.  Un poco más de testing

5.1  Conceptos de testing manejados en esta guía:

  • Testing Unitario (probar cada parte por separado)
  • Testing de Integración (probar cómo encajan las partes entre sí)
  • Testing de Sistema o Caja Negra (probar que el puzzle armado es igual al de la imagen en la caja).

__________________________________________________________


6.  Cómo probar los subprogramas por separado

Puede hacerse directamente desde la interfaz utilizando las facilidades de cargar un juego desde un archivo, se puede lograr la configuración que se desea. También se recomienda utilizar el modo *depuración* (tecla X) para poder ver el contenido de las celdas ocultas.

Otra posibilidad es hacer programas auxiliares que se encarguen de cargar un juego en particular y verificar cada subprograma del motor de manera aislada. Para ello se recomienda utilizar un esquema como el que sigue:

Código:
cargar juego
    llamar subprograma
    mostrar juego


Este programa se puede ejecutar varias veces cargando diferentes juegos y llamar el subprograma con diferentes parámetros cubriendo todas las situaciones que parezcan interesantes.

Para poder aplicar lo anterior necesitamos un procedimiento que cargue un juego de un archivo y otro que lo muestre.

Código:
procedure cargarJuego(nombre : string ; var juego :TipoJuego);

procedure mostrarJuego(juego :TipoJuego);


Por ejemplo para probar el procedimiento Descubrir sobre todas las posibles celdas de un tablero, se podría hacer algo así:

Código:
for i:= 1 to juego.tablero.topeFila do
    for j:= 1 to juego.tablero.topeColumna do
    begin
       cargarJuego('juego.txt',juego);
       posicion.fila:= i;
       posicion.columna:= j;
       descubrir(juego,posicion);
       mostrarJuego(juego);
       readln; (* pausa *)
    end;


De manera similar se pueden probar todos los subprogramas del motor.

El código de los subprogramas auxiliares cargarJuego y mostrarJuego lo pueden descargar aquí:

Testing Buscaminas Auxiliares.

---------------------------------------------------------------------------------

Mucha suerte con este proyecto. Estaré a su disposición para ayudarles en todo lo que necesiten. Soy consciente de su dificultad y espero que lo emprendan. Es muy interesante lo que se proponen aquí.

Saludos a tod@s l@s que han seguido este curso, y sobretodo, muchas gracias.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Martes 10 Ene 2012 19:25

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

profesor es posible generar un tablero en la interfaz con solo el procedimiento IniciarJuego?

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Martes 10 Ene 2012 19:53

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

sucede que al compilar el archivo buscaminas.pas me dice que no reconoce la variable juego:tipojuego, declarada en un procedimiento dentro de motor.pas; no entiendo a que se deberá ya que ese tipo de variable está efectivamente declada en buscaminas.pas.

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Martes 10 Ene 2012 20:14

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Amigo Floyd, como podrás ver difieren los subprogramas descritos en la letra con los que hay en el archivo. Pues he subido el motor del juego iguales y no el del buscaminas. Por suerte eso no es problema porque los encabezados de los subprogramas están en la letra. Menos mal que el archivo que genera la interfaz gráfica es el correcto.

Corregiré ese error cuanto antes.

Saludos y gracias por detectar esa errata.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Jueves 12 Ene 2012 00:08

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

entendido, muchas gracias Kyshuo!

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Jueves 12 Ene 2012 20:22

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Profesor aunque aún no sé exactamente como probar el procedimiento IniciarJuego con la interfaz, es el único que he redactado y me gustaria verificar si distribuye el numero de bombas correctamente y si a cada celda sin bomba se le asigna el valor correcto de bombas circundantes. ¿si es posible hacerlo? porque al tratar de compilar me pide los demás procedimientos que aún no tengo listos.
Para probar la lógica empleada en ese primer procedimiento he tenido que redactar un código análogo y verificar dichos datos sin interfaz. Aqui está el código de dicho programa por si hay alguna sugerencia:
Código:
PROGRAM tabla_prueba1;

uses crt;
const N=9;

type
tabla= array[1..N,1..N] of integer;

var i,j: integer;
    NumBombas: integer;
    matriz: tabla;
    opcion: char;
//****************************************
procedure randomCeldas(var tablero:tabla; bombas:Integer);
var i,j: integer;
    contBombas: integer;

Begin
if (Bombas>0) and (Bombas<=N*N) then
 begin
 contBombas:=0;
 repeat
 i:=random(N)+1;
 j:=random(N)+1;
 if tablero[i,j]<>1 then
  begin  {evita repetir celda}
 tablero[i,j]:=1;
 contBombas:=contBombas+1;
  end;
until ContBombas=NumBombas;
 end;
End;
//***************************************
FUNCTION Position(fila,columna: integer):Boolean;
var i,j,f: integer;
begin
IF ( (fila<=0) or (fila>N) ) then
i:=0
else
i:=1;

IF ( (columna<=0) or (columna>N) ) then
j:=0
else
j:=1;

f:=i+j;
Position:=(f=2);
end;
//*****************************************
FUNCTION bCircundantes(tablero:tabla;fila,columna:integer):integer;
var fil,col,circun:integer;
begin
circun:=0;
for fil:=fila-1 to fila+1 do
begin
 for col:=columna-1 to columna+1 do
  begin
  if ((position(fil,col)) and (tablero[fil,col]=1) )then
     circun:=circun+1
  else
  circun:=circun;
  end;
end;//end for fil
bCircundantes:=circun;
end;
//****************************************

BEGIN
clrscr;
randomize;

REPEAT

write('numero bombas: ');
readln(NumBombas);
writeln;

for i:=1 to N do
 for j:=1 to N do
 matriz[i,j]:=0; {esqumema para ocultar toda celda}


 randomCeldas(matriz,NumBombas);


for i:=1 to N do
 begin
 for j:=1 to N do
 write(matriz[i,j]);
 writeln;
 end;
writeln;
writeln('VERIFICANDO BOMBAS CIRCUNDANTES');
write('digite fila: ');
readln(i);
writeln;
write('digite columna: ');
readln(j);
j:=bCircundantes(matriz,i,j);
write('bombas circundantes = ',j);
writeln;
write('seguir? S/N: ');
readln(opcion);
writeln;

UNTIL (ord(opcion)= 78) or (ord(opcion)=110);

END.

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Jueves 12 Ene 2012 20:28

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

las bombas están representadas con '1' y las celdas vacias con '0'. Entonces bombas circundantes es el numero de 1´s que hay al rededor de una celda cuyas coordenadas se digita en la salida estándar del programa.
Para el caso de las celdas que valgan 1 el numero de bombas circundantes incluye ese mismo 1, estoy conciente que eso sería un error para buscaminas peor tambien es claro que bombas circundantes solo se aplica a las celdas sin bombas, es solo una prueba a lo lógica.... GRACIAS KYSHUO!!

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Viernes 13 Ene 2012 18:48

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Al parecer está todo bien, pero no lo sabremos del todo hasta probar el juego andando.

Para poder compilar simplemente pon todos los encabezados de los procedimientos dados en la letra y ponles a cada uno un BEGIN y un END a los que no les pondrás ninguna instrucción, es decir, no será un bloque vacío hasta que los vayas programando.

De ese modo no podrás usar las funcionalidades no programadas pero podrás utilizar la interfaz y si presionas alguna tecla que llame a alguno de esos procedimientos pues no pasará nada.

Saludos.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Viernes 13 Ene 2012 20:19

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Acabo de probar el procedimiento y al parecer hace todo lo que debe: todas las celdas ocultas, la colocación al azar y el número de bombas correctamente, el valor de cada celda sin bomba de circundantes... lo probé en modo debug y con los distintos niveles. Ahora al procedimiento de descubrir. Por cierto Kyshuo para el segundo procedimiento necesito declarar un tipo nuevo (así lo concibo hasta ahora y así lo sugiere la letra) para guardar la lista de celdas cuyo número de bombas circundantes es 0 (cero), pero tengo la duda si es estrictamente necesario ya que el ejercicio reta a no modificar el archivo buscaminas.pas .

Cita:
Se utiliza una lista de posiciones de celdas que llamaremos la lista de pendientes. En esta estructura guardamos un conjunto de posiciones de celdas que aún nos resta procesar en el proceso de descubrir toda el área circundante. La implementación de esta estructura la dejamos a consideración del estudiante.

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Viernes 13 Ene 2012 20:35

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Pues no estarás modificando el archivo, ya que dicho tipo debe ser declarado dentro del procedimiento, es decir, es un tipo local, no estarás declarando un tipo global como hemos hecho hasta ahora.

Su uso no es frecuente, como puedes observar, esta es la primera vez que surge algo por el estilo. Pero no olvides que los subprogramas respetan la misma estructura que el programa principal, es decir, puedes declarar CONSTANTES, TIPOS, VARIABLES y demás.

Espero que esto responda a tu pregunta.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Viernes 13 Ene 2012 20:41

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Genial! precisamente estuve repasando la teoría de los subprogramas para despejar la duda, debí deducirlo jejej; es muy bueno que el ejercicio me vaya enseñando más a medida que lo realizo.
Gracias Kyshuo y claro que quedó todo claro! Ok

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
Sebastián Marcos
Usuario Inquieto


Registrado: 04 Oct 2011
Mensajes: 133

Mensaje Publicado: Viernes 13 Ene 2012 22:51

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Hola a todos !!!
He iniciado el trabajo con este proyecto, sin duda que el hecho de que los tiempos aquí no apremien como en la facultad es una ventaja.

Bueno, mi pregunta es concreta, y tal vez un tanto inocente... Tengo la parte de código que distribuye las bombas en el tablero al azar, ¿debo previamente inicializar todas las celdas con tieneBomba:=false? .(previamente a la distribución, digo). En ese caso, ¿que valor le asigno a "bombasCircundantes"?. Creo que esta inicialización sería lo correcto antes de la distribución, para luego si, según dónde quedaron colocadas empezar a contar las celdas con bomba que limitan con aquellas que no tienen.
Gracias a todos.
Saludos.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Sábado 14 Ene 2012 02:38

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Digamos que eso no es requisito del sistema ni mucho menos, sino que forma parte de una decisión del implementador, o sea, tú.

Inicializar todo el tablero para luego distribuir implica una doble recorrida. Sin embargo, el ir colocando a medida que avanzamos puede complicar el código en vano...

¿Qué es mejor? Pues lo deciden ustedes según sus necesidades. En lo que a mí respecta tienen la libertad de hacerlo como más les guste.

No se si eso te ayuda jeje.

Saludos.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
sr floyd
Usuario Activo


Registrado: 05 Sep 2011
Mensajes: 196

Mensaje Publicado: Lunes 16 Ene 2012 00:06

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

profesor y para finalizar el juego,es decir, para que juego.estado:=ganado sea efectivo desde qué procedimiento se hace?¿desde iniciarjuego ó de eso se encarga la interfaz?,la duda la tengo porque en ninguno de los procedimientos se menciona de forma directa al menos.
Gracias Kyshuo.
P.D.: le ando haciendo pruebas a Descubrir Reir

Volver arriba
Ver perfil del usuario Enviar mensaje privado MSN Messenger
Kyshuo Ayame
Moderador Global


Registrado: 07 Ene 2011
Mensajes: 1035

Mensaje Publicado: Lunes 16 Ene 2012 14:02

Título del mensaje: Re: Proyecto Final: Juego Buscaminas

Responder citando

Pues cuando se descubren todas las celdas que no tienen bombas....

¿Dónde controlarás eso????

Dime tu opinión y veremos si estás en lo correcto o no.

Volver arriba
Ver perfil del usuario Enviar mensaje privado
Responder al Tema Ir a página 1234Siguiente
Mostrar mensajes anteriores:   
Ir a:  
Todas las horas están en GMT + 2 Horas

Temas relacionados

Tema Autor Foros Respuestas Publicado
El foro no contiene ningún mensaje nuevo

Agregar un volante al juego F1 2018

Miguelinho53 Programación de juegos o videojuegos 0 Domingo 11 Nov 2018 17:34 Ver último mensaje
El tema está bloqueado: no pueden editarse ni agregar mensajes.

Solicito programadores para mi proyecto

alexpin Bolsa de trabajo 0 Miércoles 23 May 2018 22:53 Ver último mensaje
El foro no contiene ningún mensaje nuevo

resultado separado por comas y al final un punto

pegomezca Python 0 Lunes 23 Oct 2017 11:19 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Duda codigo en Python - Red Neuronal con numpy ...

Daniel_wUNTG Python 1 Sábado 21 Oct 2017 22:27 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Ayuda con error script - Juego Online

streaming77 Java 5 Miércoles 04 Oct 2017 21:10 Ver último mensaje
Panel de Control
No puede crear mensajes, No puede responder temas, No puede editar sus mensajes, No puede borrar sus mensajes, No puede votar en encuestas,