TransWikia.com

Simular un juego por turnos - penales - en Python

Stack Overflow en español Asked by nicolas osorio bustos on November 10, 2021

Estoy tratando de desarrollar un simulador de penales, en el cual necesito un sistema de turnos que seria = (jugador, pc, jugador, pc….) pero no tengo idea de como hacerlo.

player1Score = 0
pcScore = 0
matchEnd = False

def printNet(Net):
    print('-------------------------------------')
    print('|  1   |          2           |   3  |')
    print('|----------------------------------- |')
    print('|      |                      |      |')
    print('|  4   |          5           |   6  |')
    print('|----------------------------------- |')
    print('|      |                      |      |')
    print('|   7  |          8           |   9  |')

def shooting(player1Score):
    import random
    notGoal = random.choice(1,2,3,4,5,6,7,8,9)
    user = input ("Seleccione a donde desea tirar")
    if notGoal == user :
        player1Score += 0
        print ("No has anotado")
    else :
        player1Score += 1
        print("GOOOOOOOOOOOOOOOL")

def goalkeeping(pcScore):
    import random
    notGoal = random.choice(1, 2, 3, 4, 5, 6,7,8,9 )
    user = input("Seleccione a donde cree que ira el penalty")
    if notGoal == user:
        pcScore += 0
        print ("Lo has parado")
    else:
        pcScore += 1
        print ("Mala suerte, tu oponente ha anotado")


def matchEnd(player1Score,pcScore):
    if player1Score >= 5 & pcScore >= 5:
        matchEnd = True
    else: matchEnd = False

Esto es lo que llevo hasta ahora, cualquier otra recomendacion es aceptada, Gracias!!

One Answer

Para la parte de las rondas, se haría dentro de un bucle infinito while True y por cada semi-ronda se verifica si el equipo ha ganado, ha perdido, o si aún siguen las rondas. Si resulta los dos primeros casos, se rompe el ciclo y se declara al ganador. Pseudocódigo:

equipo1, equipo2 = seleccionar_aleatoriamente([Equipo1], [Equipo2])
ciclo_infinito:
    patea el equipo1
    verificar si equipo1 ganó (True) o perdió (False)
        Asignar ganador
        romper ciclo_infinito (break)
    Patea el equipo2
    verificar si equipo2 ganó (True) o perdió (False)
        Asignar ganador
        romper ciclo_infinito (break)
    Si ambas verificaciones son [None], repetir el ciclo (siguiente tanda)

Mi propuesta es que cada equipo sea un objeto de una clase Penales para poder interactuar más fácil con sus métodos y atributos. Cada equipo es una lista [nombre, tipo] donde el primer elemento es el nombre (usuario, país...) y el segundo es el tipo de jugador (entrada_manual, CPU). El programa solo procesa el equipo automáticamente cuando ve la palabra "CPU", cualquier otra cosa la toma como entrada manual.

La función check_winner() no forma parte de la clase y evalúa si un equipo ganó. Primero lo hace en base a limit = 5 en ronda regular y luego 6, 7, ... etc en muerte súbita.

import random

class Penales:
    target = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    def __init__(self, team):
        self.name = team[0]
        self.ttype = team[1]
        self.goals = []
        
    def human_select(self, msg):
        while True:
            h_inp = input(msg)
            if h_inp in self.target:
                break
        return h_inp
        
    def goalkeeping(self, rname, rtype):
        if rtype.upper() == 'CPU':
            rtarget = random.choice(self.target)
        else:
            rtarget = self.human_select(f'Arquero [{rname}] - Seleccione la dirección: ')
        return rtarget
        
    def shooting(self, rival, rival_type):
        if self.ttype.upper() == 'CPU':
            starget = random.choice(self.target)
        else:
            starget = self.human_select(f'Pateador [{self.name}] - Seleccione la dirección: ')
        # Verificar si fue gol o no
        rtarget = self.goalkeeping(rival, rival_type)
        print(f'Pateador ({self.name}): {starget} | Arquero ({rival}): {rtarget}', end="")
        if starget == rtarget:
            print(' | No anotó')
            self.goals.append(0)
        else:
            print(' | GOOOOOOOOOOOOOOOL')
            self.goals.append(1)
        
    def show_goals(self, align):
        gstring = ''
        for value in self.goals:
            gstring += 'G ' if value == 1 else 'x '
        if len(self.goals) < 5:
            gstring += '. ' * (5 - len(self.goals))
        return f'{self.name} [{gstring}]' if align == 'L' else f'[{gstring}] {self.name}'
    
def check_winner(cur_team_goals, riv_team_goals, i):
    limit = 5 if i <= 5 else i
    cscored = sum(cur_team_goals)
    cremain = limit - len(cur_team_goals)
    rscored = sum(riv_team_goals)
    rremain = limit - len(riv_team_goals)
    if cscored > rscored + rremain:
        win = True
    elif(rscored > cscored + cremain):
        win = False
    else:
        win = None
    return win
    
print('######## SIMULADOR DE PENALES ########n')
teams = [['Argentina', 'Human'], ['Alemania', 'CPU']]
print('- Resultado del volado de moneda -')
random.shuffle(teams)
team1 = Penales(teams[0])
team2 = Penales(teams[1])
print(f'Primero en patear: {team1.name}. Segundo: {team2.name}n')
i = 1
while True:
    if i == 1:
        print('=== TANDA REGULAR ===')
    elif i == 6:
        print('=== MUERTE SUBITA ===')
    print(f'{team1.show_goals("L")} - {team2.show_goals("R")}n')
    print(f'[ Ronda {i} ]')
    team1.shooting(team2.name, team2.ttype)
    if (result := check_winner(team1.goals, team2.goals, i)) is not None:
        winner = team1.name if result else team2.name
        break
    team2.shooting(team1.name, team1.ttype)
    if (result := check_winner(team2.goals, team1.goals, i)) is not None:
        winner = team2.name if result else team1.name
        break
    i += 1
    print()

print('nResultado Final')
print(f'{team1.show_goals("L")} - {team2.show_goals("R")}n')
print(f'Ganador: {winner}')

[ * ] Puedes poner ambos equipos como CPU, y la computadora ¡jugará contra si misma!

Un ejemplo de una simulación CPU vs CPU:

- Resultado del volado de moneda -
Primero en patear: Alemania. Segundo: Argentina

=== TANDA REGULAR ===
Alemania [. . . . . ] - [. . . . . ] Argentina

[ Ronda 1 ]
Pateador (Alemania): 2 | Arquero (Argentina): 1 | GOOOOOOOOOOOOOOOL
Pateador (Argentina): 8 | Arquero (Alemania): 1 | GOOOOOOOOOOOOOOOL

Alemania [G . . . . ] - [G . . . . ] Argentina
.
.
.
[ Ronda 5 ]
Pateador (Alemania): 7 | Arquero (Argentina): 4 | GOOOOOOOOOOOOOOOL

Resultado Final
Alemania [G G G G G ] - [G G x G . ] Argentina

Ganador: Alemania

Obviamente esta es una tanda de penales ideal, para que sea un poco más realista hay más trabajo que hacer, por ejemplo, agregar un chance de botar el disparo; agregar un pequeño porcentaje de que el arquero adivine la trayectoria independiente del valor aleatorio generado, y así bajar la probabilidad de acierto como a 75% - 80%.
Como está actualmente he tenido tandas de muerte súbita hasta de 20 rondas, pero al menos te servirá como referencia.

Answered by aeportugal on November 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP