• No se han encontrado resultados

Proyecto I (15%) Simulación del Juego Solitario

N/A
N/A
Protected

Academic year: 2022

Share "Proyecto I (15%) Simulación del Juego Solitario"

Copied!
9
0
0

Texto completo

(1)

Universidad Simón Bolívar

Departamento de Computación y Tecnología de la Información Algoritmos y Estructuras II (CI2616)

Enero-Abril 2003

Proyecto I (15%)

Simulación del Juego Solitario

El proyecto se desarrollará en tres etapas correspondientes a los pretalleres y talleres de las semanas 6 (12-16 Mayo), 7 (19-23 Mayo) y 8 (26-30 Mayo). El informe final deberá ser entregado el lunes 26 de Mayo (el lunes de la semana 8) por todos los equipos de estudiantes (tanto del lunes como del miércoles).

Enunciado:

Se desea que usted diseñe e implemente un programa en JAVA que permita jugar al Solitario utilizando las estructuras de datos vistas en la clase de teoría. En particular, el uso de los TAD pilas serán de gran utilidad para alcanzar la solución deseada.

En la Sección I de este documento encontrará los detalles del juego y sus reglas. Se sugiere que el estudiante utilice la versión del juego disponible bajo el ambiente Windows para que aclare cualquier duda sobre su funcionamiento. En la Sección II se incluyen las instrucciones para realizar las actividades que le servirán de guía durante el proceso de implementación de este programa.

I. Descripción del Problema

El Juego Solitario es un juego de cartas disponible en la mayoría de los PCs con ambiente Windows. El objetivo del juego es el de remover de forma ordenada todas las cartas dispuestas en el tablero.

Para lograr esto el jugador dispone de siete (7) mazos de filas (filas verticales) en el tablero donde deberá colocar las cartas de forma temporal y en orden descendente. En otra sección del tablero dispone de los cuatro (4) mazos de palos que corresponden a los palos de la baraja (diamantes, corazones, tréboles, picas) y que inicialmente están vacías. En ellas irá colocando las cartas de cada palo en orden ascendente y de esta forma se llega al fin de la partida.

Inicialmente el jugador cuenta con un cúmulo de cartas denominado mazo mano donde las cartas están boca arriba y ordenadas al azar. Para empezar el juego, se reparten las cartas sobre el tablero de izquierda a derecha de la siguiente forma: 1 carta en el mazo de filas 1, 2 cartas en el mazo de filas 2, 3 cartas en el mazo de filas 3, y así sucesivamente hasta 7 cartas en el último mazo de filas. Todas las cartas de cada mazo de filas se colocan boca abajo con excepción de la última que se coloca boca arriba.

En la primera jugada, el jugador intenta mover las cartas entre los mazos de filas y mazos de palos y si esto no es posible entonces descubre la primera carta del mazo y trata de ubicarla en alguno de los mazos de filas y palos. Si no es posible colocarla

(2)

entonces la deposita en un mazo temporal donde irá colocando boca arriba todas aquellas cartas que no ha logrado colocar en el resto de los mazos. La siguiente vez repite el procedimiento y así sucesivamente hasta que todas las cartas hayan sido organizadas por palos y en orden ascendente, desde el As hasta el Rey, en los mazos de palos correspondientes o hasta que no sea posible realizar más movimientos.

1. Reglas del Juego

Para mover las cartas de un lugar a otro sobre el tablero es necesario seguir las siguientes reglas:

Cualquier carta que está boca arriba en cualquier mazo está disponible para moverse.

En los mazos de filas las cartas están ordenadas en forma descendente, hasta un máximo de 12 cartas descubiertas por fila. Las cartas cubiertas están ordenadas al azar y cada fila dispone inicialmente de numeroDeFila -1 cartas volteadas.

Si todas las cartas volteadas de un mazo fila son removidas, la carta boca abajo que esté más superficial se debe voltear.

En los mazos de filas podemos colocar cartas del mismo palo pero de diferente color (se alternan las cartas rojas con las cartas negras).

Para mover cartas entre mazos de filas se toma la carta que está en la última posición y se traslada a la última posición de la siguiente fila.

Es posible trasladar múltiples cartas entre mazos de filas si ya están ordenadas.

Una vez que el mazo mano queda vacío es posible voltear el mazo temporal y trasladarlo al mazo mano para continuar jugando.

2. Tips para Jugar

(3)

Antes de iniciar un nuevo mazo de filas:

Mover las cartas entre mazos de filas cuando sea posible para liberar tantos mazos de filas como sea posible.

