Estás en:   ArielOrtiz.info > Fundamentos de programación > Proyecto: Desliza números

Proyecto: Desliza números

Objetivos

Durante esta actividad, los alumnos serán capaces de:

Esta actividad promueve las siguientes habilidades, valores y actitudes: análisis y síntesis, capacidad de resolver problemas, creatividad, y uso eficiente de la informática y las telecomunicaciones.

Descripción de la actividad

Este proyecto puede ser elaborado de manera individual o en parejas.

Desarrollar en Python 3.5 una aplicación que implemente el juego de Desliza números, el cual es parecido, mas no idéntico, a otros juegos como Threes!, 1024 y 2048.

Requisitos

Ejemplo

En esta liga se puede ver un ejemplo completo de una corrida completa del programa con varios juegos.

¿Qué se debe entregar?

Tu programa debe estar en un solo archivo llamado desliza_numeros.py e incluir en la parte superior un comentario con nombre y matrícula de los autores, por ejemplo:

# Autores: 
#          A01166611 Pepper Pots
#          A01160611 Anthony Stark
#
# Descripción del programa.
#
# 7 de mayo, 2017.

    .
    . (El resto del programa va aquí)
    .

✔ Instrucciones para subir archivo

Para entregar el archivo desliza_numeros.py, ingresa los siguientes datos:

Solicitar NIP

Si el proyecto fue desarrollado por un equipo de dos personas, basta que una persona lo entregue.

Fecha límite: Domingo, 7 de mayo.

Reglas del juego

Inicio del juego

Desliza números se juega en una cuadrícula de cuatro renglones por cuatro columnas. Inicialmente la cuadrícula está vacía excepto por un número 1 que está dispuesto en una posición aleatoria dentro de la cuadrícula. En el siguiente ejemplo dicho 1 está en la posición (2, 0):

+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|    1 |      |      |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+

Selecciona una opción ([A]rriba, a[B]ajo, [I]zquierda, [D]erecha, [S]alir):

Realizando un tiro

El usuario tiene la opción de efectuar sus tiros en cuatro diferentes sentidos: arriba, abajo, izquierda o derecha (tecleando, respectivamente, las teclas «a», «b», «i» y «d» seguido de la tecla «Enter»). También puede terminar el juego seleccionando la tecla «s».

Cuando el usuario realiza un tiro todos los números de la cuadrilla intentarán deslizarse en el sentido seleccionado. Si el usuario selecciona «d» (derecha) en el ejemplo anterior, el único número presente en la cuadrícula se desliza a la casilla (2, 1). Adicionalmente, siempre después de un tiro no nulo el programa añade aleatoriamente un número 1 a alguna casilla que esté desocupada (en la posición (0, 3) en el siguiente ejemplo):

+------+------+------+------+
|      |      |      |    1 |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|      |    1 |      |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+

Un número no se puede deslizar si la casilla destino se encuentra ocupada (salvo que se vaya a fusionar como se explica más adelante) o si está en la orilla de la cuadrícula y el movimiento solicitado implica salirse de ésta. Por ejemplo, en la cuadrícula de arriba el número en la posición (0, 3) se queda en esa misma posición si se hace un tiro hacia arriba o hacia la derecha. Sin embargo el número en la posición (2, 1) puede deslizarse sin problema en cualquiera de los cuatro sentidos, ya que todos las casillas aledañas están desocupadas.

Fusionando números

Supongamos que ahora el usuario selecciona «a» (arriba) y que el nuevo número 1 queda en la posición aleatoria (0, 2):

+------+------+------+------+
|      |      |    1 |    1 |
+------+------+------+------+
|      |    1 |      |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+

Cuando un número se intenta deslizar hacia una casilla ocupada pero con su mismo valor, ambos números se fusionan en la casilla destino con la suma de sus valores. Si el usuario ahora selecciona «d» (derecha) los números en las posiciones (0, 2) y (0, 3) se fusionan dejando un 2 en la posición (0, 3). El número 1 de la posición (1, 1) se desliza a la posición (1, 2) y el nuevo 1 se coloca aleatoriamente en la posición (3, 1):

+------+------+------+------+
|      |      |      |    2 |
+------+------+------+------+
|      |      |    1 |      |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|      |    1 |      |      |
+------+------+------+------+

Veamos una situación más compleja. Suponiendo que después de muchos tiros nuestra cuadrícula se ve así:

+------+------+------+------+
|      |    1 |      |      |
+------+------+------+------+
|    1 |    2 |    1 |    1 |
+------+------+------+------+
|    1 |    8 |    1 |      |
+------+------+------+------+
|    8 |    4 |    4 |      |
+------+------+------+------+

