Con las expresiones case , puedes controlar el flujo de un programa con una lista de opciones. La instrucción case en Verse te permite probar un valor de acuerdo con múltiples valores posibles (como si estuvieras usando =), y ejecutar el código en función de cuál coincide.
El uso de expresiones case se puede encontrar en todo tipo de aplicaciones, como en juegos donde hay un personaje no jugable (PNJ).
Por ejemplo, supongamos que utilizas el dispositivo generador de guardias para generar un guardia con su opción de patrulla habilitada. Después de que el guardia aparece en el juego, tiene algunos estados activos posibles, que incluyen Inactivo, Patrulla, Alerta, Ataque y Recolectar. Un diagrama de transición de estado de alto nivel para esto podría verse de la siguiente manera:
Puedes observar estas transiciones de estado en el juego.
En este video, el guardia tiene habilitada la opción de patrulla como comportamiento predeterminado.
En el video, el guardia pasa de patrullar la base científica a recolectar algunos recursos. Luego, el guardia ve al jugador, lo que envía al guardia a un estado de alerta (indicado por el signo de interrogación flotante) antes de entrar en su estado de ataque (indicado por el signo de exclamación flotante).
Según el estado en el que se encuentre el guardia, exhibirá ciertos comportamientos, y estos comportamientos generalmente se codifican como funciones que se llaman cuando el programa elige ingresar a un estado específico.
Como código, esta transición de estado de guardia de alto nivel podría verse así:
case(GuardStateVariable):
idle_state =>
RunIdleAnimation()
SearchPlayerCharacter()
harvest_state =>
GatherResources()
alert_state=>
RunAlertAnimation()
PlayAlertSound()
DisplayAlertUIElement()
Esta expresión case pasa una etiqueta que le dice al programa qué funciones ejecutar si el guardia entra en un estado específico.
En esta expresión, el patrol_state del guardia es el caso predeterminado porque un guardia con la patrulla habilitada debe ejecutar su comportamiento de patrulla predeterminado.
Sintácticamente, esto es lo mismo que:
expression0
case (test-arg-block):
label1 =>
expression1
label2 =>
expression2
_ =>
expression3 for the default case
expression4Cada patrón del bloque case, como label1 y label2, debe usar la forma constante => bloque, donde la constante puede ser un entero, una lógica, una cadena, un carácter o una enumeración. Por lo tanto, las instrucciones case solo funcionan con int, logic, string, char y enums.
Estructura
Estructuralmente, la expresión case de Verse ejecuta código en función de la entrada del bloque de argumento de prueba GuardStateVariable y, a nivel funcional, es equivalente a una secuencia de expresiones if.
En este ejemplo, el programa Verse ejecuta expression3 si GuardStateVariable se resuelve en alert_state. Si el programa pasa Patrol_state, Verse salta estructuralmente al caso predeterminado y ejecuta expression5.
Cómo usar case con otro control de flujo
Los bloques en una instrucción case pueden interrumpirse y continuar si dicha instrucción está dentro de un bucle. Los bloques de instrucciones case también pueden regresar desde la función en la que se encuentran.
Por ejemplo:
loop:
case (x):
42 => break
_ => {}Este bucle absurdo se completará inmediatamente si x = 42 o hará un bucle infinito.
Otro ejemplo:
Foo(x : int) : int =
case (x):
100 => return 200
_ => return 100Este ejemplo es equivalente a lo siguiente:
Foo(x : int) : int =
case (x):
100 => 200
_ => 100Esto se debe a que la instrucción case es la última expresión de la función.
Caso predeterminado
Las instrucciones case que no tienen un caso _=> (un caso predeterminado) fallarán si ninguno de los casos coincide. Está bien usar este tipo de instrucciones en contextos de falla (como funciones con el efecto decides).
Las instrucciones case que coinciden con todos los casos de una enumeración no producirán errores aunque no tengan un caso _=>.