Baue eine Engine für ein Labyrinthspiel


9

Dies ist eine Fortsetzung der Frage " Labyrinth drucken". Wenn Ihnen diese Frage gefällt, fügen Sie bitte weitere Algorithmen zur Labyrinthgenerierung hinzu;).

Für diese Aufgabe müssen Sie eine Spiel-Engine für einen Spieler implementieren, der den Schatz in einem Labyrinth finden und den Dungeon verlassen muss.

Die Engine beginnt mit dem Lesen des Labyrinths aus der Standardeingabe, gefolgt von einer Zeile mit einem .(Punkt) einer Datei, die als Argument in der Befehlszeile angegeben ist. Als nächstes wird der Spieler @an einer zufälligen Stelle auf der Karte platziert. Dann beginnt die Engine mit dem Player über Standard io zu interagieren:

Befehle von der Engine zum Spieler :

  • continue: Spiel nicht beendet. Die Umgebung wird gedruckt, gefolgt von a .. Der Spieler wird durch den @Charakter dargestellt. Nicht beobachtbare Zellen werden durch dargestellt ?.
  • finished: Spiel beendet. Die Anzahl der Schritte wird gedruckt und das Spiel stoppt.

Befehle vom Spieler zur Engine :

  • north: Bewegt den Spieler nach oben.
  • south: Bewegt den Spieler nach unten.
  • west: Spieler nach links bewegen.
  • east: Spieler nach rechts bewegen.

Jeder ungültige Befehl (z. B. das Schlagen einer Wand) vom Spieler wird ignoriert, aber dennoch gezählt. Sie können die Umgebung nach Ihren Wünschen definieren.

  • Punkte für den kürzesten Code.
  • Punkte für komplexe Umgebungen (z. B. große Bereiche drucken und Zellen ersetzen, die nicht sichtbar sind ?).
  • Keine Punkte für Code, der das Io-Format nicht berücksichtigt

Beispiel :

In diesem Beispiel wird die Umgebung als 3x3-Zelle mit dem Player in der Mitte definiert.

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

@Alexandru: Womit erzeugen wir unsere Labyrinthe? Können wir Labyrinthalgorithmen anderer Leute verwenden (offensichtlich mit gebührender Anerkennung)? Oder müssen wir Ihren ersten Auftrag abschließen?
Snmcdonald

@snmcdonald: Tippfehler behoben. Verwenden Sie die Labyrinthe anderer Leute. Denken Sie daran, dass der Motor das Labyrinth von der Standardeingabe liest.
Alexandru

Dieser Blog enthält ausgezeichnete Artikel zur Labyrinthgenerierung mit verschiedenen und gemischten Algorithmen. Weblog.jamisbuck.org Schauen Sie sich den Algorithmus für wachsende Bäume an, insbesondere weblog.jamisbuck.org/2011/1/27/…
Dve

Ich bin verwirrt darüber, wie sowohl das Labyrinth als auch die Benutzerinteraktion von Standardeingaben stammen. Soll der Benutzer sein Labyrinth eingeben und es dann lösen? Kinda besiegt den Zweck, nur einen Teil des Labyrinths zu zeigen ...
Keith Randall

Sie können darüber eine App erstellen (diese Aufgabe bleibt für eine andere Frage übrig), um die Labyrinth-Eingabe von der Befehlseingabe zu trennen.
Alexandru

Antworten:


7

C99, 771 Zeichen

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

Benötigt und nutzt Flüche. Nur eine Makroisierung für die Länge und die N- und M-Makros sollen die fehlenden minimalen und maximalen Opperatoren ersetzen, und ich denke, dass es nicht viel mehr zu tun gibt.

Es nimmt an dem Eingang maze überschreitet nicht 80 Zeichen breit, und daß den ein Labyrinth Dateinamen hat auf der Befehlszeile übergeben worden ist , und dass die Anzahl von Parametern ist gering genug , dass der Anfangswert von C kein Bewegungsbefehl ist.

  • Weicht insofern vom Standard ab, als Einzelzeichenrichtungsbefehle als Kleinbuchstaben der vorgeschlagenen verwendet werden.

  • Zeigt unbekannte Regionen als '?' S an.

Besser lesbar mit Kommentaren:

#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();
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.