Si el usuario selecciona «i» (izquierda) entonces los números 4 en las posiciones (3, 1) y (3, 2) se fusionan en un 8 en la posicion (3, 1); por otro lado, los números 1 en las posiciones (1, 2) y (1, 3) se fusionan en un 2 en la posicion (1, 2); así mismo, el número 1 en la posición (0, 1) se desliza a la posición (0, 0); ningún otro número se puede deslizar; finalmente, el nuevo número 1 queda aleatoriamente en la posición (0, 2):

+------+------+------+------+
|    1 |      |    1 |      |
+------+------+------+------+
|    1 |    2 |    2 |      |
+------+------+------+------+
|    1 |    8 |    1 |      |
+------+------+------+------+
|    8 |    8 |      |      |
+------+------+------+------+

Si el usuario ahora selecciona «b» (abajo) entonces los números 8 en las posiciones (2, 1) y (3, 1) se fusionan en un 16 en la posición (3, 1); los números 1 en las posiciones (1, 0) y (2, 0) se fusionan en un número 2 en la posición (2, 0); el número 1 de la posición (0, 0) se desliza a la posición (1, 0) que recién quedó desocupada; el número 2 de la posición (1, 1) se desliza a la posición (2, 1) que también recién quedó vacía; todos los elementos de la columna 2 se deslizan una localidad hacia abajo; y por último, el nuevo número 1 queda en la posición (1, 3):

+------+------+------+------+
|      |      |      |      |
+------+------+------+------+
|    1 |      |    1 |    1 |
+------+------+------+------+
|    2 |    2 |    2 |      |
+------+------+------+------+
|    8 |   16 |    1 |      |
+------+------+------+------+

Tiros nulos

Si al efectuar un tiro no se produce cambio alguno en la cuadrícula se dice que ha realizado un tiro nulo. Por ejemplo, supongamos que tenemos la siguiente cuadrícula:

+------+------+------+------+
|    4 |    2 |    2 |    8 |
+------+------+------+------+
|    1 |    1 |      |    4 |
+------+------+------+------+
|      |      |      |    1 |
+------+------+------+------+
|      |      |      |      |
+------+------+------+------+

Si el usuario selecciona «a» (arriba) se produce un tiro nulo, ya que la cuadrícula no cambia de forma alguna. En otras palabras, el tiro no provocó que algún número se deslizara o que un par de números se fusionaran. Cuando esto sucede, el programa debe imprimir un mensaje indicando que el tiro fue nulo y además no debe añadir un nuevo número 1 en una posición aleatoria.

Finalización del juego

El juego termina cuando no existe forma de hacer un tiro no nulo en todos los sentidos. Por ejemplo, la siguiente cuadrícula no permite hacer ningún tipo de tiro:

+------+------+------+------+
|    2 |    4 |   16 |    1 |
+------+------+------+------+
|    1 |    8 |   32 |    4 |
+------+------+------+------+
|    2 |    4 |   16 |   32 |
+------+------+------+------+
|    1 |    2 |   32 |    4 |
+------+------+------+------+

En otras palabras, un juego finaliza cuando la cuadrícula no tenga casillas en blanco ni tampoco tenga dos o más números consecutivos iguales en un mismo renglón o columna.

Alternativamente, un juego puede terminar en cualquier momento si el usuario selecciona la opción «s» (salir).

Puntaje

El programa debe desplegar el puntaje del usuario cuando un juego termina, no importando si fue porque ya no había tiros posibles o porque seleccionó la opción de salir. El puntaje se calcula sumando todos los números presentes en la cuadrícula.

Consejos de implementación

Determinando si existe un archivo

La función exists del módulo os.path devuelve true si un cierto archivo existe, o false en caso contrario.

Ejemplo de uso:

from os.path import exists

if exists('archivo.txt'):
    print('El archivo sí existe')

Obteniendo la fecha y hora

Para obtener la fecha y hora del sistema se puede usar la función strftime del módulo time. La función recibe una cadena de formato y devuelve una cadena con la información solicitada.

Ejemplo de uso:

from time import strftime

fecha_y_hora = strftime('%Y-%m-%d %H:%M:%S')
print(fecha_y_hora)

Algoritmo de deslizamiento y fusión a detalle

Veamos detalladamente cómo ocurre un tiro hacia arriba:

  1. El renglón 0 queda sin cambio, pues está en la orilla de la cuadrícula y ningún número se puede deslizar hacia afuera.
  2. Se revisa cada casilla c del renglón 1:
    • Si c no está vacía y la casilla de arriba de c está desocupada, entonces se copia el elemento en c al renglón de arriba en la misma columna y c se deja vacía.
    • Si el elemento contenido en c es un número que además es igual al de la casilla de arriba, entonces se guarda el doble del contenido de c en la casilla del renglón de arriba en la misma columna y c se deja vacía.
  3. Se repite el paso 2 para los renglones 2 y 3 de la cuadrícula.

Para los tiros de abajo, izquierda y derecha se sigue un procedimiento similar.