Iniciar mazos de filas para poder destapar nuevas cartas. Sólo puede iniciarse un nuevo mazo de filas con un Rey.

Si hay dos o más cartas que pueden colocarse en un mazo de filas, hacer el movimiento que resulte en voltear una nueva carta boca arriba. Si ningún movimiento resulta en una carta boca arriba, hacer el movimiento que resulte en más movimientos.

II. Implementación

1. Estructuras de Datos

Los componentes principales de este juego son el tablero, las cartas y los mazos. El primer paso para lograr la implementación de este problema, consistira en la seleccion de las estructuras de datos para representar estos objetos.

Se sugiere utilizar la siguiente convención de nombres:

palo – Conjunto de nombres que indica la familia a la que pertenece una carta (diamantes, corazones, tréboles, picas).

rango – Conjunto de nombres y números que van desde el As hasta el Rey.

Carta - El nombre de la clase que representa una carta.

carta - Variable que representa un objeto de la clase Carta.

TableroDeCartas – Nombre de la clase que contiene los objetos de la clase Carta.

tableroDeCartas - Variable para representar el tablero de juego sobre el cual se barajan las cartas y se realizan los movimientos de cartas entre mazos.

mazoMano - Contiene inicialmente todas las cartas de la baraja organizadas en forma aleatoria y colocadas boca abajo.

mazoFilas - Las 7 filas verticales donde se colocan las cartas antes de pasar a los mazos de palos.

mazoPalos - Las 4 pilas de cartas, una para cada palo, ordenadas en forma ascendente.

mazoTemporal - Contiene las cartas que se toman del mazo para descubrirlas, es decir, colocarlas boca arriba.

1.1 Objeto Carta y Paquete de Cartas

Los principales atributos de este objeto serán el valor de la carta, con valores [0...12]

que corresponden al rango [As...Rey], y la pinta con valores [0...3] para los palos de [diamantes, corazones, tréboles y picas] respectivamente. Esta asociación valor – rango y pinta – palos puede implementarse dentro de la clase carta utilizando un arreglo estático y definiendo los métodos necesarios para obtener la conversión entre valores y nombres.

(4)

En relación a los métodos se requerirán funciones para asignar y obtener el valor y la pinta de una carta, determinar si una carta es de color rojo o negro y cuándo dos cartas son del mismo color.

Así, la clase carta vendría dada por:

