Saltar al contenido
Regresar

Piedra, Papel o Tijera: Lógica de Juego con Python

Publicado:  a las  08:52 p.m.

¡Prepárate para un duelo de ingenio, estrategia y… código! ¿Quién ganará en esta batalla algorítmica de Piedra, Papel y Tijera? ⚔️

🔮 Enunciado del Problema

Ana y Alejandro, dos entusiastas de la programación, han llevado su rivalidad hasta el ancestral juego de Piedra, Papel y Tijera. Para automatizar la ardua tarea de determinar el ganador, necesitamos tu ayuda.

El Desafío:

Escribe una función en Python que reciba como entrada una serie de partidas de Piedra, Papel y Tijera y determine quién ha ganado en general.

Parámetros:

Retorna:

Ejemplos:

>>> rock_paper_seasor([['r', 's'], ['s', 'r']])
'Empate'
>>> rock_paper_seasor([['r', 's']])
'Jugador 1'
>>> rock_paper_seasor([['s', 'r'], ['r', 'r']])
'Jugador 2'
>>> rock_paper_seasor([['p', 'p'], ['s', 's'], ['r', 's'], ['r', 'p']])
'Empate'

Notas Adicionales:

🧩 Resolución Paso a Paso

La clave de esta solución radica en mantener un rastreador de puntaje que se incrementa o disminuye según quién gane cada partida. En lugar de hacer comparaciones directas entre las jugadas, simplificamos la lógica con condicionales anidados que evalúan las combinaciones ganadoras.

Primero, inicializamos una variable llamada result para llevar la cuenta de las victorias y derrotas. Esta variable actuará como un termómetro del dominio en el juego:

result = 0

A continuación, iteramos sobre cada partida en la lista games. Este bucle for es el motor que impulsa la evaluación de cada enfrentamiento:

for game in games:
    m1 = game[0]

Dentro del bucle, asignamos la jugada del jugador 1 a la variable m1, que nos servirá como punto de referencia para determinar el resultado de la partida. Observamos que asumimos que el jugador 1 siempre juega primero.

Ahora viene la parte crucial: evaluar quién gana cada partida y actualizar el puntaje. Utilizamos condicionales if y elif para verificar las posibles combinaciones ganadoras:

    if 's' in game and 'p' in game:
        result += -1 if m1 == 's' else 1
    elif 'p' in game and 'r' in game:
        result += -1 if m1 == 'p' else 1
    elif 'r' in game and 's' in game:
        result += -1 if m1 == 'r' else 1

En este bloque, utilizamos el operador ternario condition ? value_if_true : value_if_false (en este caso value_if_true if condition else value_if_false), una forma concisa de escribir un if-else en una sola línea. Si el jugador 1 gana la partida (por ejemplo, jugando tijera contra papel), restamos 1 a result. Si el jugador 2 gana, sumamos 1 a result.

Finalmente, después de evaluar todas las partidas, determinamos el ganador general basándonos en el valor de result:

return 'Jugador 1' if result < 0 else 'Jugador 2' if result > 0 else 'Empate'

Aquí nuevamente utilizamos el operador ternario. Si result es negativo, el Jugador 1 ha ganado. Si es positivo, el Jugador 2 ha ganado. Si es cero, hay un empate.

Solución Completa:

def rock_paper_seasor(games):
	"level: medium; points: 6"
	result = 0
	for game in games:
		m1 = game[0]
		if 's' in game and 'p' in game:
			result += -1 if m1 == 's' else 1
		elif 'p' in game and 'r' in game:
			result += -1 if m1 == 'p' else 1
		elif 'r' in game and 's' in game:
			result += -1 if m1 == 'r' else 1
	return 'Jugador 1' if result < 0 else 'Jugador 2' if result > 0 else 'Empate'

🧠 Conceptos Clave

La solución propuesta se sustenta sobre pilares fundamentales de la programación. La iteración, mediante el bucle for, nos permite procesar cada partida individualmente. Las condicionales (if, elif) son esenciales para implementar la lógica del juego, determinando el ganador en función de las jugadas. El operador ternario, por su parte, ofrece una sintaxis concisa y elegante para expresar decisiones simples. Las estructuras de datos, en este caso, la lista de listas games, son cruciales para organizar la información de entrada de manera eficiente.

La lógica de juego está encapsulada en las comparaciones de jugadas y la actualización del puntaje. Se utilizan comparaciones dentro de las condicionales para determinar si una jugada es ganadora o perdedora. Cada uno de estos conceptos, aunque individualmente sencillos, se entrelazan para crear una solución robusta y eficiente.

¿Sabías que la complejidad temporal de esta función es O(n), donde n es el número de partidas? Esto significa que el tiempo de ejecución crece linealmente con la cantidad de partidas, lo que la hace eficiente incluso para grandes conjuntos de datos.

💫 Reflexiones Finales

Esta solución, aunque funcional, puede optimizarse aún más. Por ejemplo, podríamos utilizar un diccionario para mapear las jugadas a valores numéricos, simplificando las comparaciones. Además, podríamos considerar la posibilidad de extender la función para manejar entradas inválidas o para incluir otras variantes del juego, como “Piedra, Papel, Tijera, Lagarto, Spock”.

Si te ha gustado este análisis y quieres profundizar en el mundo de los algoritmos y la resolución de problemas, ¡no dudes en explorar otros artículos de nuestro blog! La programación es un universo infinito de posibilidades, ¡y te invitamos a descubrirlo junto a nosotros! 🚀



Publicación anterior
Calcula Intereses: Inversión con Interés Simple y Días
Siguiente publicación
Promociones de Refrescos: Calcula tus Botellas Gratis (Python)