elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  ¿Ordenar turnos por velocidad?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: ¿Ordenar turnos por velocidad?  (Leído 10,840 veces)
Tachikomaia


Desconectado Desconectado

Mensajes: 1.180


Superhacker (es broma xD )


Ver Perfil
¿Ordenar turnos por velocidad?
« en: 8 Agosto 2021, 06:06 am »

Ejemplo de input:
Player1Speed = 2
Player2Speed = 3
Player3Speed = 1
Player4Speed = 4
(pueden ser más)

Para ese input quiero que el output sea:
Turn1 = Player4
Turn2 = Player2
Turn3 = Player1
Turn4 = Player3

¿Cómo hacer eso sin for ni arrays? Es que no me gustan.


« Última modificación: 8 Agosto 2021, 06:15 am por Tachikomaia » En línea

3n31ch


Desconectado Desconectado

Mensajes: 445


Grandes conocimientos engendran grandes dudas


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #1 en: 8 Agosto 2021, 09:02 am »

¿Como es eso de que no te gustan los fors ni arrays?  :xD :xD :xD

En que lenguaje, ¿python? lo puedes hacer con eval(), exec() y while.. pero vamos, es una tontería no usar arrays  :xD.

Quizás lo haga para entretenerme un rato, pero me mataste con ese comentario  ;-) ;-) ;-) :laugh:

Modifico este mensaje en un rato hahahaha.

Código
  1. # Seteo de variables
  2. Player1Speed = 2
  3. Player2Speed = 3
  4. Player3Speed = 1
  5. Player4Speed = 4
  6.  
  7. # Calculo la cantidad de jugadores y seteo los turnos (sin ordenar) con la velocidad
  8. l = 1
  9. while True:
  10. try:
  11. var = eval('Player'+str(l)+'Speed')
  12. exec('Turn'+str(l)+' = '+str(var))
  13. l += 1
  14. except:
  15. l -= 1
  16. break
  17.  
  18. # El bubble sort mas feo del mundo
  19. i = 1
  20. while i < l:
  21. j = 1
  22. while j < l:
  23. v1 = eval('Turn'+str(j))
  24. v2 = eval('Turn'+str(j + 1))
  25. if v1 < v2:
  26. exec('Turn'+str(j)+' = '+str(v2))
  27. exec('Turn'+str(j + 1)+' = '+str(v1))
  28. j += 1
  29. i += 1
  30.  
  31. # Remplazo las velocidades por los jugadores (uso la misma varialbe turn)
  32. i = 1
  33. while i <= l:
  34. name = 'Player' + str(i)
  35. speed = eval(name+'Speed')
  36. j = 1
  37. while j <= l:
  38. turn = eval('Turn'+str(j))
  39. if speed == turn:
  40. exec( 'Turn'+str(j) + ' = "' + name + '"')
  41. break
  42. j += 1
  43. i += 1
  44.  
  45. #Imprimo el resultado ordenado
  46. i = 1
  47. while i <= l:
  48. var = eval('Turn' + str(i))
  49. print('Turn' + str(i) + ' = ' + var)
  50. i += 1
  51.  


« Última modificación: 8 Agosto 2021, 10:50 am por 3n31ch » En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.180


Superhacker (es broma xD )


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #2 en: 9 Agosto 2021, 03:09 am »

¿Como es eso de que no te gustan los fors ni arrays?  :xD :xD :xD
Well... los for siempre me parecieren contra intuitivos, o mal redactados, y que yo sepa los whiles pueden hacer lo mismo. Ahora que recuerdo tampoco me gustan los case, aunque tal vez esos ayuden bastante a que el código sea más legible.
Yo uso Macromedia Flash 5, al comienzo porque era el último Flash que tenía la función de guardar variables en un archivo txt, o al menos tenía una forma fácil de hacerlo. Pero si las variables eran arrays entonces no funcionaba, por eso empecé a no usar arrays y me resultó más comprensible.

Tu código parece muy complicado, no pensé que fuera tanto  :o Me tomará un tiempo comprenderlo.
En línea

3n31ch


Desconectado Desconectado

Mensajes: 445


Grandes conocimientos engendran grandes dudas


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #3 en: 9 Agosto 2021, 05:19 am »

Bueno, al margen de lo del for, el tema de los arrays es lo que hace complicado el código que lees. No sé nada de macromedia flash, así que te lo explicaré según lo que escribí en python (tu haces la traducción luego).

