Track
/
Crystal
Crystal
/
Esercizi
/
Partita a scacchi
Partita a scacchi

Partita a scacchi

Esercizio di apprendimento

Introduzione

Gli intervalli rappresentano l'insieme dei valori compresi tra due estremi. I tipi più comuni che supportano gli intervalli sono Int, Char e String. Si possono usare per molte cose, come creare rapidamente una collezione, estrarre sottostringhe, controllare se un valore è compreso in un intervallo e iterare. Si creano con l'operatore di intervallo .. o ... (rispettivamente inclusivo ed esclusivo).

1..5  # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4

Il motivo per cui esistono due operatori di intervallo è poter creare intervalli che includono o escludono il valore finale: una cosa utile, per esempio, quando si lavora con indici che partono da zero.

Gli intervalli si possono anche creare usando l'inizializzatore Range.

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

Quando crei un intervallo in Crystal con gli operatori .. o ... e vuoi chiamare un metodo su quell'intervallo, devi racchiuderlo tra parentesi. Altrimenti il metodo verrà chiamato sul secondo argomento dell'operatore di intervallo.

(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32

Ottenere sottostringhe

Quando vuoi estrarre una parte di una stringa, puoi usare l'operatore di intervallo per ottenere una sottostringa. Basta creare un intervallo con l'indice iniziale e quello finale della sottostringa.

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

Puoi anche usare indici negativi per ottenere la sottostringa dalla fine della stringa.

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

Metodi degli intervalli

Gli intervalli hanno una serie di metodi con cui lavorare. Per esempio, questi metodi permettono di ottenere la somma di tutti i valori dell'intervallo o di verificare se l'intervallo include un valore.

Metodo Descrizione Esempio
sum Restituisce la somma di tutti i valori dell'intervallo (1..5).sum # => 15
size Restituisce la dimensione dell'intervallo (1..5).size # => 5
includes? Restituisce true se l'intervallo include il valore dato, altrimenti false (1..5).includes?(3) # => true

Intervalli senza fine e senza inizio

Un intervallo può essere senza fine e senza inizio. In un intervallo senza fine o senza inizio il valore iniziale o quello finale è nil, ma nil può essere omesso quando si definisce l'intervallo.

Usare intervalli senza inizio e senza fine è utile quando vuoi, per esempio, estrarre una parte di stringa dall'inizio o fino alla fine.

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Caution

Se non viene usato su una collezione, un intervallo senza fine può generare una sequenza infinita, se non lo si usa con cautela.

Intervalli di Char

I caratteri si possono usare negli intervalli e permettono di ottenere un intervallo di caratteri compreso tra due caratteri. Per esempio, può essere comodo quando vuoi ottenere l'alfabeto.

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

Intervalli di stringhe

Anche le stringhe si possono usare negli intervalli, il che permette di ottenere un intervallo di stringhe tra due stringhe. Il comportamento però è un po' diverso da quello di Char quando in un intervallo di stringhe si usano più caratteri. Con gli intervalli di stringhe più complessi il comportamento può diventare confuso, quindi fai attenzione.

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

Istruzioni

Da appassionato di scacchi, vuoi scrivere la tua versione del gioco. Certo, online ci sono già tantissime implementazioni degli scacchi, ma la tua sarà unica!

Inizi implementando un sistema di movimento di base per i pezzi.

La partita di scacchi si giocherà su una scacchiera di otto caselle di larghezza e otto caselle di lunghezza. Le caselle sono identificate da una lettera e da un numero.

1. Definisci l'intervallo di traverse e colonne

Il gioco dovrà memorizzare le traverse della scacchiera. Le traverse sono le righe della scacchiera e sono numerate da 1 a 8.

Il gioco dovrà anche memorizzare le colonne della scacchiera. Le colonne sono disposte in verticale e sono identificate dalle lettere dalla A alla H.

Definisci le costanti Chess::RANKS e Chess::FILES, che memorizzano rispettivamente l'intervallo delle traverse e quello delle colonne.

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. Verifica se una casella è valida

Il gioco dovrà verificare se una casella è valida. Una casella è valida se la traversa e la colonna rientrano negli intervalli delle traverse e delle colonne.

Definisci il metodo Chess.valid_square?, che prende gli argomenti rank, che contiene un numero intero che rappresenta la traversa, e file, che contiene un carattere che rappresenta la colonna. Il metodo deve restituire true se la traversa e la colonna rientrano nell'intervallo delle traverse e delle colonne, e false in caso contrario.

Chess.valid_square?(1, 'A')
# => true

3. Ottieni il soprannome del giocatore

Il gioco dovrà ottenere il soprannome del giocatore. Il soprannome è formato dai primi due caratteri del nome del giocatore e dagli ultimi due caratteri del suo cognome. Il soprannome deve essere scritto in maiuscolo.

Definisci il metodo Chess.nickname, che prende gli argomenti first_name, che contiene una stringa con il nome del giocatore, e last_name, che contiene una stringa con il cognome del giocatore. Il metodo deve restituire il soprannome del giocatore come stringa in maiuscolo.

Chess.nickname("John", "Doe")
# => "JOOE"

4. Crea il messaggio di una mossa

Il gioco dovrà creare un messaggio per una mossa, per indicare quale giocatore si è spostato su quale casella. Il messaggio deve usare il soprannome del giocatore e la casella su cui si è spostato. Il gioco deve anche determinare se la mossa è valida, verificando se la colonna e la traversa della casella rientrano negli intervalli delle colonne e delle traverse.

Se la mossa è valida, il messaggio deve essere: "{nickname} moved to {square}" Se la mossa non è valida, il messaggio deve essere: "{nickname} attempted to move to {square}, but that is not a valid square"

Definisci il metodo Chess.move_message, che prende gli argomenti first_name, che contiene una stringa con il nome del giocatore, last_name, che contiene una stringa con il cognome del giocatore, e square, che contiene una stringa con la casella su cui il giocatore si è spostato. Il metodo deve restituire il messaggio della mossa come stringa.

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Crystal Exercism

Vuoi iniziare Partita a scacchi?

Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.