1
+ #42 { Retos para Programadores } TORNEO DRAGON BALL
2
+
3
+ # Bibliography reference:
4
+ # I use GPT as a reference and sometimes to correct or generate proper comments.
5
+
6
+ """
7
+ * EJERCICIO:
8
+ * ¡El último videojuego de Dragon Ball ya está aquí!
9
+ * Se llama Dragon Ball: Sparking! ZERO.
10
+ *
11
+ * Simula un Torneo de Artes Marciales, al más puro estilo
12
+ * de la saga, donde participarán diferentes luchadores, y el
13
+ * sistema decidirá quién es el ganador.
14
+ *
15
+ * Luchadores:
16
+ * - Nombre.
17
+ * - Tres atributos: velocidad, ataque y defensa
18
+ * (con valores entre 0 a 100 que tú decidirás).
19
+ * - Comienza cada batalla con 100 de salud.
20
+ * Batalla:
21
+ * - En cada batalla se enfrentan 2 luchadores.
22
+ * - El luchador con más velocidad comienza atacando.
23
+ * - El daño se calcula restando el daño de ataque del
24
+ * atacante menos la defensa del oponente.
25
+ * - El oponente siempre tiene un 20% de posibilidad de
26
+ * esquivar el ataque.
27
+ * - Si la defensa es mayor que el ataque, recibe un 10%
28
+ * del daño de ataque.
29
+ * - Después de cada turno y ataque, el oponente pierde salud.
30
+ * - La batalla finaliza cuando un luchador pierde toda su salud.
31
+ * Torneo:
32
+ * - Un torneo sólo es válido con un número de luchadores
33
+ * potencia de 2.
34
+ * - El torneo debe crear parejas al azar en cada ronda.
35
+ * - Los luchadores se enfrentan en rondas eliminatorias.
36
+ * - El ganador avanza a la siguiente ronda hasta que sólo
37
+ * quede uno.
38
+ * - Debes mostrar por consola todo lo que sucede en el torneo,
39
+ * así como el ganador.
40
+
41
+ """
42
+
43
+ log = print
44
+
45
+ import random
46
+ import time
47
+ import asyncio
48
+
49
+ class Fighter :
50
+ def __init__ (self , id , name , speed , attack , defense ):
51
+ self .id = id
52
+ self .name = name
53
+ self .speed = speed
54
+ self .attack = attack
55
+ self .defense = defense
56
+ self .health = 100 # Each fighter starts with 100 health
57
+
58
+ def calculate_damage (self , opponent ):
59
+ damage = max (self .attack - opponent .defense , 0 ) # No negative damage
60
+
61
+ # Check if the opponent dodges the attack
62
+ if random .random () < 0.2 : # 20% chance to dodge
63
+ return 0 # No damage dealt
64
+
65
+ # If the opponent's defense is greater than the attack, reduce damage
66
+ if opponent .defense > self .attack :
67
+ damage *= 0.1 # 10% of the attack damage
68
+
69
+ return int (damage ) # Return the damage as an integer
70
+
71
+
72
+ class Battle :
73
+ def __init__ (self , fighter1 , fighter2 ):
74
+ self .fighter1 = fighter1
75
+ self .fighter2 = fighter2
76
+ self .attacker = fighter1 if fighter1 .speed >= fighter2 .speed else fighter2
77
+ self .defender = fighter2 if self .attacker == fighter1 else fighter1
78
+
79
+ def winner (self , win_fighter ):
80
+ log (f"{ win_fighter .name } is the winner!" )
81
+
82
+ def loser (self , los_fighter ):
83
+ log (f"{ los_fighter .name } is the loser!" )
84
+
85
+ async def start (self ):
86
+ while self .fighter1 .health > 0 and self .fighter2 .health > 0 :
87
+ damage = self .attacker .calculate_damage (self .defender )
88
+
89
+ # Ensure a minimum level of damage
90
+ min_damage = 10
91
+ actual_damage = max (min_damage , damage )
92
+
93
+ self .defender .health -= actual_damage
94
+
95
+ # Log the attack and damage
96
+ if actual_damage == min_damage :
97
+ log (f"{ self .attacker .name } 's attack was partially blocked by { self .defender .name } , dealing { actual_damage } damage." )
98
+ else :
99
+ log (f"{ self .attacker .name } attacks { self .defender .name } for { actual_damage } damage." )
100
+ log (f"{ self .defender .name } has { self .defender .health } health left." )
101
+
102
+ # Swap roles for the next turn
103
+ self .attacker , self .defender = self .defender , self .attacker
104
+
105
+ # Introduce a delay between attacks
106
+ await asyncio .sleep (0.5 )
107
+
108
+ winner = self .fighter1 if self .fighter1 .health > 0 else self .fighter2
109
+ log (f"{ winner .name } wins the battle!" )
110
+ self .winner (winner )
111
+ self .loser (self .fighter1 if winner == self .fighter2 else self .fighter2 )
112
+
113
+ return winner
114
+
115
+
116
+ class Tournament :
117
+ def __init__ (self , fighters ):
118
+ if not self .is_power_of_two (len (fighters )):
119
+ raise ValueError ("Number of fighters must be a power of 2." )
120
+ self .fighters = fighters
121
+
122
+ @staticmethod
123
+ def is_power_of_two (n ):
124
+ return (n & (n - 1 )) == 0 and n > 0 # Check if n is a power of two
125
+
126
+ async def start (self ):
127
+ log ("Starting the tournament..." )
128
+ round = 1
129
+
130
+ while len (self .fighters ) > 1 :
131
+ log (f"\n --- Round { round } ---" )
132
+
133
+ winners = []
134
+ for i in range (0 , len (self .fighters ), 2 ):
135
+ battle = Battle (self .fighters [i ], self .fighters [i + 1 ])
136
+ winner = await battle .start ()
137
+ winners .append (winner )
138
+
139
+ log ("\n Winners of Round " + str (round ) + ":" )
140
+ for fighter in winners :
141
+ log ("- " + fighter .name )
142
+
143
+ self .fighters = winners # Update fighters for the next round
144
+ round += 1
145
+
146
+ log (f"\n The champion of the tournament is { self .fighters [0 ].name } !" )
147
+
148
+
149
+ # Create fighters
150
+ fighters = [
151
+ Fighter (1 , 'Goku' , 95 , 80 , 50 ),
152
+ Fighter (2 , 'Vegeta' , 90 , 85 , 45 ),
153
+ Fighter (3 , 'Gohan' , 85 , 75 , 55 ),
154
+ Fighter (4 , 'Piccolo' , 80 , 70 , 60 ),
155
+ Fighter (5 , 'Frieza' , 88 , 90 , 40 ),
156
+ Fighter (6 , 'Cell' , 85 , 80 , 50 ),
157
+ Fighter (7 , 'Majin Buu' , 70 , 60 , 70 ),
158
+ Fighter (8 , 'Trunks' , 75 , 65 , 65 )
159
+ ]
160
+
161
+ # Function to start the tournament
162
+ async def main ():
163
+ tournament = Tournament (fighters )
164
+ await tournament .start ()
165
+
166
+ # Run the tournament
167
+ if __name__ == "__main__" :
168
+ asyncio .run (main ())
169
+
170
+
171
+ # Possible Output:
172
+ """
173
+ Starting the tournament...
174
+
175
+ --- Round 1 ---
176
+ Goku attacks Vegeta for 35 damage.
177
+ Vegeta has 65 health left.
178
+ Vegeta attacks Goku for 35 damage.
179
+ Goku has 65 health left.
180
+ Goku attacks Vegeta for 35 damage.
181
+ Vegeta has 30 health left.
182
+ Vegeta's attack was partially blocked by Goku, dealing 10 damage.
183
+ Goku has 55 health left.
184
+ Goku attacks Vegeta for 35 damage.
185
+ Vegeta has -5 health left.
186
+ Goku wins the battle!
187
+ Goku is the winner!
188
+ Vegeta is the loser!
189
+ Gohan attacks Piccolo for 15 damage.
190
+ Piccolo has 85 health left.
191
+ Piccolo attacks Gohan for 15 damage.
192
+ Gohan has 85 health left.
193
+ Gohan's attack was partially blocked by Piccolo, dealing 10 damage.
194
+ Piccolo has 75 health left.
195
+ Piccolo attacks Gohan for 15 damage.
196
+ Gohan has 70 health left.
197
+ Gohan attacks Piccolo for 15 damage.
198
+ Piccolo has 60 health left.
199
+ Piccolo's attack was partially blocked by Gohan, dealing 10 damage.
200
+ Gohan has 60 health left.
201
+ Gohan attacks Piccolo for 15 damage.
202
+ Piccolo has 45 health left.
203
+ Piccolo attacks Gohan for 15 damage.
204
+ Gohan has 45 health left.
205
+ Gohan attacks Piccolo for 15 damage.
206
+ Piccolo has 30 health left.
207
+ Piccolo attacks Gohan for 15 damage.
208
+ Gohan has 30 health left.
209
+ Gohan attacks Piccolo for 15 damage.
210
+ Piccolo has 15 health left.
211
+ Piccolo attacks Gohan for 15 damage.
212
+ Gohan has 15 health left.
213
+ Gohan attacks Piccolo for 15 damage.
214
+ Piccolo has 0 health left.
215
+ Gohan wins the battle!
216
+ Gohan is the winner!
217
+ Piccolo is the loser!
218
+ Frieza's attack was partially blocked by Cell, dealing 10 damage.
219
+ Cell has 90 health left.
220
+ Cell's attack was partially blocked by Frieza, dealing 10 damage.
221
+ Frieza has 90 health left.
222
+ Frieza attacks Cell for 40 damage.
223
+ Cell has 50 health left.
224
+ Cell attacks Frieza for 40 damage.
225
+ Frieza has 50 health left.
226
+ Frieza attacks Cell for 40 damage.
227
+ Cell has 10 health left.
228
+ Cell attacks Frieza for 40 damage.
229
+ Frieza has 10 health left.
230
+ Frieza attacks Cell for 40 damage.
231
+ Cell has -30 health left.
232
+ Frieza wins the battle!
233
+ Frieza is the winner!
234
+ Cell is the loser!
235
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
236
+ Majin Buu has 90 health left.
237
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
238
+ Trunks has 90 health left.
239
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
240
+ Majin Buu has 80 health left.
241
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
242
+ Trunks has 80 health left.
243
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
244
+ Majin Buu has 70 health left.
245
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
246
+ Trunks has 70 health left.
247
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
248
+ Majin Buu has 60 health left.
249
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
250
+ Trunks has 60 health left.
251
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
252
+ Majin Buu has 50 health left.
253
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
254
+ Trunks has 50 health left.
255
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
256
+ Majin Buu has 40 health left.
257
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
258
+ Trunks has 40 health left.
259
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
260
+ Majin Buu has 30 health left.
261
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
262
+ Trunks has 30 health left.
263
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
264
+ Majin Buu has 20 health left.
265
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
266
+ Trunks has 20 health left.
267
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
268
+ Majin Buu has 10 health left.
269
+ Majin Buu's attack was partially blocked by Trunks, dealing 10 damage.
270
+ Trunks has 10 health left.
271
+ Trunks's attack was partially blocked by Majin Buu, dealing 10 damage.
272
+ Majin Buu has 0 health left.
273
+ Trunks wins the battle!
274
+ Trunks is the winner!
275
+ Majin Buu is the loser!
276
+
277
+ Winners of Round 1:
278
+ - Goku
279
+ - Gohan
280
+ - Frieza
281
+ - Trunks
282
+
283
+ --- Round 2 ---
284
+ Goku attacks Gohan for 25 damage.
285
+ Gohan has -10 health left.
286
+ Goku wins the battle!
287
+ Goku is the winner!
288
+ Gohan is the loser!
289
+ Frieza attacks Trunks for 25 damage.
290
+ Trunks has -15 health left.
291
+ Frieza wins the battle!
292
+ Frieza is the winner!
293
+ Trunks is the loser!
294
+
295
+ Winners of Round 2:
296
+ - Goku
297
+ - Frieza
298
+
299
+ --- Round 3 ---
300
+ Goku's attack was partially blocked by Frieza, dealing 10 damage.
301
+ Frieza has 0 health left.
302
+ Goku wins the battle!
303
+ Goku is the winner!
304
+ Frieza is the loser!
305
+
306
+ Winners of Round 3:
307
+ - Goku
308
+
309
+ The champion of the tournament is Goku!
310
+
311
+ """
0 commit comments