Construye un motor para un juego de laberinto


9

Este es un seguimiento de Imprimir una pregunta de laberinto . Si te gusta esta pregunta, agrega más algoritmos de generación de laberintos;).

Para esta tarea, tendrás que implementar un motor de juego para un jugador que debe encontrar el tesoro en un laberinto y salir de la mazmorra.

El motor comienza leyendo el laberinto de la entrada estándar seguido de una línea que contiene un .(punto) un archivo dado como argumento en la línea de comando. A continuación, el jugador @se coloca en una ubicación aleatoria en el mapa. Entonces el motor comienza a interactuar con el jugador a través de io estándar:

Comandos del motor al jugador :

  • continue: Juego no terminado. Los alrededores están impresos seguidos de a .. El jugador está representado por el @personaje. Las celdas no observables están representadas por ?.
  • finished: Juego terminado. Se imprime el número de pasos y el juego se detiene.

Comandos del jugador al motor :

  • north: Mueve al jugador hacia arriba.
  • south: Mueve al jugador hacia abajo.
  • west: Mueve el jugador a la izquierda.
  • east: Mueve el jugador a la derecha.

Cualquier comando no válido (como golpear una pared) del jugador se ignora, pero aún se cuenta. Eres libre de definir los alrededores a tu gusto.

  • Puntos por el código más corto.
  • Puntos para entornos complejos (por ejemplo, imprima regiones grandes y reemplace las celdas que no son visibles ?).
  • No hay puntos para el código que no respeta el formato io

Ejemplo :

En este ejemplo, el entorno se define como la celda 3x3 con el jugador en el medio.

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

@Alexandru: ¿Qué estamos usando para generar nuestros laberintos? ¿Podemos usar algoritmos de laberinto de otras personas (obviamente con el debido crédito)? ¿O debemos completar su primera tarea?
snmcdonald

@snmcdonald: error tipográfico fijo. Usa los laberintos de otras personas. Recuerde que el motor lee el laberinto a partir de la entrada estándar.
Alexandru

Este blog tiene excelentes artículos sobre la generación de laberinto utilizando diferentes algoritmos y mixtos weblog.jamisbuck.org Salida del creciente algoritmo de árbol en particular, weblog.jamisbuck.org/2011/1/27/...
Dve

Estoy confundido en cuanto a cómo la interacción del laberinto y el usuario provienen de la entrada estándar. ¿Se supone que el usuario debe escribir su laberinto y luego resolverlo? Un poco derrota el propósito de mostrar solo una parte del laberinto ...
Keith Randall

Puede crear una aplicación (esta tarea se deja para otra pregunta) además de separar la entrada del laberinto de la entrada de comandos.
Alexandru

Respuestas:


7

C99, 771 caracteres

#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();}

Requiere y hace uso de ncurses. Solo una macroización por longitud, y las macros N y M reemplazarán a los operadores mínimos y máximos que faltan, y no creo que haya mucho más que hacer al respecto.

Se supone que el laberinto de entrada no supera los 80 caracteres de ancho y que se ha pasado un nombre de archivo del laberinto en la línea de comandos, y que el número de parámetros es lo suficientemente bajo como para que el valor inicial de c no sea un comando de movimiento.

  • Se desvía del estándar en que toma comandos de dirección de un solo carácter como la primera letra minúscula de las sugeridas.

  • Muestra regiones desconocidas como '?' S.

Más legible con comentarios:

#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();
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.