Costruisci un motore per un gioco del labirinto


9

Questo è il seguito di Print a labirinto . Se ti piace questa domanda, aggiungi altri algoritmi di generazione del labirinto;).

Per questo compito dovrai implementare un motore di gioco per un giocatore che deve trovare il tesoro in un labirinto ed uscire dalla prigione.

Il motore si avvia leggendo il labirinto dall'input standard seguito da una riga contenente un .(punto) un file fornito come argomento nella riga di comando. Successivamente il giocatore @viene posizionato in una posizione casuale sulla mappa. Quindi il motore inizia a interagire con il lettore tramite io standard:

Comandi dal motore al giocatore :

  • continue: Gioco non terminato. I dintorni sono stampati seguiti da a .. Il giocatore è rappresentato dal @personaggio. Le celle non osservabili sono rappresentate da ?.
  • finished: Gioco finito. Viene stampato il numero di passaggi e il gioco si interrompe.

Comandi dal giocatore al motore :

  • north: Sposta il giocatore verso l'alto.
  • south: Sposta il giocatore verso il basso.
  • west: Sposta il giocatore a sinistra.
  • east: Sposta il giocatore a destra.

Qualsiasi comando non valido (come colpire un muro) dal giocatore viene ignorato, ma viene comunque conteggiato. Sei libero di definire l'ambiente che preferisci.

  • Punti per il codice più breve.
  • Punti per ambienti complessi (ad esempio, stampa di aree estese e sostituisci celle non visibili ?).
  • Nessun punto per il codice che non rispetta il formato io

Esempio :

In questo esempio l'ambiente circostante è definito come la cella 3x3 con il giocatore al centro.

$ cat maze
+-+-+
  |#|
|   |
+---+
$ python engine.py maze
 |#
 @ 
---
.
east
|#|
 @|
--+
.
north
+-+
|@|
  |
.
south
|#|
 @|
--+
.
west
 |#
 @ 
---
.
west
  |
|@ 
+--
.
north
+-+
 @|
|  
.
west
finished
7

@Alexandru: cosa stiamo usando per generare i nostri labirinti? Possiamo usare gli algoritmi del labirinto di altre persone (ovviamente con il dovuto credito)? O dobbiamo completare il tuo primo incarico?
Snmcdonald,

@snmcdonald: errore di battitura fisso. Usa i labirinti di altre persone. Ricorda che il motore legge il labirinto dall'input standard.
Alexandru,

Questo blog contiene articoli eccellenti sulla generazione di labirinti utilizzando algoritmi vari e misti weblog.jamisbuck.org Scopri l'algoritmo dell'albero in crescita in particolare weblog.jamisbuck.org/2011/1/27/…
Dve

Sono confuso su come sia il labirinto che l'interazione dell'utente provengano dall'input standard. L'utente dovrebbe digitare il suo labirinto e poi risolverlo? Kinda sconfigge lo scopo di mostrare solo una parte del labirinto ...
Keith Randall

Puoi creare un'app (questa attività è lasciata per un'altra domanda) sopra di essa per separare l'input del labirinto dall'input dei comandi.
Alexandru,

Risposte:


7

C99, 771 caratteri

#include <ncurses.h>
#include <string.h>
#define MIN(A,B) (A<B?A:B)
#define MAX(A,B) (A>B?A:B)
#define T(C,X,Y) case C:if((m[x+X][y+Y]==' ')||(m[x+X][y+Y]=='#'))x+=X,y+=Y;s++;break;
char m[24][81],M[24][81];int i,j,I=0,J,x,y,s=0;
int main(int c,char**v){FILE*f=fopen(v[1],"r");
for(I=0;fgets(m[I],80,f);I++)J=MAX(J,strlen(m[I]));
J--;f=fopen("/dev/random","r");do{x=fgetc(f)%I;y=fgetc(f)%J;}
while(m[x][y]!=' ');initscr();curs_set(0);do{
switch(c){T('e',0,1)T('n',-1,0)T('s',1,0)T('w',0,-1)}
for(i=MAX(0,x-1);i<MIN(x+2,I);i++)for(j=MAX(0,y-1);j<MIN(y+2,J);j++)M[i][j]=1;
for(i=0;i<I;i++)for(j=0;j<J;j++)mvaddch(i,j,M[i][j]?m[i][j]:'?');
mvaddch(x,y,'@');refresh();}while((m[x][y]!='#')&&(c=getch())!='q');
if(m[x][y]=='#')mvprintw(I,0,"Finished in %d steps!",s),getch();endwin();}

Richiede e utilizza ncurses. Solo una macro per lunghezza, e le macro N e M sostituiranno gli oppositori minimo e massimo mancanti, e non credo che ci sia molto altro da fare al riguardo.

Presuppone che il labirinto di input non superi gli 80 caratteri e che il nome del file di un labirinto sia stato passato sulla riga di comando e che il numero di parametri sia sufficientemente basso da rendere il valore iniziale di c non un comando di movimento.

  • Devia dallo standard in quanto richiede comandi di direzione a singolo carattere come la prima lettera minuscola di quelli suggeriti.

  • Mostra le regioni sconosciute come '?'.

Più leggibile con i commenti:

#include <ncurses.h>
#include <string.h>

#define MIN(A,B) (A<B?A:B)/*unsafe,but short*/
#define MAX(A,B) (A>B?A:B)/*unsafe,but short*/
// #define MAX(A,B) ((_A=A)>(_B=B)?_A:_B) /* safe but verbose */
#define T(C,X,Y) case C:if((m[x+X][y+Y]==' ')||(m[x+X][y+Y]=='#'))x+=X,y+=Y;s++;break;
char m[24][81],M[24][81];/* [m]ap and [M]ask; NB:mask intialized by default */
int i,j, /* loop indicies over the map */
  I=0,J, /* limits of the map */
  x,y,   /* player position */
  s=0;   /* steps taken */
int main(int c,char**v){
  FILE*f=fopen(v[1],"r"); /* fragile, assumes that the argument is present */
  /* Read the input file */
  for(I=0;fgets(m[I],80,f);I++)J=MAX(J,strlen(m[I])); /* Read in the map */ 
  J--;
  /* note that I leak a file handle here */
  f=fopen("/dev/random","r");
  /* Find a open starting square */
  do{ 
    x=fgetc(f)%I; /* Poor numeric properties, but good enough for code golf */
    y=fgetc(f)%J;
  } while(m[x][y]!=' ');
  /* setup curses */
  initscr(); /* start curses */
  //  raw();     /* WARNING! intercepts C-c, C-s, C-z, etc...
  //          * but shorter than cbreak() 
  //          */
  curs_set(0); /* make the cursor invisible */
  /* main loop */
  do {
    switch(c){
      T('e',0,1)
      T('n',-1,0)
      T('s',1,0)
      T('w',0,-1)
    }
    /* Update the mask */
    for(i=MAX(0,x-1);i<MIN(x+2,I);i++)
      for(j=MAX(0,y-1);j<MIN(y+2,J);j++)
    M[i][j]=1;
    /* draw the maze as masked */
    for(i=0;i<I;i++)
      for(j=0;j<J;j++)
    mvaddch(i,j,M[i][j]?m[i][j]:'?');
    /* draw the player figure */
    mvaddch(x,y,'@');
    refresh(); /* Refresh the display */
  } while((m[x][y]!='#')&&(c=getch())!='q');
  if(m[x][y]=='#')mvprintw(I,0,"Finished in %d steps!",s),getch();
  endwin();
}
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.