Facciamo una mappa di Dungeon


9

Molto tempo fa, quando passavo più tempo a giocare a giochi di ruolo, uno dei problemi che alcuni giocatori avevano, era tenere traccia dei movimenti del partito e disegnare una mappa adeguata. Quindi vengo con l'idea, per verificare come voi ragazzi venite ad affrontare questo problema.

Compito è scrivere una funzione, che accetta come elenco di parametri di input delle direzioni (passate come struttura a scelta) ^v<>, visualizzare la mappa del dungeon. Nell'esempio per input: >>>vvv<<<^^^output sarà:

+----+               +----+
|    |               |>>>v|
| ++ |               |^++v|
| ++ |  because      |^++v|
|    |               |^<<<|
+----+               +----+

Casi test

>>>>>>vvvvv<<<<^^^>>v



 +-------+
 |       |
 +-+---+ |
   |   | |
   | + | |
   | +-+ |
   |     |
   +-----+


^^^^^vvv<<<^^vv>>>>>>>>vv>><<^^^^v>>>>v^<^

          +-+ 
       +-+| | +-++-+
       | || | | ++ ++
       | ++ +-+     |
       |        +-+ |
       +--+ +-+ +-+-+
          | | |   |
          +-+ +---+

Dato che si tratta della sfida del codice golf, vince il codice più corto.

Buon golf.

EDIT Ci scusiamo per la modifica tardiva, non ho avuto molto tempo di recente.

La mappa viene generata in base al movimento. Dovrebbe contenere solo corridoi visitati durante la passeggiata. Quindi creare una grande stanza non sarà una risposta valida.

Esistono tre simboli validi nella mappa:

  • | parete verticale
  • | parete orizzontale
  • + intersezione di parete verticale e orizzontale.

La lunghezza massima del percorso è di 255 caratteri (ma se puoi, non limitarti).

Altri casi di test:

 ><><><><

 +--+
 |  |
 +--+

 >^<v

 +--+
 |  |
 |  |
 +--+

Spero che ora sia tutto chiaro.


3
È necessario fornire una descrizione dell'attività. I due casi di test non vengono nemmeno gestiti in modo coerente: il primo aggiunge una regione disconnessa senza motivo apparente.
feersum,

3
Il tuo secondo esempio ha una stanza chiusa, che inizialmente pensavo fosse perché il bordo esterno doveva essere rettangolare, ma poi il terzo esempio smentisce quell'idea. Si prega di utilizzare il Sandbox per ottenere feedback su una sfida prima di pubblicare.
El'endia Starman,

2
Eccellente. Suggerirei comunque di essere esplicito su come il dungeon è costruito dai movimenti.
El'endia Starman,

1
Cosa intendi con "visualizza mappa"? È consentita la restituzione della mappa da una funzione?
Paul Schmitz,

3
Questo sembra interessante. Qualche possibilità di modifica per riaprirla? Le cose da guardare in particolare: dagli esempi, sembra che non ti dispiaccia uno spazio extra attorno all'output ma sarebbe bene chiarire. Inoltre, se descrivi esplicitamente l'aspetto del muro e rispondi alla domanda del latte, la domanda dovrebbe essere sufficientemente chiara. Una cosa che penso non hai coperto è ciò vvv>>^^^<<che produrrebbe (incroci? Tubi?)
Dave,

Risposte:


3

Javascript (ES6), 261 254 243 byte

s=>{v=Array(w=32);p=526;b=n=>v[n>>5]&(1<<(n&31));B=(n,i)=>b(p+n)|b(p-n)?i:0;[...0+s].map(c=>v[(p+=[0,1,-1,w,-w]['0><v^'.indexOf(c)])>>5]|=1<<(p&31));for(z='',p=0;p<w*w;z+=' |-+'[b(p)?0:B(1,1)|B(w,2)||B(31,3)|B(33,3)],p++%w||(z+=`
`));return z}

JSFiddle


