 /*
  * ACME inc 2000
  * no warranties at all.
  * @TITLE Rope Land Doc
  * @AUTHOR R.Corda (roberto.corda@inferentia.it)
  * @VERSION v0.4.1.11052000
 */

Cosa e' Ropeland

E' la simulazione di un mondo popolato da animaletti che si muovono si riproducono
e mangiano. Si possono trovare altre informazioni su ropeland nel newsgroup it.comp.ai
e nel sito http:\\www.geocities.com\gnammyland. 

Installazione:
Unzippare i file ropelandXXXb.zip (cioe' l'insieme degli eseguibili) in una directory 
qualsiasi, aprire una sessione dos (prompt msdos in programmi in start[avvio])
spostarsi nella directory suddetta e scrivere go (e dopo battere invio :-)
NB essendo ancora instabile potrebbe bloccarsi (1) in questo caso:
schiacciare il tasto windows, tasto destro mouse sull'icona del programma,
scegliere l'opzione chiudi.

(1) si dice anche: incaponirsi, impiantarsi, hangare, impantanarsi, 
    morire etc..

Uso
State a guardare sinche' non vi stancate, dopo di che schiacciate un
tasto qualsiasi, la simulazione terminera'. E' probabile (in funzione del tempo 
di delay messo mentre programmavo) che la simulazione finisca molto in fretta o
che sia molto lento.
 Se siete piu' curiosi guardate i file di esempio
default.inc tree.asm e lamb.asm (piu' la descrizione che segue del
linguaggio rl) e createvi il vostro universo privato
(nel qual caso mandatemi delle copie del lavoro fatto per favore)
Se invece di go fate partire debug.bat vedrete la macchina virtuale di rl 
in azione. 
Altro file di esempio e' speak.inc che carica talking.asm 
Va richiamato con uno tra i comandi

ropeland -nograph speak.inc
ropeland -match speak.inc
ropeland -debug speak.inc

