Go Go Go PowerRanger

Spoiler Alert: questo articolo parla dello scorso kata incrementale (RPG Inc) e coloro i quali vogliano farlo sono pregati di non leggere questo articolo fino a che non lo abbiano terminato.

Quindi… in seguito al kata dello scorso incontro ci siamo imbattuti in GO, un linguaggio fuori dal tempo.

Analizziamo la soluzione appunto in GO, partendo dalla stesura funzionante, ma non elegante (in fondo abbiamo visto il linguaggio per la prima volta appunto all’incontro del PUG):

Questo approccio parsa le righe del file come se fossero le righe di un CSV, anche se non lo sono propriamente, poi computa le due eccezioni possibili; le armi con il tipo e il danno con il range. Lo fanno controllando se il valore estratto dal csv inizia per parentesi tonda aperta [(]. In tal caso shifta di 1 gli indici a cui prenderà le entità dopo e trimma le parentesi chiuse di troppo. Questo per 2 volte. Ci eravamo ripromessi di refattorizzare il tutto in caso di una terza eccezione, perché il codice era arrivato al limite della manutenibilità

Letti i dati li abbiamo messi in una struct (non ne vedevo da anni), senza strutturare troppo questo contenitore di informazione. Anche qui ci eravamo ripromessi di strutturarlo di più appena la complessità si fosse alzata anche solo di poco, ma il kata è terminato prima 🙂

La simulazione del combattimento vera e propria è stata la parte più semplice. Un ciclo fino alla morte di uno o entrambi i giocatori. La stampa dello stato durante il combattimento è risultata un po’ insidiosa, perché i punti ferita stampati sono sempre nell’ordine giocatore1;giocatore2, mentre subito li avevamo stampati nell’ordine giocatore-attaccante;giocatore-attaccato.

Qui il sorgente

Sull’onda della curiosità per questo linguaggio ci siamo chiesti come scrivere “bene” questo codice così confuso. Abbiamo quindi ottenuto il seguente codice per il nostro main.go

package main

import (
 "rpgkata"
 "os"
)

func main() {
 filename := "combat.rpg"
 combat_stats := rpgkata.ReadFile(filename)
 players := rpgkata.Decode(combat_stats)
 os.Exit(rpgkata.Run(players))
}

Inoltre restituiamo un codice di uscita in base a chi ha vinto (o in caso di pareggio).

Abbiamo create 3 funzioni nel package rpgkata; ReadFile, Decode e Run

Abbiamo affinato la ReadFile, permettendole di gestire qualunque profondità di parentesi tonde annidate; abbiamo ottenuto di conseguenza una Decode più facile da scrivere e manutenere. Per la Run i cambamenti sono stati minimi, in quanto già partiva dall’oggetto Player che non abbiamo toccato.

Possibili evoluzioni anche qui sarebbero quelle alla struttura dati del giocatore e della sua arma, creando una struct per l’arma e mettendo nella struct del Player un puntatore all’arma usata. Ma abbiamo preferito provare a fare i test.

Ecco intanto i 3 file con le 3 funzioni.

http://pastebin.com/KwzJ6hCw
http://pastebin.com/ktAtkVSM
http://pastebin.com/ExUw9su7

Test.

Leggendo la documentazione di GO, abbiamo creato un primo test per la funzione ReadLine del file reader.go

http://pastebin.com/Fggk9xRh

Il test è volutamente semplice perché è un primo approccio a Go; abbiamo preso in prestito un paio di funzioni per determinare l’uguaglianza di oggetti, che fanno uso di reflection, dal magico mondo di internet. Il framework di test ha le funzionalità anche per i test paralleli, ma non ha gli assert di base che ci si aspetterebbe venendo da PHP o Python.

Alla fine il test parsa una stringa e asserisce che l’oggetto risultante sia uguale a quello creato nel test.

Soooo…… GOooooo ?

Quindi GO come linguaggio del futuro? No. È palesemente un linguaggio per chi deve scrivere codice che deve essere compilabile e di veloce esecuzione. Quindi non ci sembra un linguaggio di prototyping (come può essere Python), ma un linguaggio per software di produzione soggetti a pesante carico, con pero’ il vantaggio di potere essere molto più pulito da leggere di C o C++.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax