Con le espressioni case, puoi controllare il flusso di un programma da un elenco di scelte. L'istruzione case in Verse è un modo per testare un valore rispetto a più valori possibili (come se si stesse utilizzando =) ed eseguire il codice in base a quello corrispondente.
L'utilizzo di espressioni case si può trovare in tutti i tipi di applicazioni, come nei giochi in cui è presente un personaggio non giocabile (PNG).
Ad esempio, supponiamo di utilizzare il dispositivo Generatore di guardie per generare una guardia con l'opzione di pattuglia abilitata. Dopo che la guardia si è generata nel gioco, ha alcuni possibili stati attivi, tra cui Inattivo, Pattuglia, Allerta, Attacco e Raccolto. Un diagramma di transizione di stato di alto livello per questo potrebbe essere simile al seguente:
Puoi osservare queste transizioni di stato nel gioco.
In questo video, la guardia ha la sua opzione di pattuglia abilitata come comportamento predefinito.
Nel video, la guardia passa dal pattugliamento della base scientifica alla raccolta di alcune risorse. Quindi la guardia individua il giocatore che manda la guardia in uno stato di allerta (indicato dal punto interrogativo sospeso) prima di entrare nello stato di attacco (indicato dal punto esclamativo sospeso).
A seconda dello stato in cui si trova la guardia, mostrerà determinati comportamenti e questi sono tipicamente codificati come funzioni che vengono chiamate quando il programma sceglie di entrare in uno specifico stato.
Come codice, questa transizione di alto livello dello stato di guardia potrebbe essere simile al seguente:
case(GuardStateVariable):
idle_state =>
RunIdleAnimation()
SearchPlayerCharacter()
harvest_state =>
GatherResources()
alert_state=>
RunAlertAnimation()
PlayAlertSound()
DisplayAlertUIElement()
Questa espressione case passa un'etichetta che indica al programma quali funzioni eseguire se la guardia entra in uno specifico stato.
In questa espressione, il patrol_state della guardia è il case predefinito perché una guardia con pattuglia abilitata deve eseguire il comportamento di pattuglia predefinito.
Sintatticamente, questo è lo stesso di:
expression0
case (test-arg-block):
label1 =>
expression1
label2 =>
expression2
_ =>
expression3 for the default case
expression4Ciascun pattern nel blocco case, come label1 e label2, deve utilizzare il formato constant => block, dove la costante può essere una costante integer, logic, string, char o enum. Quindi le istruzioni case funzionano solo con int, logic, string, char ed enums.
Struttura
Dal punto di vista strutturale, l'espressione Verse case esegue il codice basato sull'input del blocco di argomenti di test GuardStateVariable e da quello funzionale opera come una serie di espressioni if.
In questo esempio, il programma Verse esegue expression3 se GuardStateVariable si risolve in alert_state. Se il programma passa in patrol_state, Verse passa strutturalmente al case predefinito ed esegue expression5.
Utilizzo di case con un altro flusso di controllo
I blocchi in un'istruzione case possono interrompersi e continuare se l'istruzione case è all'interno di un loop. Anche i blocchi di istruzioni case possono tornare dalla funzione in cui si trovano.
Ad esempio:
loop:
case (x):
42 => break
_ => {}Questo loop assurdo terminerà immediatamente se x = 42 o si ripeterà per sempre.
Un altro esempio:
Foo(x : int) : int =
case (x):
100 => return 200
_ => return 100Questo esempio equivale a:
Foo(x : int) : int =
case (x):
100 => 200
_ => 100Questo perché l'istruzione case è l'ultima espressione della funzione.
Case predefinito
Le istruzioni case che non hanno un case _=> (predefinito) danno esito negativo se nessuno dei case corrisponde. È possibile utilizzare tali istruzioni case in contesti di errore (come le funzioni con l'effetto decides).
Le istruzioni case che corrispondono a tutti i case di un'enumerazione non hanno esito negativo pur non avendo un case _=>.