Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Enunciado]
Se pide hacer una aplicación que permita jugar al juego Rectángulos que es
una variante del siguiente juego:
[Link]
El juego representa un conjunto de bloques de distintos colores de forma que
el usuario debe eliminar el mayor número posible de bloques. Para eliminar un
conjunto de bloques hay que seleccionar un rectángulo de forma que las 4 esqui-
nas de dicho rectángulo contengan un bloque del mismo color.
Haremos una versión modificada de este juego. En nuestra versión el juego se
basará en un tablero rectangular de casillas. El tablero se rellenará aleatoriamente
tal como se muestra en la siguiente figura:
Figura 1: Ejemplo de tablero inicial
Habrá dos jugadores que van eliminando bloques de forma alternativa y su-
mando puntos. Para seleccionar un rectángulo, los jugadores deben indicar la es-
quina superior izquierda y la esquina inferior derecha de dicho rectángulo. Si el
rectángulo elegido es correcto (las 4 esquinas son del mismo color), se procederá
a realizar la jugada que consiste en eliminar todos los bloques del rectángulo, su-
mar al jugador los puntos correspondientes en función del tamaño del rectángulo
y generar bloques nuevos en los espacios vacı́os dejados por el rectángulo elimi-
nado del tablero.
La Figura 2 muestra el proceso para realizar una jugada. Todos los pasos antes
descritos dan lugar a un funcionamiento recurrente que debe implementarse con
una secuencia iterativa:
1. Seleccionar un rectángulo indicando la esquina superior izquierda y la es-
Página 1 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
Figura 2: Ejemplo de jugada: (izquierda) el jugador elige la esquina superior iz-
quierda y la esquina inferior derecha del rectángulo, (centro) se borra el rectángu-
lo y se suman los puntos al jugador, y (derecha) se rellena el hueco dejado
quina inferior derecha del rectángulo.
2. Eliminar los bloques del rectángulo elegido.
3. Sumar los puntos al jugador en función del número de bloques eliminados
(10 puntos por cada bloque eliminado).
4. Generar nuevos bloques para rellenar el espacio dejado por el rectángulo
eliminado.
Para hacer el juego más interesante y aumentar un poco la dificultad vamos
a implementar la opción de que uno de los jugadores pueda ser la máquina. El
juego dará la posibilidad, antes de iniciarse, de que el jugador decida si quiere
enfrentarse a la máquina o no. Si elige la opción de enfrentarse a la máquina, el
jugador será el “Jugador 1” y la máquina jugará como “Jugador 2”. En caso de no
enfrentarse a la máquina, el juego asumirá que ambos jugadores son humanos y
por tanto efectuará las jugadas seleccionadas por ambos jugadores.
Página 2 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
Algunas otras consideraciones que debe cumplir el juego son las siguientes:
Inicio. Al iniciarse la partida, el juego debe permitir a los jugadores ele-
gir los siguientes parámetros: dimensiones del tablero (filas y columnas),
número de jugadas de la partida, si va a enfrentarse a la máquina o van a
jugar dos jugadores humanos y el nivel de la máquina en caso de que el
Jugador 2 sea el ordenador.
Colores. El tablero solamente podrá tener bloques de un número fijo de
colores. En los ejemplos de este documento se ha utilizado un juego con 2
colores: rojo y azul, tal como muestran las figuras de los ejemplos. Es decir,
el número de colores puede ser un dato fijo y no es necesario que pueda ser
variable. En cualquier caso se recomienda un número bajo de colores (2-3),
porque sino es posible que no se generen muchas jugadas válidas.
Tablero. El tablero tendrá unas dimensiones (no de filas y columnas) que
podrán decidirse al iniciarse el juego. Para ello es necesario que el construc-
tor de la clase que implemente el juego (y que debe ser el método encargado
de crear e inicializar el tablero) tenga al menos dos parámetros para indicar-
le las dimensiones del tablero.
Inicialización del tablero. Un elemento que puede resultar novedoso es ini-
cializar el tablero asignando a todas las casillas su correspondiente bloque
de un color. Esto se puede realizar fácilmente mediante números aleatorios.
Por ejemplo, se puede hacer usando el método [Link]() que gene-
ra un número aleatorio entre 0 y 1. Para decidir el color del cuadrado, se
puede sacar un número aleatorio que decida entre los colores disponibles
de forma que todos ellos sean equiprobables. Un ejemplo del uso de núme-
ros aleatorios se realizó en las prácticas con el programa que permitı́a jugar
al juego Piedra, papel y tijera, o en la clase estática que implementaba un
Dado.
Realización de jugadas. Los jugadores irán realizando jugadas seleccionan-
do un rectángulo. Para ello indicarán la esquina superior izquierda y la es-
quina inferior derecha del rectángulo. Si ambas esquinas no dieran lugar
a un rectángulo válido (porque alguna de las 4 esquinas no fuera del mis-
mo color), el juego debe indicar que el rectángulo elegido no es correcto,
permitiendo al jugador seleccionar un nuevo rectángulo.
Puntuación. Los jugadores irán sumando puntos con cada jugada que de-
penderán de los bloques que se hayan eliminado. Por cada bloque elimina-
do sumarán 10 puntos.
Visualización de la partida. El juego mostrará tras cada jugada el estado del
tablero, ası́ como la puntuación de ambos jugadores y el número de jugadas
restantes. Se debe mostrar el tablero tras cada variación que se produzca en
el mismo, es decir, tras los siguiente eventos:
Página 3 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
1. Tras borrar los bloques del rectángulo al hacer una jugada. Es decir,
que se visualice el hueco dejado al borrar el rectángulo.
2. Tras rellenar el hueco dejado al borrar el rectángulo.
Esto permitirá comprobar que el juego funciona correctamente. Ver ejemplo
en la Figura 4.
Fin de la partida. El juego finaliza cuando ambos jugadores hayan realizado
cada uno el número de jugadas elegido al iniciarse la partida. La aplicación
mostrará un mensaje indicando el fin de la partida y el jugador que ha ga-
nado o si ambos jugadores han empatado. A partir de ese momento ya no
se podrán efectuar nuevas jugadas.
Figura 3: Fin del juego
Página 4 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Opciones para realizar la práctica]
Hay dos opciones para realizar la práctica:
1. Aplicación de consola: la puntuación máxima siguiendo esta opción es de
8 puntos.
2. Aplicación gráfica: la puntuación máxima en este caso es de 10 puntos.
En cualquiera de las dos opciones, la parte de implementar el jugador máqui-
na valdrá 3 puntos.
[Aplicación de consola]
Se jugará a través de la consola, mostrando el estado del tablero mediante una
representación basada en caracteres. A cada color se le puede asignar una letra,
por ejemplo en el caso de usar 3 colores, siguiendo sus respectivas iniciales en
inglés (para evitar duplicados), tendrı́amos rojo (’R’), verde (’G’) y azul (’B’). Las
casillas que se han eliminado se pueden representar, por ejemplo, mediante el
carácter ’-’. Las jugadas se leerán de teclado, indicando el jugador la posición de
las casillas elegidas en cada jugada mediante sus coordenadas.
En las imagen siguiente aparece un ejemplo de funcionamiento de la aplica-
ción de consola:
Página 5 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
Filas: 6
Columnas: 8
Jugadas: 5
Jugar contra la Maquina (SI/NO): SI
Nivel (1 principiante/2 medio/3 experto/4 maestro): 4
1 R B R B R B B R
2 R B R R R R R B
3 B R R B R B B B
4 B R B R B B B B
5 B B R B R B B R
6 B R B B B B R B
1 2 3 4 5 6 7 8
Puntos: Jug1 0 Jug2 0 Jugadas restantes 5
Turno Jug1, Casilla elegida #1, fila y columna? 1 3
Turno Jug1, Casilla elegida #2, fila y columna? 5 8
1 R B - - - - - -
2 R B - - - - - -
3 B R - - - - - -
4 B R - - - - - -
5 B B - - - - - -
6 B R B B B B R B
1 2 3 4 5 6 7 8
Puntos: Jug1 300 Jug2 0 Jugadas restantes 5
1 R B B R R B B B
2 R B B R B B R R
3 B R B B R B R B
4 B R R B R R B R
5 B B R R R B R R
6 B R B B B B R B
1 2 3 4 5 6 7 8
Puntos: Jug1 300 Jug2 0 Jugadas restantes 5
Turno Jug2, Casilla elegida #1, fila y columna? 1,3
Turno Jug2, Casilla elegida #2, fila y columna? 6,8
1 R B - - - - - -
2 R B - - - - - -
3 B R - - - - - -
4 B R - - - - - -
5 B B - - - - - -
6 B R - - - - - -
1 2 3 4 5 6 7 8
Puntos: Jug1 300 Jug2 360 Jugadas restantes 4
1 R B B B B R B R
2 R B B B B R B R
3 B R R B R B R B
4 B R R R B R B B
5 B B R R R R B R
6 B R R B R R R R
1 2 3 4 5 6 7 8
Puntos: Jug1 300 Jug2 360 Jugadas restantes 4
Figura 4: Funcionamiento de la aplicación de consola
Página 6 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Aplicación gráfica]
Se jugará a través de una ventana gráfica mostrando el estado del tablero me-
diante una representación similar a la que aparece en las figuras que describen el
juego al inicio de este documento.
Las jugadas se leerán mediante clicks de ratón, pinchando el jugador prime-
ro el bloque de la esquina superior izquierda y luego el de la esquina inferior
derecha.
Aunque la aplicación sea gráfica, se debe mostrar por la consola el estado del
tablero tras cada operación (eliminado de piezas, relleno) de forma que se pueda
comprobar que el juego funciona correctamente. Hacer que la visualización del
tablero se detenga tras cada uno de esos momentos NO es trivial y NO se pide.
Si algún grupo desea hacerlo, puede consultar el documento [Link] que se su-
ministra con este enunciado. En el se indica cómo manejar timers en aplicaciones
gráficas. Los grupos que hagan una aplicación de consola NO deben hacer nada
de esto.
Cuando la partida acabe se mostrará por pantalla una ventana indicando el
jugador que ha ganado la partida (ver Figura 3).
Página 7 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Pistas para implementar el jugador máquina]
La jugada de la máquina se debe basar en calcular para cada bloque del table-
ro cuál es el mayor rectángulo posible que tiene como esquina superior izquierda
dicho bloque. Repitiendo ese proceso para todos los bloques de la matriz, se pue-
de obtener lo bueno que es cada bloque como esquina superior izquierda y con
ello la puntuación de todas las jugadas posibles. Por ejemplo, la puntuación de
cada casilla en el tablero de la imagen serı́a la que se muestra en la matriz de la
parte inferior, donde la primera lı́nea y el primer número de cada lı́nea represen-
tan respectivamente los números de las columnas y de las filas.
1 2 3 4 5 6 7 8
1 40 30 30 18 9 6 4 5
2 32 30 25 20 5 12 5 4
3 18 6 24 20 4 4 2 4
4 24 21 18 15 4 2 1 3
5 8 12 6 8 3 3 2 1
6 8 7 6 5 1 3 2 1
Figura 5: Ejemplo de cálculo de la puntuación de cada jugada posible para imple-
mentar el jugador máquina
A partir de ese cálculo es sencillo implementar varios niveles del jugador
máquina. Se pide implementar cuatro niveles:
1. Nivel maestro: la máquina elige siempre la mejor jugada posible. Se trata de
coger simplemente la jugada de mayor puntuación. En el ejemplo anterior
serı́a la jugada con 40 bloques que tiene como esquina superior izquierda el
bloque que está en la primera fila, primera columna.
Página 8 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
Para el resto de niveles (experto, medio y principiante), el proceso ya no será
determinista, sino que la máquina elegirá la jugada al azar pero teniendo en cuen-
ta la puntuación de las jugadas posibles. Por ejemplo:
1. Nivel experto: la máquina elige al azar una jugada que tenga al menos el
60 % de la puntuación máxima. Si por ejemplo la puntuación máxima es 40,
entonces las jugadas posibles deben tener al menos 24 puntos.
2. Nivel medio: la máquina elige al azar una jugada que tenga al menos el
40 % de la puntuación máxima. Si por ejemplo la puntuación máxima es 40,
entonces las jugadas posibles deben tener al menos 16 puntos.
3. Nivel principiante: la máquina elige al azar una jugada que tenga al menos
el 20 % de la puntuación máxima. Si por ejemplo la puntuación máxima es
40, entonces las jugadas posibles deben tener al menos 8 puntos.
Página 9 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Normas]
1. Se debe seguir el paradigma de la Programación orientada a objetos, es de-
cir, se debe escribir una clase que implemente el juego y un programa que
emplee dicha clase para realizar la aplicación.
2. El programa debe ser original. Si se detecta cualquier tipo de copia, de cual-
quier fuente o procedencia, los integrantes del grupo o los grupos que se
vean implicados suspenderán la asignatura. Suspende también los alum-
nos que pasan la práctica, no solamente los que la copian.
3. Cada grupo, formado por un máximo de 3 alumnos, debe entregar en un
documento zip lo siguiente:
Una memoria en formato pdf de no más de 4 páginas en el que se
expliquen brevemente los aspectos más destacables de la aplicación
realizada. En concreto se deben explicar:
a) La descripción de las clases empleadas.
b) La forma de representar el tablero y de colocar las fichas.
c) Los esquemas iterativos empleados para realizar el juego.
d) (Muy Importante) Una lista con todos aquellos elementos que no
funcionen en la aplicación. Por ejemplo, si la aplicación no puede
hacer alguna de las partes del programa descritas anteriormente,
se debe indicar en la memoria.
e) Los aspectos extra que se hayan implementado, si es que existe
alguno (aunque no son necesarios).
f ) NO se deben incluir listados de la aplicación en la memoria.
Otro fichero zip con los ficheros .java que componen la aplicación.
[Se valorarán los siguientes aspectos]
Que se empleen las metodologı́as de programación que se han estudiado
durante el curso. Por ejemplo en cuanto al diseño de clases y de esquemas
iterativos.
La eficiencia del programa.
Los comentarios incluidos en el programa, Javadoc y normales.
La claridad y sencillez del código.
Hora y fecha lı́mite de entrega: las 8:59 horas del dı́a 10 de Enero de 2023. La
entrega se debe hacer a través del Campus Virtual en la Tarea que se habilitará al
efecto (basta con que la suba un alumno del grupo).
Página 10 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
[Ejemplo de aplicación para capturar los clicks de ratón]
Lo que sigue a continuación es el código fuente de las dos clases que integran
el proyecto Tablero que se suministra con este enunciado: la clase Tablero que
puede servir de base para la implementación del juego, y la clase TestTablero
que constituirı́a el programa principal. Si se ejecuta tal como se suministra, el
programa captura los click del ratón e indica en un cuadro de diálogo la posición
(en pixeles) donde se produjo el click.
En el fichero [Link] se encuentra implementado mediante la clase
privada MouseHandler la manera de detectar los clicks de ratón y las coordena-
das donde se producen.
La forma de mostrar cuadros de diálogos ([Link])
se estudió en las sesiones prácticas de la asignatura. Para dibujar cuadrados se
puede utilizar el método fillRect(), para dibujar lı́neas puede emplearse el
método drawLine() y y para escribir textos drawString(). Todos esos méto-
dos con un objeto de la clase Graphics como se muestra en el siguiente ejemplo.
[Link]
1 import [Link];
2 import [Link];
4 public class TestTablero {
6 public static void main(String[] args) {
7 Tablero t = new Tablero();
9 JFrame app = new JFrame(”Tablero”);
11 String entrada= [Link](”Filas:”);
12 int filas =[Link](entrada);
14 String salida=[Link](”Has elegido %d filas”, filas ) ;
15 [Link](null, salida);
17 [Link]([Link] ON CLOSE);
18 [Link](0, 0, 440, 470);
19 [Link](t);
20 [Link] (true) ;
21 }
22 }
[Link]
1 import [Link];
Página 11 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
2 import [Link];
3 import [Link];
4 import [Link];
5 import [Link];
6 import [Link];
7 import [Link];
10 public class Tablero extends JPanel {
12 //Aquı́ irı́an los atributos necesarios
14 //Constructores
15 Tablero() {
16 //El constructor debe tener los parámetros oportunos
17 //para inicializar el tablero y el juego
19 // Añadimos el ’escuchador’ de ratón
20 addMouseListener(new MouseHandler());
21 }
23 //Métodos de la clase que implementan el juego: básicamente hacer una
24 //jugada, dibujar el estado del tablero y comprobar si la partida se acabó
26 //Método paint
27 public void paintComponent(Graphics g) {
28 [Link](g);
30 //Aquı́ irı́a el código para pintar el estado del tablero
32 // Pintar rectángulo
33 [Link]([Link]);
34 g. fillRect (10, 10, 40, 40) ;
36 // Pintar lı́nea
37 [Link]([Link]);
38 [Link](55, 10, 55, 80) ;
40 // Pintar un texto
41 Font fuente = new Font(”Arial”, [Link], 20);
42 [Link](fuente) ;
43 [Link]([Link]);
44 [Link](”Texto”, 10,100);
45 }
Página 12 de 13
Práctica en Grupo de Introducción a la Programación
Curso 2022-2023
47 //Clase privada para capturar los eventos del ratón
48 private class MouseHandler extends MouseAdapter {
49 public void mouseClicked (MouseEvent e) {
50 //Mostramos un diálogo con la posición del ratón
51 //para ver un ejemplo de cómo se obtienen las coordenadas
52 //donde se produjo el click
53 [Link](null, [Link](”Ratón %d
, %d \n”,[Link](),[Link]()));
55 //Aquı́ irı́an las instrucciones para comprobar si el
56 //click del ratón se produjo en una posición correcta
57 //y hacer la jugada correspondiente
59 //Se pueden llamar a los métodos públicos de la clase
61 //Seguramente habrá que repintar el tablero si se realizó
62 //una jugada válida
63 repaint () ;
64 }
65 }
66 }
Página 13 de 13