Compilazione
Procuratevi DJGPP e in particolare Allegro (che e' una libreria
di routine grafiche) unzippate il file ropelandXXXs.zip, create un 
progetto con ropegui.c rope.c ropeasm.c, se usate rhide mettete tra 
librerie usate  alleg, oppure compilate con gcc con l'opzione -lalleg.
Se scoprite/fate/impastrocchiate qualcosa di interessante fatemelo
sapere.
Allegro e DJGPP possono essere trovati sul sito www.delorie.com o in uno dei
mirror. (Io in realta' l'ho preso dal cd contenuto in una rivista per motivi
di praticita')

files

*files .asm*
contengono i programmi nel linguaggio macchina di ropeland (rlm o rl)
la struttura deve essere

ACME_inc

@TITLE titolo_tutto_attaccato
@AUTHOR nome_tutto_attaccato
@VERSION 0.0_tutta_attaccata

begin
<codice>
end

NB
- la correzione sintattica e' quasi nulla, quindi mettere il numero
sbagliato di parametri o sbagliare il nome di un comando rendera' impossibile 
il caricamento del file senza ulteriori segnalazioni di errore.
- #12 significa "il numero 12"
- 12 significa "il valore contenuto nella variabile numero 12"
- Titolo autore e versione sono facoltativi ma se presenti devono
comparire in quest'ordine.

* files .masm *
come i precedenti piu' la dichiarazione di label e variabili. Non sono
direttamente caricati da ropeland servono solo da documentazione
al file .asm associato. (in parole povere: per fare i file .asm
ho scritto prima i file .masm che poi ho compilato in .asm a mano)

*files .inc
Contengono lo stato iniziale dell'universo ropeland con posizioni
e parametri degli oggetti.
la struttura del file e'

ACME_inc

@TITLE titolo_tutto_attaccato
@AUTHOR nome_tutto_attaccato
@VERSION 0.0_tutta_attaccata

begin
  file: nome.asm number: <numero di quelli di questo tipo>
  file: nome1.asm number: <numero di quelli di questo tipo>
  ..
  
  <elenco parametri per tutti quelli del primo tipo>
  ( father_id: GOD mother_id: GOD type: TREE erg: 100 weight: 42 
    x: 3 y: 3 )
  ..
  <elenco parametri per tutti quelli del secondo tipo>
  ( father_id: GOD mother_id: GOD type: LAMB erg: 10000 weight: 42 
    x: 3 y: 15 )
  ...
  <rocce ROCK nb: erg == 0 significa che l'oggetto e' inamovibile>
  ( father_id: GOD mother_id: GOD type: ROCK erg: 10000 weight: 42 
    x: 3 y: 15 )
end

guardare default.inc per un esempio
NB anche qui la correzione sintattica e' molto scarsa quindi il minimo errore
porta al mancato caricamento del file o a comportamenti bizzarri.
NB2 devo ancora decidere come strutturare questi file, accetto consigli.

*parametri ropeland

-nograph 
come match solo che l'interfaccia e' a caratteri.

-match 
(parzialmente implementato)
scontro tra 2 o piu' elementi, i programmi non variano con la
duplicazione, [non ancora implementato] esiste un sistema di
punteggi che decide quale oggetto (o quale squadra) ha vinto.
[fix: dovrebbe essere vietata la duplicazione in questa modalita']

-darwin
(non implementato)
gli oggetti evolvono (cambia nel tempo il loro programma).

-debug
come -match solo che invece che il campo da gioco vengono visualizzati
i comandi eseguiti.

-single
come debug solo che carica un singolo oggetto .asm con parametri
di default stabiliti.
fix: in una prossima versione voglio che si possano passare i parametri

-ver
stampa la versione e' il copyright del programma

descrizione del progetto
-------------------------------------------------------------
Rope Land: 
 spazio bidimensionale LATO * LATO formato da caselle(x,y)

Caselle:
ogni casella e' caratterizzata da
-posizione
-oggetto contenuto
-segnali presenti (parlato udibile)
-quando il segnale e' stato emesso (i segnali decadono col tempo)

Oggetti in RL: 
ogni oggetto e' definito dal suo
-id 
-data creazione (in tic)
-id padre (id = GOD se non esiste un padre )
-id madre (non utilizzato)
-tipo in (carnivori, erbivori, massi,piante)
-peso (non utilizzato)
-posizione (x,y) in [0..LATO-1]
-inerzia (movimento pregresso)
-direzione dello spostamento per inerzia

gli oggetti viventi (carnivori, erbivori,piante aka LION,LAMB,TREE)
-energia (intero positivo)
-status (vivo, morto)
-comportamento (cioe' il programma in rl)

le rocce (ROCK) non hanno un programma associato, al momento 
energia == 0 significa che sono amovibili (non possono essere spostate). La loro 
energia esprime in qualche modo [fix] il loro peso cioe' l'energia necessaria per 
spostarli.

il programma e definito come:
-stato
-programma

i viventi muoiono quando la loro energia va a zero o
[fix: da implementare] se avviene un errore di programma (dell'rl/asm intendo :-)
i viventi una volta morti perdono energia progressivamente sino a scomparire
----------------------------------------------------------------------
la grammatica del linguaggio ropelm (linguaggio macchina)

esempio:

load 0 1
load 1 1
move 0
if 1 1
halt


comandi linguaggio assembler rl
-----------------------------------------------------------------------
Semantica comandi:

*sinopsi:  move ( MDIR , ERG) ; 
*comando RLM: move OUT MDIR ERG 
*descrizione: si muove nella direzione indicata se lo spazio e' libero o se riesce
  a spostare l'elemento bloccante, se qualcosa blocca il passaggio l'energia
  (misurata in ropeton) viene trasferita all'oggetto bloccante
  NB (per i fisici) energia viene qui e nel seguito usata in modo improprio e riassume 
  in se' il significato di *energia* vera e propria (in particolare cinetica) e *forza*.
  [fix: La fisica di ropeland deve essere meglio definita] vedi *fisica di ropeland* per 
  ulteriori particolari.
*restituisce: OK == 0 ,se si e' effettivamente mosso [fix: i diversi valori restituiti
  in caso contrario sono da stabilire]

*sinopsi speak ( WHAT , ERG) ; 
*comando RLM: speak WHAT ERG
*descrizione: dice qualcosa diffondendolo sino a una certa
 distanza, cioe' con una certa energia. La diffusione e' spiraliforme in senso orario
 attorno all'oggetto, mettere il segnale in una casella costa un erg. L'oggetto puo'
 morire a causa deli'urlo. 
*restituisce: nulla ;

*sinopsi: ear ( ) ; 
*comando RLM: ear OUT
*descrizione: legge i segnali presenti nella posizione corrente
*restituisce: segnale

*sinopsi: see ( DIR ) ; 
*comando RLM: see OUT DIR
*descrizione: guarda in una certa direzione, (nord, nord-ovest, ovest ...)
*restituisce: i tipi di oggetto piu' vicini lungo le tre linee visuali
parallele, sono caricati nei tre indirizzi contigui a partire da out
in rl.

*sinopsi: radar ( DIR ) ; 
*comando RLM: see OUT DIR
*descrizione: guarda in una certa direzione, le direzioni sono le
tre parallele alle direzioni che passano per l'oggetto.
*restituisce: la distanza (in caselle) del primo oggetto incontrato

*sinopsi: dup ( MDIR , ERG) ; 
*comando RLM: dup OUT MDIR ERG
*descrizione: duplica l'oggetto nella direzione indicata fornendogli una certa energia
iniziale, il parto prevede uno spreco di energia pari alla lunghezza del programma
piu' l'energia fornita al figlio (fix: non ancora implementato, per adesso quantita'
fissa), puo' morire nel tentativo.
*restituisce: vero se andato a buon fine 
  
*sinopsi:  eatv ( MDIR ) ; // solo per animali erbivori
  eatm ( MDIR ) ;  // solo per animali carnivori
  eatl ( ) ;  |     // solo per vegetali
*comando RLM: eatv OUT MDIR; eatl OUT
*descrizione: mangia quanto a destra, se c'e' qualcosa a destra e se e' del giusto tipo
  se l'oggetto che mangia e' del giusto tipo
*restituisce: ropeton di energia prelevati (0 se fallito cioe' falso)

*sinopsi:  feed ( MDIR , ERG) ;
*comando RLM: feed MDIR ERG
*descrizione: passa dell'energia (erg) a quanto ha a destra, puo' morire nel tentativo.
*restituisce: nulla


i parametri sono solo interi positivi, e si intendono o come nomi di variabili, ovvero
puntatori (indici) alle variabili dello stato, o come valori veri e propri

Descrizione della fisica di ropeland [da migliorare]
--------------------------------------------------------------------------------------
Ropeland ha una fisica, ovvero un corpus di leggi che stabilisce in che
modo gli oggetti si muovono a causa delle "spinte" ricevute, quindi per meglio
dire ha una sua dinamica. Le leggi di ropeland non sono quelle Newtoniane (le tre 
leggi della dinamica) sono piuttosto una loro versione semplificata che in realta' 
assomiglia piu' alle leggi fisiche aristoteliche.  
Mi sono preso molte liberta' anche per quanto riguarda la 
termodinamica di ropeland visto che l'energia si conserva solo approssimativamente.
(premessa seriosa per fisici pedanti)

Innanzitutto ropeland e' bidimensionale due oggetti non possono essere uno
"sopra" l'altro, in ogni casella ci puo' essere solo un oggetto (incompenetrabilita'
dei corpi) i movimenti sono sempre e comunque soggetti ad attriti, ropeland
e' un mondo chiuso solo in apparenza visto che esiste un "sole" che lo illumina
e che permette agli alberi (TREE) di crescere (eatl == eat light = mangia luce).

Il concetto di energia di forza e di massa sono in ropeland riuniti nell'unico
concetto di *energia* che si misura in erg (nella fisica vera gli erg misurano
solo la forza).

Ogni oggetto ha tra gli attributi una direzione (dir) e una inerzia (inerzia)
che ne stabiliscono il cosiddetto "movimento per inerzia". La quantita' di
inerzia (nella fisica vera sarebbe l'energia cinetica) viene progressivamente
e linearmente persa durante il percorso fatto, cioe' per ogni casella percorsa
viene sottratta una quantita' costante di energia dipendente dal peso. [fix:
cosa e' il peso e' ancora da stabilire]
Il peso e' funzione dell'energia totale dell'oggetto vivente, altrimenti
e' una costante.

quindi diciamo che A spinga B con energia x e che B pesi p

se x<p la direzione viene invertita e l'inerzia passa a A
      (azione e reazione urto elastico) se B non e' vivente
      altrimenti si fanno dei danni a B (da stabilire con piu' precisione)
se x=p B si muove di una casella nella direzione indicata A passa tutta l'energia
       e non si muove.
se x>p B si muove di una o piu' caselle nella direzione 
      indicata a seconda del valore di x, ad ogni casella perde una certa
      quantita' di inerzia, A rimane fermo.

Queste leggi sono state scelte in modo che sia possibile
-lanciare pietre
-prendere a *capocciate* oggetti danneggiandoli (sino ad ucciderli)

Per quanto riguarda la visione tutti gli oggetti sono opachi e gli ostacoli
bloccano i segnali (suoni)


Linguaggio Macchina Rope Land (rlm o solo rl)
-------------------------------

Tutte le variabili segnate come di tipo OUT (valore restituito) sono puntatori
a variabile quindi il valore di OUT sara' contenuto in .vars[OUT]
i valori sono segnalati dal cancelletto (#) e i puntatori (o indici che dir
si voglia) dalla sua assenza.
Quindi

add #0 #1 #1
significa (in pseudo linguaggio)
vars[0] = 1 + 1

add 0 #1 #1
diventa
vars[vars[0]] = 1 + 1

if #0 #10 
diventa 
if (0) goto 10

if 0 #10
diventa
if (vars[0]) goto 10

notare che rlm segue lo stesso criterio del c per cui 
0 == falso
non-zero == vero

-------------------------------
// flusso
load OUT VALUE
if COND WHERE 
halt

// matematici
add OUT VALUE VALUE
sub OUT VALUE VALUE
inc OUT
dec OUT

// logici
// OUT = (VALUE <cmp> VALUE)
and OUT VALUE VALUE
or OUT VALUE VALUE
not OUT VALUE
lt OUT VALUE VALUE
eq OUT VALUE VALUE 

// movimento
move OUT DIR ERG

// I/O ambiente
speak WORD ERG
ear OUT

// mettono i tre valori restituiti nelle tre posizioni a partire da OUT
see OUT DIR
radar OUT DIR

// biologici
dup OUT DIR ERG
eatv OUT DIR
eatm OUT DIR
eatl OUT
feed DIR ERG

// personali
// prende le variabili dell'oggetto e le mette in una posizione 
// in memoria
father OUT
type OUT
erg OUT
id OUT
birth OUT

// di sistema
// fix: potrebbero esserci  notte e  giorno, le stagioni e il maltempo
// tempo passato
tic OUT
rand OUT RANGE
----------------------