class Carta () {

public int valor;

public int pinta;

public int obtenerValor() {

return valor;

}

public int asignarValor (int v) {

valor = v;

}

public int obtenerPinta() {

return pinta;

}

public int asignarPinta (int p) {

pinta = p;

}

public boolean esRoja () {

return (pinta == diamantes ¦¦ pinta == corazones) }

public boolean esNegra () {

return (pinta == picas ¦¦ pinta == tréboles}

}

public boolean mismoColor (Carta c) {

return ((this.pinta == diamantes ¦¦ this.pinta == corazones) &&

(c.pinta == diamantes ¦¦ c.pinta == corazones) ...

...

} }

Una vez definida la clase Carta podemos entonces definir la clase paqueteDeCartas para agrupar las 52 cartas de la baraja y realizar operaciones sobre ellas. Los métodos que se requieren sobre este objeto son los siguientes:

• Un método para crear e inicializar la estructura que contiene las cartas de la baraja, es decir, el paquete de cartas, asignando a cada una de estas cartas un valor (0 ...

12) y una pinta (0..3) y disponiéndolas al azar.

• Un método que permita obtener una carta del paquete de cartas.

(5)

• Un método para barajar las cartas (disponerlas al azar).

ACTIVIDAD 1: completar estas funciones prototipo e implementar la clase Carta y paqueteDeCartas. Ver el código para estas clases en [1] (disponible en la biblioteca).

1.2 Objeto Mazo

Para representar los mazos del tablero, el TAD pila se ajusta bastante bien a las caraterísticas de estos objetos. En particular, se tienen cartas que entran y/o salen por el extremo de cada montón. Para manejar esta estructura se requieren funciones que permitan meter un elemento en la pila (empilar), sacar un elemento de la pila (desempilar), encontrar el primer elemento de la pila y vaciar la pila. Así, la clase pilaDeCartas vendría dada por:

class pilaDeCartas () {

public String nombre;

public Carta[] cartas;

public int contador;

public void empilar (Carta c) {

if (c != null)

cartas[contador++] = c;

}

public Carta desempilar () {

return cartas[--contador];

}

public Carta tope () {

return cartas[contador - 1];

}

public void vaciar () {

contador = 0;

}

ACTIVIDAD 2: completar estas funciones prototipo e implementar la clase pilaDeCartas.

Los mazos del tablero pueden entonces definirse haciendo uso de la estructura pilaDeCartas.

En el caso particular de los mazos de filas se sugiere utilizar una estructura de datos tipo pila para las cartas boca abajo colocadas en las 7 filas al inicio del juego y otra estructura de datos tipo secuencia para manejar las cartas boca arriba disponibles en las 7 filas sobre las cuales se realizan los movimientos. De esta forma se simplifica el manejo de las estructuras y se evita tener una estructura de datos de mayor complejidad donde es necesario hacer inserciones intermedias.

(6)

ACTIVIDAD 3: definir e implementar las estructuras de datos para los mazos fila, mazo temporal y mazo de palos.

1.3 Objeto Tablero de Cartas

Finalmente el tablero de juego se define como una clase tableroDeCartas que es un conjunto de objetos de las clases pilaDeCartas, etc.

Para manejar esta estructura se requieren los siguientes métodos:

• Un método para crear e inicializar los mazos del tablero (mazo filas, mazo palos, mazo temporal, mazo mano) con longitud inicial igual a cero (0).

• Un método para repartir las cartas en los mazos filas tal y como se indicó en la descripción del juego: 1 carta en el mazo de filas 1, 2 cartas en el mazo de filas 2, 3 cartas en el mazo de filas 3, y así sucesivamente hasta 7 cartas en el último mazo de filas. Finalmente se colocan las cartas sobrantes en el mazo mano.

ACTIVIDAD 4: definir e implementar los métodos y atributos de la estructura de datos correspondiente al tablero de juego tableroDeCartas.

2. Algoritmo General

Un primer nivel de la solución para implementar el juego anteriormente descrito vendría dado por el siguiente algoritmo:

crearTablero;

do jugada != vacío ->

jugadaEnTablero;

od

Donde la acción de jugadaEnTablero es un método del tablero que viene dado por dos operaciones a realizar sobre el tablero que son: encontrar la jugada y mover las cartas.

El siguiente paso para avanzar en la solución de nuestro problema consistiría en definir un algoritmo para estas dos operaciones principales. Veamos en qué consiste cada uno de estos subproblemas.

2.1 Encontrar jugada

Este subproblema será quizás el de mayor complejidad debido a las verificaciones que deberán realizarse. Se deben chequear entonces todos los posibles movimientos que pueden o no hacerse sobre el tablero:

De mazo temporal a mazo palo

De mazo fila a mazo palo

De mazo fila a mazo fila

De mazo temporal a mazo fila

Así, necesitaríamos métodos para chequear si desde un mazo particular podemos mover cartas a un mazo palo o a un mazo fila, como sigue:

(7)

boolean puedoMoverAMazoFila () {Pre: ...}

{Post: ...}

boolean puedoMoverAMazoPalo () {Pre: ...}

{Post: ...}

De acuerdo a las reglas del juego, para realizar movimientos al mazo fila debe verificarse que la carta origen y la carta destino sean de diferente color y que el valor de la carta origen sea uno menos que el valor de la carta destino. Si la carta destino no tiene valor, estaríamos en presencia de una fila vacía, en cuyo caso sólo una carta origen de valor Rey podría ser movilizada.

De la misma forma, para mover una carta al mazo palo debemos verificar que la carta fuente sea superior en valor por una unidad a la carta destino, teniendo en cuenta que el As es la primera carta que se coloca en cada mazo palo. Este es el caso en que la carta fuente tendría valor As y la carta destino no tendría valor definido.

ACTIVIDAD 5: definir e implementar los métodos puedoMoverAMazoFila y puedoMoverAMazoPalo.

Finalmente, podemos definir el método para encontrar la jugada de la siguiente manera:

Jugada encontrarJugada () {

public Jugada jugada;

// Chequear de mazo temporal a mazo palo if puedoMoverAMazoPalo ()

return jugada;

fi

// Chequear de mazo fila a mazo palo if puedoMoverAMazoPalo ()

return jugada, fi

// Chequear de mazo fila a mazo fila if puedoMoverAMazoFila ()

return jugada, fi

// Chequear de mazo temporal a mazo fila if puedoMoverAMazoFila ()

return jugada, fi

return jugada = null;

}

En este punto nos damos cuenta de que es necesario definir una estructura para manejar el resultado del método encontrarJugada de forma tal que se conozca el mazo origen y el mazo destino sobre los cuales se realizará el movimiento de cartas. Esta nueva estructura recibirá el nombre de Jugada y se deja al estudiante la tarea de definirla.

(8)

ACTIVIDAD 6: definir e implementar el método encontrarJugada y la estructura Jugada.

2.2 Mover cartas

A este nivel se actualizan las estructuras de datos según el resultado obtenido con el método encontrarJugada. Sabiendo que el mazo origen y el mazo destino son ya conocidos y están representados por la estructura Jugada el método moverCartas podría definirse como un método de esta clase.

ACTIVIDAD 7: escribir la especificación para el método moverCartas.

3. Interfaz Gráfica

Las cartas deben mostrarse por pantalla utilizando formato texto. Por ejemplo: 5C para el 5 de corazones, KT para el Rey de tréboles, AD para el As de diamantes, y así sucesivamente.

Para cada jugada el programa deberá mostrar la disposición de las cartas sobre el tablero, indicando además en un mensaje el movimiento de cartas realizado. Por ejemplo: | carta -> AD | origen -> mazo fila 1 | destino -> mazo palo |. Esto facilitará la comprensión del juego ya que el formato texto ofrece una visión poco clara de las cartas y los movimientos realizados.

5. Informe

Se requiere que entregue un informe utilizando el formato que se indica en la página web del curso, con énfasis en la discusión e inclusión de los siguientes puntos:

Diseño

• Resultado del análisis descendente del problema.

Implementación

• Descripción de las estructuras de datos.

• Estructura del código.

• Guía del usuario.

• Código fuente documentado de acuerdo a las normas publicadas en el material de apoyo de la materia. Recuerde incluir la precondición y poscondición para cada función de su programa.

6. Entregas

Primera Entrega (12 - 16 Mayo): 2%

1. Cada equipo deberá tener lista las estructuras de datos para representar las cartas y el paquete de cartas, así como las operaciones requeridas sobre cada una de ellas.

(9)

2. Presentar el esqueleto del programa que obtuvo aplicando análisis descendente para obtener una primera versión de la solución.

3. Implementar la interfaz gráfica para mostrar por pantalla el contenido de las estructuras de datos.

Segunda Entrega (19 -23 Mayo): 3%

1. Para la segunda entrega se requiere que obtenga una representación para los mazos y el tablero junto con las operaciones asociadas a estos elementos.

2. Presentar la implementación de los subproblemas identificados en la primera etapa utilizando análisis descendente.

Tercera Entrega (26 - 30 Mayo): 10%

1. Entregar la versión operativa del programa en JAVA que permita jugar el Juego Solitario.

2. Durante la revisión se verificará el funcionamiento del programa y se harán preguntas a ambos miembros del equipo.

.

7. Referencias

[1] Horstman, C. S. y Cornell, G., Core Java Fundamentals V. 1.2, Vol. I, Capítulo 4:

Objetos y Clases, Prentice Hall.

Referencias

Documento similar

DECORA SOLO LAS IMÁGENES QUE NECESITES PARA LLEGAR AL NÚMERO CORRESPONDIENTE... CEIP Sansueña/CEIP Juan XXIII Infantil

Las personas solicitantes deberán incluir en la solicitud a un investigador tutor, que deberá formar parte de un grupo de investigación. Se entiende por investigador tutor la

Respecto a las enfermedades profesionales, en virtud del RD 1299/2006, de 10 de noviembre, por el que se aprueba el cuadro de enfermedades profesionales en el sistema de

Pero antes hay que responder a una encuesta (puedes intentar saltarte este paso, a veces funciona). ¡Haz clic aquí!.. En el segundo punto, hay que seleccionar “Sección de titulaciones

Este aspecto higiénico es, por lo tanto, otro aspecto facilitador de esta popula- ridad social de la que gozó la actividad y que lo llevó a ser «un juego que conocen todos los

Imparte docencia en el Grado en Historia del Arte (Universidad de Málaga) en las asignaturas: Poéticas del arte español de los siglos XX y XXI, Picasso y el arte español del

(29) Cfr. MUÑOZ MACHADO: Derecho público de las Comunidades Autóno- mas, cit., vol. Es necesario advertir que en la doctrina clásica este tipo de competencias suele reconducirse

De esta manera, ocupar, resistir y subvertir puede oponerse al afrojuvenicidio, que impregna, sobre todo, los barrios más vulnerables, co-construir afrojuvenicidio, la apuesta