1+ """
2+ * EJERCICIO:
3+ * ¡El último videojuego de Dragon Ball ya está aquí!
4+ * Se llama Dragon Ball: Sparking! ZERO.
5+ *
6+ * Simula un Torneo de Artes Marciales, al más puro estilo
7+ * de la saga, donde participarán diferentes luchadores, y el
8+ * sistema decidirá quién es el ganador.
9+ *
10+ * Luchadores:
11+ * - Nombre.
12+ * - Tres atributos: velocidad, ataque y defensa
13+ * (con valores entre 0 a 100 que tú decidirás).
14+ * - Comienza cada batalla con 100 de salud.
15+ * Batalla:
16+ * - En cada batalla se enfrentan 2 luchadores.
17+ * - El luchador con más velocidad comienza atacando.
18+ * - El daño se calcula restando el daño de ataque del
19+ * atacante menos la defensa del oponente.
20+ * - El oponente siempre tiene un 20% de posibilidad de
21+ * esquivar el ataque.
22+ * - Si la defensa es mayor que el ataque, recibe un 10%
23+ * del daño de ataque.
24+ * - Después de cada turno y ataque, el oponente pierde salud.
25+ * - La batalla finaliza cuando un luchador pierde toda su salud.
26+ * Torneo:
27+ * - Un torneo sólo es válido con un número de luchadores
28+ * potencia de 2.
29+ * - El torneo debe crear parejas al azar en cada ronda.
30+ * - Los luchadores se enfrentan en rondas eliminatorias.
31+ * - El ganador avanza a la siguiente ronda hasta que sólo
32+ * quede uno.
33+ * - Debes mostrar por consola todo lo que sucede en el torneo,
34+ * así como el ganador.
35+ """
36+ import random
37+
38+ class Fighter :
39+
40+ def __init__ (self , name : str , attr : dict , health : int ) -> None :
41+ self .name = name
42+ self .attr = attr
43+ self .health = health
44+
45+ def __str__ (self ) -> str :
46+ return f"{ self .name } - { self .health } HP"
47+
48+ def __repr__ (self ) -> str :
49+ return f"{ self .name } "
50+
51+ def reset_health (self ) -> None :
52+ self .health = 100
53+
54+ @property
55+ def speed (self ) -> int :
56+ return self .attr ['speed' ]
57+
58+ @property
59+ def attack (self ) -> int :
60+ return self .attr ['attack' ]
61+
62+ @property
63+ def defense (self ) -> int :
64+ return self .attr ['defense' ]
65+
66+ @property
67+ def is_alive (self ) -> bool :
68+ return self .health > 0
69+
70+ def take_damage (self , damage : int ) -> None :
71+
72+ attack_damage = 0
73+
74+ if random .random () < 0.2 :
75+ # print(f"{self.name} ha esquivado el ataque")
76+ attack_damage = 0
77+ else :
78+ if self .defense >= damage :
79+ attack_damage = damage * 0.1
80+ else :
81+ attack_damage = damage - self .defense
82+
83+ attack_damage = int (attack_damage )
84+
85+ self .health = max (self .health - attack_damage , 0 )
86+ # print(f"{self.name} ha recibido {attack_damage} de daño")
87+ # print(f"Salud restante de {self.name}: {self.health}")
88+
89+
90+ class Battle :
91+
92+ def __init__ (self , fighterA : Fighter , fighterB : Fighter ) -> None :
93+ self .FighterA = fighterA
94+ self .FighterB = fighterB
95+
96+ def start (self , verbose = True ) -> Fighter :
97+ if verbose :
98+ print (f"\n ***** { self .FighterA .name } vs. { self .FighterB .name } *****" )
99+
100+ if self .FighterA .speed > self .FighterB .speed :
101+ attacker = self .FighterA
102+ defender = self .FighterB
103+ else :
104+ attacker = self .FighterB
105+ defender = self .FighterA
106+
107+ while attacker .is_alive and defender .is_alive :
108+
109+ defender .take_damage (attacker .attack )
110+ if defender .is_alive :
111+ attacker .take_damage (defender .attack )
112+
113+ if self .FighterA .is_alive :
114+ # print(f"\n{self.FighterA.name} es el ganador de la batalla")
115+ return self .FighterA
116+ else :
117+ # print(f"\n{self.FighterB.name} es el ganador de la batalla")
118+ return self .FighterB
119+
120+
121+ class Tournament :
122+
123+ def __init__ (self , fighters : list , verbose : bool ) -> None :
124+ self .fighters = fighters
125+ self .verbose = verbose
126+
127+ def start (self ) -> Fighter :
128+ round = 1
129+ if self .verbose :
130+ print ("¡¡¡TORNEO DRAGON BALL!!!" )
131+ print (f"Participantes: { ', ' .join ([fighter .name for fighter in self .fighters ])} " )
132+
133+
134+ if len (self .fighters ) % 2 != 0 :
135+ raise ValueError (f"El número de luchadores debe ser potencia de 2 y hay { len (self .fighters )} luchadores." )
136+
137+ while len (self .fighters ) > 1 :
138+ if self .verbose :
139+ print (f"\n ***** Ronda { round } *****" )
140+
141+ random .shuffle (self .fighters )
142+ winners = []
143+ for i in range (0 , len (self .fighters ), 2 ):
144+ battle = Battle (self .fighters [i ], self .fighters [i + 1 ])
145+ if self .verbose :
146+ winner = battle .start ()
147+ else :
148+ winner = battle .start (verbose = False )
149+ if self .verbose :
150+ print (f"{ winner .name } es el ganador de la batalla" )
151+ winners .append (winner )
152+
153+ self .fighters = winners
154+ self .reset_health ()
155+ round += 1
156+
157+ return self .fighters [0 ]
158+
159+ def reset_health (self ) -> None :
160+ for fighter in self .fighters :
161+ fighter .reset_health ()
162+
163+ if __name__ == "__main__" :
164+
165+ fighters = [
166+ Fighter ("Goku" , {"speed" : 80 , "attack" : 95 , "defense" : 85 }, 100 ),
167+ Fighter ("Vegeta" , {"speed" : 70 , "attack" : 80 , "defense" : 90 }, 100 ),
168+ Fighter ("Gohan" , {"speed" : 90 , "attack" : 70 , "defense" : 80 }, 100 ),
169+ Fighter ("Piccolo" , {"speed" : 60 , "attack" : 60 , "defense" : 60 }, 100 ),
170+ Fighter ("Freezer" , {"speed" : 95 , "attack" : 90 , "defense" : 75 }, 100 ),
171+ Fighter ("Krillin" , {"speed" : 95 , "attack" : 90 , "defense" : 75 }, 100 ),
172+ Fighter ("Célula" , {"speed" : 92 , "attack" : 70 , "defense" : 73 }, 100 ),
173+ Fighter ("Trunks" , {"speed" : 88 , "attack" : 88 , "defense" : 88 }, 100 )
174+ ]
175+
176+ print ("\n SIMULACIÓN DE TORNEO" )
177+ result_sim = [Tournament (fighters , verbose = False ).start ().name
178+ for _ in range (1000 )]
179+
180+ from collections import Counter
181+ print ("\n RESULTADOS DE LA SIMULACIÓN" )
182+ counter = dict (Counter (result_sim ))
183+ counter = sorted (counter .items (), key = lambda x : x [1 ], reverse = True )
184+ print (f"El favorito para ganar es: { counter [0 ][0 ]} con { counter [0 ][1 ]/ 1000 } de probabilidades.\n \n " )
185+
186+ tournament = Tournament (fighters , verbose = True )
187+ winner = tournament .start ()
188+ print ("\n ¡¡¡TORNEO FINALIZADO!!!" )
189+ print (f"El ganador del torneo es: { winner .name } " )
190+ print ("¡¡¡Felicidades!!!" )
191+
192+
193+
194+
0 commit comments