Aca los metódos claves son:
eval()  eval se usa para evaluar una sola expresión de Python generada dinámicamente. Le paso un string (código), esta la ejecuta y me retorna el resultado. Por ejemplo, le paso el nombre de una variable y de existir me dará el resultado, en caso contrarió me tirara un error (el mismo error que arrojaría si yo intentara acceder al valor de una variable que no existe).
exec() exec se usa para ejecutar código de Python generado dinámicamente. Le paso un string y lo ejecuta. Lo utilizó para crear una variable, osea: eval("variable = 5"), sería lo mismo que directamente escribir variable = 5 (solo que lo puedo hacer desde un string, en tiempo de ejecución).

El código se divide en 5 partes (identificadas por los comentarios):

1.- Seteo de variables: Esto ya lo entenderás así que no lo explicaré.

2.- Cálculo de cantidad de jugadores: Dado que no puedo usar arrays o diccionarios lo que hice fue usar un while que tuviera un contador incremental que parte desde 1. En cada ciclo uso la función eval para obtener el valor de la variable (iteración 1: Player1Speed, iteración 2: Player2Speed, etc.), y exec para guardar dicho valor en Turn1, Turn2, Turn3, etc. Cuando eval me tire un error de que la variable que intento acceder no existe entonces salgo del while. Como resultado de este bloque de código obtengo 2 cosas: La creación de variables Turn1, Turn2, Turn3, etc. con las velocidades en desorden y la cantidad de variables de entrada (obtenida a partir del contador resultante). Ejemplo:

Código:
l = 4
Turn1 = 2
Turn2 = 3
Turn3 = 1
Turn4 = 4

3.- El bubble sort mas feo del mundo: Aca no hay mucho que explicar. Si no lo conoces, busca bubble sort en internet y ya está. (Se podrían haber usado otros métodos de ordenamiento, pero este es el mas facil que se me ocurrió). Como resultado de este método obtengo las velocidades ordenadas (estas velocidades están guardadas dentro de Turn1, Turn2, Turn3, etc). Ejemplo:

Código:
Turn1 = 4
Turn2 = 3
Turn3 = 2
Turn4 = 1

4.- Remplazar velocidades por jugadores: Acá recorro la "lista" de jugadores, y por cada uno de estos, recorro la lista de turnos. Si la velocidad del jugador corresponde a la velocidad del turno, remplazo la velocidad del turno por el nombre del jugador y avanzo al siguiente jugador, así hasta que todos los valores sean remplazados. Ejemplo:

Código:
Turn1 = "Player4"
Turn2 = "Player2"
Turn3 = "Player1"
Turn4 = "Player3"


5.- Imprimir resultado ordenado: Nada que decir, solo recorro la lista de turnos e imprimo el resultado.

PD: Si el problema es no poder guardar arrays en un txt, entonces lee el txt, guarda esa lectura en un array de objetos con el nombre del jugador y su velocidad, y ejecuta un metodo de ordenamiento. Te será mucho mas simple.

PD2: No se nada de macromedia flash, pero esto no estaba muerto? Es una duda, no una critica, no te lo tomes a mal hahaha.
« Última modificación: 9 Agosto 2021, 05:25 am por 3n31ch » En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.180


Superhacker (es broma xD )


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #4 en: 9 Agosto 2021, 19:24 pm »

eval es igual que en M. Flash 5, y exec parece "set variable" o (aunque hace mucho que no uso esto) una expresión como por ejemplo llamar a una variable (o dinámica, si se dice así) función.

Código
  1. # Calculo la cantidad de jugadores y seteo los turnos (sin ordenar) con la velocidad
  2. l = 1
  3. while True:
  4. try:
  5. var = eval('Player'+str(l)+'Speed')
  6. exec('Turn'+str(l)+' = '+str(var))
  7. l += 1
  8. except:
  9. l -= 1
  10. break
¿Cual es el resultado de esta parte?

Creas una variable var que contiene la Speed del player 1.
var = 2

Luego parece que creas otra llamada Turn1 que contiene la variable creada.
Turn1 = 2

No entiendo cómo i pasa a ser negativo, pero parece que el resultado del código es crear 4 variables Turn.

Seguiré analizando...

Citar
PD: Si el problema es no poder guardar arrays en un txt, entonces lee el txt, guarda esa lectura en un array de objetos con el nombre del jugador y su velocidad, y ejecuta un metodo de ordenamiento. Te será mucho mas simple.
O el problema era no poder cargar los array del txt, fue hace mucho... Ya no uso archivos externos (como los txt).