È possibile rimuovere il returnsostituendo il ;con ,e il {}con()
Cyoce

@Cyoce - C'è un forloop lì dentro che non può essere incorporato in quel modo.
Arnauld,

quindi sostituisci {con eval("e }con ")per rimuovere il ritorno codegolf.stackexchange.com/a/80967/41042
Cyoce

@Cyoce - Sfortunatamente, penso che dovrei sfuggire alla letterale interruzione di linea come '\\n'se lo facessi. Se conto correttamente, ciò porta effettivamente a +1 byte. O c'è un modo migliore per incorporare l'interruzione di linea nell'eval?
Arnauld,

Avresti bisogno solo \nperché le stringhe di template supportano letteralmente nuove righe, ma ciò lascerebbe comunque lo stesso conteggio di byte. Oh bene
Cyoce,

3

C, 246 byte

n,y,*g,*p;main(c,v)char**v;{for(n=c*2+3,g=calloc(n*n,8),p=g+(n+1)*(c+1);c--;y=*v[c],p-=(y>70?n:1)*(y%5%4?-1:1))*p=1;for(y=n-1;--y;)for(c=n-1;c--;putchar(c?" |-++|-+"[*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4]:10))p=g+y*n+c;}

Accetta input come caratteri separati, ad esempio:

./mapper '>' '>' '>' 'v' 'v' 'v' '<' '<' '<' '^' '^' '^'

O più convenientemente, questo formato (intenzionalmente non quotato!):

./mapper $(echo '>>>vvv<<<^^^' | fold -w1)

O per input casuale (piuttosto inefficiente):

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 10 | fold -w1)

E infine, usare awkper ritagliare il risultato significa che possiamo diventare molto più grandi:

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 500 | fold -w1) | awk '/[^ ]/{l=match($0,"\\+");if(l&&(l<L||!L))L=l;v[i++]=$0}END{for(;j<i;){l=v[j++];print substr(l,L,match(l," *$")-L)}}'

 +-----+
 |     |
 |     +-+  +-----+
 |       |+-+     |
++       +|      ++
|         |      |
|         +      +-+
+--+               |
 +-+               +--+
 |     ++             |
 +-+  +-++           +-+
   ++   |+--+          |
    +-+ | |        ++  |
     ++ | ++   + +--+ ++
     |  |  +---|      |
     |  |     ++  +---+
     ++ |-+   |   |
      | | +--+-+  |
      | +    +    |
      |        +--+
      +--------+

Emette su stdout. Usa il fatto che è consentito il padding attorno alla mappa (produce una mappa che ha la lunghezza del bordo 2 * n + 1, mettendo la posizione finale al centro).

Abbattersi

Questo funziona ripetendo ciclicamente gli argomenti al contrario e spostandosi al contrario. In realtà utilizza il fatto che arg 0 è il nome del programma; non importa quale sia il nome, ma ci consente di visitare sia la cella iniziale che l'ultima (nonché tutte le celle in mezzo) senza bisogno di una gestione speciale.

n,                                  // Size of internal grid
y,                                  // Loop counter / current character
*g,                                 // Internal grid memory
*p;                                 // Current working pointer
main(c,v)char**v;{                  // K&R style function declaration
    for(                            // Step 1: identify visited cells
        n=c*2+3,                    //  Set output grid size
        g=calloc(n*n,8),            //  Allocate map storage space
        p=g+(n+1)*(c+1);            //  Start at centre
        c--;                        //  Loop over directions in reverse
        y=*v[c],                    //  Get current direction
        p-=(y>70?n:1)*(y%5%4?-1:1)  //  Move in reverse
    )*p=1;                          //  Mark cell visited
    for(y=n-1;--y;)                 // For each row (except edges)
        for(c=n-1;c--;              //   For each column (except edges, +1 for \n)
            putchar(c?" |-++|-+"[   //   Print wall using lookup table
                *p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4
            ]:10)                   //   Or newline
        )p=g+y*n+c;                 //   Set current cell (happens first)
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.