ElRaulxX Posted August 30, 2013 Report Share Posted August 30, 2013 Ya hacía tiempo que no me dejaba ver por aquí... que mejor rebienvenida que un nuevo capítulo de nuestro curso quest. El curso parece que ha quedado algo muerto, intentaré reavivarlo y mejorarlo con nuevos capítulos y mejoras de los anteriores. Si a keko le apetece que me eche una mano, sino conmigo tenéis más que suficiente. Bueno, yendo al grano... este capítulo trata de los famosos bucles (loops) tan utilizados en programación y que quizá deberíamos haber tratado antes. Introducción Primero de todo, ¿qué es un bucle? Un bucle es un conjunto de sentencias que se repiten un número determinado (o indeterminado - bucles infinitos) de veces en nuestro programa. A diferencia de los seres humanos, la mejor característica de un PC no es su inteligencia (al fin y al cabo, no deja de ser una máquina diseñada por nosotros), sino su rapidez. Un ordenador puede procesar en un sólo segundo miles de órdenes; sería poco lógico no aprovechar esta característica en nuestros lenguajes de programación. El método (o mejor dicho, los métodos) que disponemos para utilizar esta característica son los bucles. Un bucle repetirá el bloque de sentencias asignadas hasta que la condición asignada sea verdadera. En lua disponemos de 4 tipos diferentes de bucles. Aunque los 4 tipos no dejan de hacer la misma acción, son diferentes entre si y nos vendrá mejor usar un tipo u otro según la finalidad que tengamos. repeat bloque until condición - bucle repeat while condición do bloque end - bucle while for var = start, stop [, step] do bloque end - bucle for numérico for var_1, ..., var_n in iterador do bloque end - bucle for genérico 1 - Bucle repeat Para los que estéis en el mundillo de la programación, este bucle equivale a la sentencia Do-While en C. La estructura del bucle es la siguiente: repeat bloque de sentenciasuntil (condición) El bloque (las acciones, funciones que defináis) se ejecutará al entrar al bucle hasta llegar a 'until (condición)'. Entonces se comprobará la condición definida. Si dicha condición no es verdadera se volverá al principio del bucle y se ejecutará de nuevo. Este proceso se repetirá hasta que la condición sea verdadera. Un ejemplo de uso de éste bucle es el siguiente: quest metin2zone begin state start begin when 20016.chat."Probando bucle repeat" begin say_title("Probando bucle repeat") local i = 0 --definimos una variable a verificar en la condición repeat i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito say(i) until (i == 10) --definimos una condición end --when end --stateend --quest Este ejemplo mostrará en pantalla lo siguiente: Probando bucle repeat12345678910 Como podéis comprobar, la primera vez que se entra al bucle la variable i se modifica su valor a 1 y, como la condición (1 == 10) es falsa, se repite el bucle. En el momento que el valor de i es 9 (ha ido aumentando en el bucle) nos encontraremos al principio del bucle, lo que hará que se modifique a 10 y, como la condición (10 == 10) es verdadera, el bucle finalizará. Teniendo todo esto en cuenta, para crear un bucle infinito (en el punto 6 podéis ver su utilidad en quest) con el bucle repeat deberíamos hacer lo siguiente: repeat bloqueuntil false A RECORDAR: La condición del bucle repeat se comprueba al final del bloque y las sentencias se repetirán hasta que la condición sea verdadera. Esto significa que el código se ejecutará por lo menos una vez. Para continuar el bucle la condición debe ser falsa. El bucle repeat no necesita ser cerrado con ningún end. 2 - Bucle while Para los que estéis en el mundillo de la programación, este bucle equivale a la sentencia While en C. La estructura del bucle es la siguiente: while (condición) do bloque de sentenciasend El bloque se ejecutará al entrar al bucle sólo si la condición es cierta. Esto significa que el bucle while será ignorado si la primera vez que se entra al bucle la condición es falsa. Tras entrar al bucle y llegar al final del bloque se comprobará la condición. Si dicha condición es verdadera se volverá a ejecutar el bloque. Este proceso se repetirá hasta que la condición no sea verdadera. Un ejemplo de uso de éste bucle es el siguiente: quest metin2zone begin state start begin when 20016.chat."Probando bucle while" begin say_title("Probando bucle while") local i = 0 --definimos una variable a verificar en la condición while (i != 10) do --definimos una condición i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito say(i) end --while end --when end --stateend --quest Este ejemplo mostrará en pantalla lo siguiente: Probando bucle while12345678910 Como podéis comprobar, se entra al bucle porque la variable i es diferente a 10. Al entrar al bucle la variable i se modifica su valor a 1 y, como la condición (1 != 10) es verdadera, se repite el bucle. En el momento que el valor de i es 9 (ha ido aumentando en el bucle) nos encontraremos al principio del bucle, lo que hará que se modifique a 10. Entonces (a diferencia del repeat) vuelve a comenzar el bucle pero, como la condición (10 != 10) es falsa, el bucle finalizará. Teniendo todo esto en cuenta, para crear un bucle infinito (en el punto 6 podéis ver su utilidad en quest) con el bucle while deberíamos hacer lo siguiente: while true do bloqueend A RECORDAR: La condición del bucle while se comprueba al principio del bloque y las sentencias se repetirán hasta que la condición sea falsa. Esto significa que el bucle puede ser ignorado y su código no ejecutado. Para continuar el bucle la condición debe ser verdadera. El bucle while debe ser cerrado con un end. 3 - Bucle for numérico La estructura del bucle es la siguiente: for var = start, stop [, step] do bloque de sentenciasend donde var es una variable, y start, stop y step son constantes. El bucle for es una abreviación de acciones que podrían hacerse con los anteriores dos bucles de una manera más tediosa. Veamos un ejemplo de su uso: quest metin2zone begin state start begin when 20016.chat."Probando bucle for numérico" begin say_title("Probando bucle for numérico") for i = 1, 10, 1 do say(i) end --for end --when end --stateend --quest Este ejemplo mostrará en pantalla lo siguiente: Probando bucle for numérico12345678910 Como habéis visto, hemos podido realizar las mismas acciones que en los anteriores bucles pero con una declaración mucho más sencilla. Lo que hace este bucle es asignar a una variable local (var) un valor numérico (start). El bucle se irá repitiendo y en cada repetición añadirá (sumará o restará) el valor de step a la variable var. El bucle finalizará cuando el valor de var sea mayor (si step es un número > 0) o menor (si step es un número < 0) que el valor de stop. Igual que pasa en el bucle while, la condición se evalua al principio del bucle. El valor de step puede ser omitido (for i = start, end do bloque end). En ese caso, step será siempre 1 (se sumará una unidad a la variable). La variable var puede tener cualquier identificador (como cualquier otra variable), aunque el nombre más común a poner es i. Esta variable es local, lo que significa que podemos llamarla dentro del bucle pero no fuera. Cuando finalice el bucle no podremos acceder a la variable utilizada. Este bucle se acostumbra a utilizar para recorrer tablas ya que es fácil de utilizar y de entender, aunque existe una forma más práctica con el bucle for genérico. A RECORDAR: Al iniciar el bucle se asigna a una variable un valor numérico. En cada vuelta del bucle se añadirá el valor del tercer argumento hasta que el valor de la variable sea igual al valor del segundo argumento. La sintaxis de este bucle es fácil de recordar ya que siempre es la misma. En caso de omitir el tercer argumento, el valor de este será 1 (se sumará siempre una unidad a la variable). La condición del bucle for numérico se comprueba al principio del bloque. El bucle for numérico debe ser cerrado con un end. 4 - Bucle for genérico La estructura del bucle es la siguiente: for var_1, var_2, ..., var_n in iterador do bloque de sentenciasend donde (var_1, var_2, ..., var_n) es un número cualquiera de variables y iterador es una función especial llamada iterador. Un iterador es aquella función utilizada en un for genérico que devuelve un determinado valor de la estructura que estemos recorriendo con el bucle. El valor que devuelve estas funciones especiales se asigna a (var_1, var_2, ..., var_n). Por lo tanto, el número de variables a declarar depende del iterador. Este bucle se utiliza principalmente en las tablas, por eso el uso de éste se explicará en detalle en otro capítulo del curso. Un ejemplo de uso de éste bucle es el siguiente: quest metin2zone begin state start begin when 20016.chat."Probando bucle for genérico" begin say_title("Probando bucle for genérico") local tab = {"valor1", "valor2", "valor3"} for k, v in ipairs(tab) do say(k.." = "..v) end --for end --when end --stateend --quest Este ejemplo mostrará en pantalla lo siguiente: Probando bucle for genérico1 = valor12 = valor23 = valor3 Como habéis visto, este bucle viene de perlas para recorrer tablas de una manera más fácil. Como ya he dicho, el uso adecuado de este bucle se explicará con más atención en otro capítulo; mientras podéis utilizar el bucle for numérico como os enseñó keko en el capítulo VIII. 5 - La palabra clave break Hasta ahora hemos visto que un bucle se repetía hasta llegar a una determinada condición. Lua dispone de una segunda manera más controlada por el programador para finalizar el bucle: la palabra clave break. Cuando dentro del bloque de sentencias el bucle se encuentre un break, el bucle finalizará automáticamente, independientemente del lugar y estado donde se encuentre el bucle. Veamos un ejemplo. El siguiente código quest metin2zone begin state start begin when 20016.chat."Probando bucle while" begin say_title("Probando bucle while") local i = 0 --definimos una variable a verificar en la condición while (i != 10) do --definimos una condición i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito if i == 3 then say("Estoy en la posición 3!") end say(i) end --while end --when end --stateend --quest mostrará en pantalla lo siguiente: Probando bucle while12Estoy en la posición 3!345678910 ¿Qué pasaría si cambiáramos say("Estoy en la posición 3!") por break? El código quedaría: quest metin2zone begin state start begin when 20016.chat."Probando bucle while" begin say_title("Probando bucle while") local i = 0 --definimos una variable a verificar en la condición while (i != 10) do --definimos una condición i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito if i == 3 then break end say(i) end --while end --when end --stateend --quest Y mostrará en pantalla esto: Probando bucle while12 ¿Qué ha pasado? Pues que el bucle a finalizado cuando se ha encontrado el break. 6 - Bucles infinitos en quest Antes os he hablado de bucles infinitos. ¿Qué utilidad tiene algo que no controlamos (se repetirá siempre)? Ninguna. ¿Pero y si lo combinamos con condiciones y break? Muchísima. Veamos un ejemplo: quest metin2zone begin state start begin when 20016.chat."Probando bucle while" begin say_title("Probando bucle while") while true do --definimos un bucle infinito local s = select("Opción 1", "Opción 2", "Salir") --añadimos un valor a s con la intervención del usuario if s == 1 then say("opción 1 seleccionada") --muestra opción 1 wait() elseif s == 2 then say("opción 2 seleccionada") --muestra opción 2 wait() else break --finaliza el bucle end end --while end --when end --stateend --quest Si lo ejecutamos veréis que nos ha quedado un pequeño menú que, ampliando vosotros mismos, puede llegar a ser un menú dinámico con múltiples opciones. Juntar esta técnica con tablas para obtener grandes resultados. Esta es una aplicación de un bucle infinito, podéis hacer con ellos lo que se os ocurra si lo entendéis correctamente. Changelog 30/08/13 19:26 - Primera publicación oficial del capítulo Y aquí llega el final del capítulo. Espero que os haya gustado. Cualquier duda que tengáis podéis ponerla en una respuesta a este post. PD: Más de 2000 palabras en este capítulo. Yeah! Rinnegan, Jfirewall, JazZ* and 1 other 4 Link to comment Share on other sites More sharing options...
Tiico™ Posted August 30, 2013 Report Share Posted August 30, 2013 Muy buén post, te lo agradesco. Por otro lado, yo entendi rapidamente ya que yo trabajo con los for = variable hace un tiempo, asi que no me costo entenderlo... Buen capitulo! y Bienvenido nuevamente al foro e.é Link to comment Share on other sites More sharing options...
rokvor Posted September 6, 2013 Report Share Posted September 6, 2013 No lo he pillado del todo bien, ¿podrias dar algunos ejemplo de, para que usarian los bucles en una quest? Link to comment Share on other sites More sharing options...
PACI Posted September 6, 2013 Report Share Posted September 6, 2013 Mira por ejemplo: quest ejemplo begin state start begin when login with pc.getqf("a") < 1 begin local item = {19, 29, 39} for i = 1, table.getn(item) do pc.give_item2(item end end end end quest ejemplo2 begin state start begin when login begin while pc.level < 75 do pc.give_exp2(pc.get_next_exp()) end end end end Te he dejado los mas usuales, los demás aún no he podido probarlos ya que estoy sin pc dr momento, así que es un poco dificil para mi darte un ej. con el while true, until, etc. Pero no es muy difícil. El con el while true la acción se ejecutará hasta q hagas break, el until la acción se repite hasta que la condición sea verdadera. Lo demás será probando xD Link to comment Share on other sites More sharing options...
rokvor Posted September 6, 2013 Report Share Posted September 6, 2013 Mira por ejemplo: quest ejemplo begin state start begin when login with pc.getqf("a") < 1 begin local item = {19, 29, 39} for i = 1, table.getn(item) do pc.give_item2(item end end end end quest ejemplo2 begin state start begin when login begin while pc.level < 75 do pc.give_exp2(pc.get_next_exp()) end end end end Te he dejado los mas usuales, los demás aún no he podido probarlos ya que estoy sin pc dr momento, así que es un poco dificil para mi darte un ej. con el while true, until, etc. Pero no es muy difícil. El con el while true la acción se ejecutará hasta q hagas break, el until la acción se repite hasta que la condición sea verdadera. Lo demás será probando xD No ando muy enterado en esto de las quest, en la opcion 2 entiendo que cuando eres nivel 75, te da mas exp (creo, como he dicho soy mal en esto aun) pero no le veo sentido a los bucles Link to comment Share on other sites More sharing options...
PACI Posted September 6, 2013 Report Share Posted September 6, 2013 Vale, sabes las quest esas de iniciar con items? En vez de estar siempre con el pc.give_item2 haces un array donde tenga los items que quieres dar, y después un for para que la función se repita X veces, que fue lo que hice. La segunda, enquanto el nivel del player sea menor que 75 te dará la exp necesaria para pasar de nivel hasta que llegues a 75. Link to comment Share on other sites More sharing options...
Recommended Posts