Citar
PD2: No se nada de macromedia flash, pero esto no estaba muerto? Es una duda, no una critica, no te lo tomes a mal hahaha.
MF según veo es del año 2000. Fue comprado por Adobe e hicieron varias nuevas versiones. Ni idea si siguen haciendo, pero como sea, el programa que yo uso es viejo, pero es el lenguaje (actionscript) y entorno que más entiendo.

Luego está el tema del Flash Player, que creo ya no se usa (los navegadores tienen sus propios reproductores, creo que Htlm 5) salvo quizá para los archivos swf, que se crean con Flash.
En línea

3n31ch


Desconectado Desconectado

Mensajes: 445


Grandes conocimientos engendran grandes dudas


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #5 en: 9 Agosto 2021, 20:09 pm »

Explico linea por linea

Código
  1.    # Calculo la cantidad de jugadores y seteo los turnos (sin ordenar) con la velocidad
  2.    l = 1 # dado que la primera variable es Player1Speed, l parte en uno
  3.    while True: #se repite por siempre (hasta que ocurra el break)
  4.     try: #contengo el error que ocurrira cuando intente acceder a una variable PlayerNSpeed que no exista
  5.     var = eval('Player'+str(l)+'Speed') #Accedo a la variable PlayerlSpeed (siendo l el número), de no existir se ejecuta exepct
  6.     exec('Turn'+str(l)+' = '+str(var)) #Creo una variable TurnX = PlayerlSpeed
  7.     l += 1 # Le sumo 1 a l, para que la siguiente iteración sea con un número mas.
  8.     except: #lo de abajo se ejecuta en caso de que la variable PlayerlSpeed no exista
  9.     l -= 1 #dado que PlayerlSpeed no existe, tengo que restar 1 a l, (osea si el total de players eran 4, cuando ocurra el error l será 5, me interesa que vuelva a 4
  10.     break #salgo del ciclo while
  11.  

Como ves l nunca es negativo. Un ejemplo de la ejecución del código con dos players sería:

Código:
Player1Speed = 2
Player2Speed = 1
l = 1
Iteración 1:

var = Player1Speed
Turn1 = var
l = l + 1 #osea 2

Iteración 2:
var = Player2Speed
Turn2 = var
l = l  + 1 #osea 3

Iteración 3:
var  = Player3Speed <- #ERORR!!!! ESTO NO SE PUEDE EJECUTAR PORQUE LA VARIABLE NO EXISTE.
l =  l -1 #Osea vuelve a dos
break #dejo de iterar

#RESULTADOS OBTENIDOS POR EL CÓDIGO DE ARRIBA
Turn1 = 1 #velocidad del primer jugador
Turn2 = 2 #velocidad del segundo jugador
l = 2 #cantidad de jugadores

PD: Yo separe eval de exec, pero en vez de pasar de Player1Speed a var y de var a Turn1 puedes hacerlo directo: Turn1 = Player1Speed

Recomendación:
No sigas por este camino, los arrays existen por algo, trabajar con variables independientes hará que tu código sea dificil de leer y mantener. Puedo entender que no quieras usar switch y case, o incluso que no quieras usar for (aun cuando es mucho mas "controlable" que while), pero no usar arrays solo te limitará como programador. Es tu decisión, pero no puedo evitar hacerte esta recomendación.
« Última modificación: 9 Agosto 2021, 20:22 pm por 3n31ch » En línea

Danielㅤ


Conectado Conectado

Mensajes: 1.667


🔵🔵🔵🔵🔵🔵🔵


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #6 en: 9 Agosto 2021, 20:42 pm »

Hola, una pequeña mejora y recomendación al código del compañero 3n31ch es la siguiente:

Se puede cambiar ésto:

Código
  1. l = 1
  2. while True:
  3. try:
  4. var = eval('Player'+str(l)+'Speed')
  5. exec('Turn'+str(l)+' = '+str(var))
  6. l += 1
  7. except:
  8. l -= 1
  9. break
  10.  

Por esto:

Código
  1. l = 1
  2. continuarBucle = True
  3. while continuarBucle:
  4.    try:
  5.        var = eval('Player'+str(l)+'Speed')
  6.        exec('Turn'+str(l)+' = '+str(var))
  7.        l += 1
  8.    except:
  9.        l -= 1
  10.        continuarBucle = False
  11.  

