Adivina el numero - Juegos con Python
Hola a todos. En el presente artículo les propongo crear otro sencillo juego, haciendo uso del modulo “random” (del que ya hablé en un artículo anterior) de python. En este caso se trata de crear un juego en el que el usuario ha de “adivinar” un número “escogido” previamente por la computadora (dentro de un rango que vendrá determinado por el nivel de dificultad escogido previamente), de modo aleatorio, mientras que se van contando los “intentos” del jugador hasta dar con el número acertado. Como ayuda en cada “intento”, nuestro programa le irá indicando a nuestro usuario si se está acercando o, si por el contrario, se está alejando de la solución. E aquí un ejemplo de nuestro programa:
Para empezar (como ye es habitual) empezaremos importando aquellos módulos que contengan las funciones que vamos a necesitar:
De este modo importamos el modulo “random” (que contiene las funciones encargadas de proporcionarnos ciertos datos de forma aleatoria), el modulo “subprocess” que emplearemos para limpiar la pantalla después de cada “partida”. Finalmente, del modulo “VALID” (cuyo desarrollo explico en este enlace: https://www.pythondiario.com/2018/01/creando-calculadoras-del-tiempo-2-el.html) importaremos las funciones “OKI” y “ns” cuyos códigos reproduzco a continuación para aquellos que no tengan dicho modulo:
Una vez que tenemos los módulos que vamos a necesitar, empezaremos con el desarrollo de nuestro programa. Tal y como he señalado más arriba, el rango en el que se va a encontrar el número a adivinar, dependerá del nivel de dificultad que previamente daremos a elegir a nuestro usuario/jugador (de modo que cuanto más elevado sea dicho nivel de dificultad, mayor será el rango en el que se encontrará nuestro número). Así daremos a elegir dicho nivel, mostrando primero los niveles posibles (niveles 1, 2, 3 y 4) y a continuación, pidiendo al usuario (mediante un input) que escoja el nivel que desea (dicha elección la almacenaremos en una variable a la que llamaremos “level”):
Aquí vemos como la variable “level” almacenará el número correspondiente al nivel de dificultad escogido por el jugador. Sobre el input que introduzcamos para “level” se aplicará la función “OKI” que en su momento creamos para asegurarnos de que el usuario solo pueda introducir números enteros.
Sin embargo, en este caso no nos vale con cualquier número entero. Esto es así en la medida de que al ser 4 los niveles de dificultad posibles, el número que introducirá el jugador ha de estar también en dicho rango (entre 1 y 4, ambos inclusive). Es por ello por lo que a continuación, escribimos la instrucción de que se continúe pidiendo el nivel de dificultad, mientras el número introducido sea distinto de 1, 2, 3, y 4:
Una vez escrito la parte del programa orientada a la selección (por parte de usuario) del nivel de dificultad, tenemos que hacer que la computadora “escoja” al azar, un número, el cual se encontrará dentro del rango definido por el nivel de dificultad. Para ello, haremos uso de la función “random.randint” la cual nos genera, de forma aleatoria, un número, el cual, se encuentra dentro de un rango previamente definido. Para ver cómo funciona esta función, veremos un sencillo ejemplo:
En el ejemplo hemos creado una variable (“num_azar”) la cual, nos devuelve en cada ejecución, un valor numérico, el cual se encuentra dentro del rango que expresamos entre paréntesis (en este caso, entre 0 y 10). Obteniendo de ese modo, 9, en la primera ejecución, 8 en la segunda y 0 en la tercera.
Este es, pues, el método que vamos a emplear para establecer el número a elegir por el jugador. Sin embargo, antes de continuar, debemos recordar que el rango que emplearemos para generar el número a adivinar, estará en función del nivel previamente escogido (de modo que el rango tendrá un valor mínimo de 0 y uno máximo de 100, 1000, 10000, 100000 en función de si el nivel escogido es de 1, 2, 3 y 4 respectivamente). Con dicho fin, vamos a crear una variable (a la que llamaremos “MAX”) la cual definirá dicho máximo en función del nivel previamente escogido. Así tenemos:
Lo que hemos hecho aquí ha sido buscar una fórmula que a partir de un dato establecido de antemano (en este caso, la variable “level”) nos de uno de los máximos establecidos pensados para cada nivel. De esta manera, una vez que tenemos el máximo para el rango correspondiente al nivel que hayamos elegido, el número a adivinar lo almacenaremos en una variable a la que daremos el nombre de “numero_elegido”.
Una vez que tenemos el número que debe adivinar el jugador, es hora de iniciar el juego, pidiendo al usuario que introduzca un número perteneciente al rango correspondiente para el nivel escogido. También en este bloque crearemos las variables cuyo valor irá cambiando dentro del ciclo “while” que emplearemos para el desarrollo del juego. Así tenemos:
Así vemos como, después de haber definido nuestro “numero_elegido”, creamos la variable “intentos”, la cual irá contando el número de veces que tengamos que introducir número antes de dar con el resultado. También crearemos la variable “diferencia”, la cual emplearemos para calcular la diferencia (que habiendo uso de “abs” nos aseguraremos de que sea siempre un valor positivo) entre el número que introduzcamos en cada intento y el número que debemos adivinar (lo cual nos proporcionará el criterio para, en cada intento, informar al jugador de si se está acercando a la solución o no). Por su parte usaremos la variable “repes” para el caso de que el jugador introduzca dos o más veces seguidas el mismo número.
Para empezar a pedir al jugador que introduzca un número usaremos una variable a la que daremos el nombre de “tu_numero”.
Para ello escribimos: “tu_numero= (limites (OKI (input (“Escribe un número comprendido entre”+Di+”: “)), MAX)).En donde “Di” no es más que una variable que almacena el formato en el que vamos a presentar los límites del rango (“Di=(" 0 y "+str(MAX))”) y donde la función “limites” (que aplicamos sobre el input introducido por el usuario y toma la variable “MAX” como argumento) se encargará de evitar que nuestro jugador pueda introducir un número que se encuentre fuera del rango previsto para el nivel del que se trate. Esta función tendremos que haberla definido antes y será la siguiente:
La función “limites” toma como argumentos el input introducido por el jugador (del que, mediante la función “OKI”, nos habremos asegurado de que sea un número entero) y el número más alto dentro del rango del nivel seleccionado (“MAX”). De modo que mientras dicho input sea menor de 0 y mayor del número correspondiente a la variable “MAX”, nos aparecerá un mensaje de error en el que se nos pedirá que ingresemos un número comprendido entre 0 y dicho número máximo, tal y como se muestra abajo.
Una vez introducido el número por parte del jugador por primera vez (y después de haber de haber contabilizado nuestro primer intento, mediante “intentos+=1”) entraremos en un ciclo (“while”) el cual repetirá (en principio) mientras que el número introducido por el usuario sea distinto del numero que tengamos que adivinar (“while tu_numero!=numero_elegido: “). Así tendremos:
Este bloque de programa describe lo que tendrá que suceder cada vez que el jugador introduzca un nuevo número. Básicamente el procedimiento que seguimos es el siguiente:
-
Mediante la variable “tu_numero”, el usuario introduce un nuevo número en su búsqueda de la respuesta correcta.
-
En el caso de que la distancia entre el número introducido y el número que haya que adivinar sea mayor de 0 (o lo que es lo mismo: no coincidan). Pasaremos a distinguir dos nuevas posibilidades.
-
La primera de tales posibilidades es que el número anterior que hayamos introducido (“num_anterior”) sea diferente del que acabemos de introducir en ese momento (“tu_numero”). En cuyo caso pasaremos a mostrar un mensaje en el que se nos indicará si nos estamos alejando o acercando al número a adivinar (esto lo haremos en función de si la diferencia “actual” entre “tu_numero” y “numero_elegido”, con signo positivo, es mayor o menor a la variable “diferencia”, la cual es igual a esa misma diferencia, solo que referida al intento anterior al actual).
-
Por su parte, para el caso de que “num_anterior” (variable que se actualiza en cada ejecución del ciclo) sea igual al número introducido actual (“tu_numero”), incrementaremos en 1 la variable “repes” y mostraremos un mensaje en el que avisaremos al jugador de que ha introducido el mismo número “repes” veces seguidas.
-
Finalmente, completado cada ciclo actualizaremos las variables “num_anterior” (que pasará a equivaler a “tu-numero”) y la variable “intentos” cuyo valor incrementaremos en 1.
Hasta aquí, hemos visto el modo de ir introduciendo números hasta dar, finalmente, con la solución. Sin embargo, de este modo podría suceder que un jugador pudiese ir probando uno a uno todos los números del rango. Para evitar esto (y para darle más emoción a nuestro juego) vamos a limitar el número posible de intentos para acertar nuestro número. De ese modo añadiremos a nuestro ciclo, el siguiente bloque:
De modo que en el momento en el que el número de “intentos” acumulados sea igual a la mitad del límite máximo (es decir: la mitad del rango), nos aparecerá un mensaje en el que se nos comunicará que hemos rebasado el límite, junto con el mensaje de cuál era la solución. Acto seguido se finalizará la ejecución del ciclo mediante una sentencia “break”.
El último supuesto (que daba por finalizado el ciclo) era aquel en el que el número introducido (“tu_numero”) y el número a adivinar (“numero_elegido”) coincidieran quedaría expresado de este modo:
En este caso, mostraremos un mensaje de victoria junto con la expresión del número de intentos (expresados con la variable “intentos”) que hemos necesitado hasta dar con el resultado correcto. Finalmente usamos una función (que hemos denominado “sing_plu”) la cual toma como argumento el número de intentos, para incluir la palabra “intento” o “intentos” en función de si el número de tales intentos es 1 o mayor de 1:
Finalmente, una vez acabada la “partida” daremos (mediante la variable “conti”) la posibilidad al usuario/jugador, de escoger si quiere o no volver a jugar. De modo de que en el caso de que la respuesta sea positiva, se lleve a cabo una “limpieza” de pantalla (mediante “subprocess”) dejando la pantalla lista para una nueva ejecución del programa desde el principio. Y si la respuesta es negativa, se producirá el cierre del programa mediante la sentencia “break”.
Dado que la variable “conti” solo acepta una respuesta del tipo si/no, usaremos la función “ns” previamente expuesta, para asegurar que la respuesta dada sea solo “s” (para “sí”) o “n” (para “no”).
El código completo de este programa (“desafio.py”) y del modulo “VALID”, puede verse integro en el siguiente enlace de github: https://github.com/antonioam82/adivina-numero
Escrito por: Antonio Alfonso Martinez.
Subir
Deja una respuesta