Jump to content

Capítulo IX - Bucles


Recommended Posts

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!

Link to comment
Share on other sites

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

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

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

  • Dilong locked this topic
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...