de esa manera se estaría usando semáforos y no se detendría el bucle tan bruscamente con break.


Saludos
En línea

3n31ch


Desconectado Desconectado

Mensajes: 445


Grandes conocimientos engendran grandes dudas


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #7 en: 9 Agosto 2021, 23:09 pm »

Si correcto, muchas gracias Daniel. Una forma de no usar break es poner el condicional en el while. Ahora, para mi es mas facil de entender un código con break "Si pasa esto me salgo del ciclo en el que estoy" a con una condición while "Si pasa esto cambio el booleano a falso, luego pueden o no pasar cosas, en la siguiente iteración me salgo.". Fuera de eso, no sé si hay algún problema a nivel de ejecución (velocidades o cosas) pero en caso de no haberlo prefiero el break.

Nota: Esto que digo solo aplica si hay una condicional booleana que se altere en medio del código, en caso contrario, en efecto puede ser mejor la condición en el while. Supongo que es tema de preferencias. No estoy seguro si Clean Code habla de esto.

Aunque en tu caso en Macro Flash tengo entendido que tienes el do-while (si al terminar pasa esto me salgo), puede que lo prefieras.

De todas formas si el tema es hacerlo lo mas reducido y correcto posible (con bubble) quizás la opción correcta sea algo como esto:

Código
  1. # Seteo de variables
  2. Player1Speed = 2
  3. Player2Speed = 3
  4. Player3Speed = 1
  5. Player4Speed = 4
  6.  
  7. # Calculo la cantidad de jugadores y seteo y orden de turnos.
  8. l = 0
  9. while f"Player{l+1}Speed" in globals(): #verifico si la variable i+1 existe (ahora no hay error de try except)
  10. l+=1
  11. exec(f'Turn{l} = "Player{l}"') #seteo Turn1 directamente con el nombre del player
  12. j = l
  13. while 1 < j: #ordenamiento burbuja "inverso" directamente en la definición de variables
  14. if(eval(eval(f'Turn{j-1}') + str('Speed')) < eval(eval(f'Turn{j}') + str('Speed'))): #si el player actual es mas rapido que el anterior entonces ejecuto lo siguiente
  15. exec(f'Turn{j}, Turn{j-1} = Turn{j-1}, Turn{j}') #intercambio el player actual con el anterior
  16. else: #en caso contrario
  17. break #me salgo de este ciclo, ya que los anteriores estan ordenados
  18. j-= 1 #resto a j-1
  19.  
  20. #imprimir resultados
  21. i = 1
  22. while i <= l:
  23. print(f'Turn{i} = {eval("Turn" + str(i))}')
  24. i += 1
  25.  
« Última modificación: 9 Agosto 2021, 23:27 pm por 3n31ch » En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.180


Superhacker (es broma xD )


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #8 en: 11 Agosto 2021, 05:26 am »

No me da el cerebro para entender el código. ¿Podría alguien decirme los outputs de las 3 últimas partes? Gracias.
En línea

3n31ch


Desconectado Desconectado

Mensajes: 445


Grandes conocimientos engendran grandes dudas


Ver Perfil
Re: ¿Ordenar turnos por velocidad?
« Respuesta #9 en: 11 Agosto 2021, 05:34 am »

Te envíe un mensaje privado para ver si te lo puedo explicar por otro medio. No obstante no te entiendo. Te refieres a explicarte a detalle lo que pasa en la sección 3. bubble sort, 4. remplazo de velocidad y 5. impresión de resultados?
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
hacer el cambio de turnos automatico con un timer en una empresa
Programación Visual Basic
audioslave1401 3 2,793 Último mensaje 17 Diciembre 2009, 23:36 pm
por Angeldj27
Ayuda para establecer un sistema de turnos en un juego
Java
aahjnnot 3 9,503 Último mensaje 9 Junio 2011, 06:15 am
por dakomt
sistema de turnos php
PHP
kakashi20 2 3,256 Último mensaje 28 Junio 2013, 18:34 pm
por kakashi20
Turnos en C++
Programación C/C++
BrendiisFox 1 4,475 Último mensaje 27 Septiembre 2015, 12:04 pm
por ivancea96
Piscinas en fase 2: Las mejores webs para gestionar los turnos
Noticias
El_Andaluz 0 1,503 Último mensaje 5 Junio 2020, 00:25 am
por El_Andaluz
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines