Bir labirent oyunu için bir motor inşa


9

Bu, Labirent sorusunu yazdırın bir devamıdır . Bu soruyu beğendiyseniz, lütfen daha fazla labirent oluşturma algoritması ekleyin;).

Bu görev için, bir labirentte hazineyi bulması ve zindandan çıkması gereken bir oyuncu için bir oyun motoru uygulamanız gerekir.

Motor, labirenti standart girişten. okuyarak başlar ve ardından komut satırında bağımsız değişken olarak verilen bir dosyayı (nokta) içerir . Daha sonra oyuncu @harita üzerinde rastgele bir konuma yerleştirilir. Ardından motor, oynatıcıyla standart io aracılığıyla etkileşime başlar:

Motordan oyuncuya komutlar :

  • continue: Oyun bitmedi. Çevre, ardından a .. Oyuncu @karakter ile temsil edilir . Gözlenemeyen hücreler ile temsil edilir ?.
  • finished: Oyun bitti. Adım sayısı yazdırılır ve oyun durur.

Oyuncudan motora komutlar :

  • north: Oynatıcıyı yukarı taşır.
  • south: Oynatıcıyı aşağı taşır.
  • west: Oynatıcıyı sola hareket ettirin.
  • east: Oynatıcıyı sağa hareket ettirin.

Oynatıcıdaki geçersiz komutlar (duvara vurmak gibi) yok sayılır, ancak yine de sayılır. Çevreyi beğeninize göre tanımlamakta serbestsiniz.

  • En kısa kod için puan .
  • Karmaşık ortamlar için noktalar (örneğin, geniş bölgeleri yazdırın ve görünmeyen hücreleri değiştirin ?).
  • İo biçimine uymayan kod için nokta yok

Örnek :

Bu örnekte ortam, oynatıcı ortada olacak şekilde 3x3 hücre olarak tanımlanmıştır.

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

@Alexandru: Labirentlerimizi üretmek için ne kullanıyoruz? Diğer insanların labirent algoritmalarını kullanabilir miyiz (tabii ki gerekli krediyle)? Yoksa ilk ödevinizi mi tamamlamalıyız?
snmcdonald

@snmcdonald: Sabit yazım hatası. Başkalarının labirentini kullanın. Motorun labirenti standart girişten okuduğunu unutmayın.
Alexandru

Bu blog, çeşitli ve karışık algoritmalar kullanarak labirent üretimi hakkında mükemmel makalelere sahiptir weblog.jamisbuck.org Özellikle weblog.jamisbuck.org/2011/1/27/…
Dve

Hem labirent hem de kullanıcı etkileşiminin standart girdiden nasıl geldiği konusunda kafam karıştı. Kullanıcının labirentine yazıp çözmesi mi gerekiyor? Tür labirentin sadece bir kısmını gösterme amacını yendi ...
Keith Randall

Labirent girişini komut girişinden ayırmak için bir uygulama oluşturabilirsiniz (bu görev başka bir soru için bırakılır).
Alexandru

Yanıtlar:


7

C99, 771 karakter

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

Ncurses gerektirir ve kullanır. Uzunluk için sadece bir makroizasyon ve N ve M makroları eksik minimum ve maksimum rakiplerin yerini alacak ve bunun üzerinde daha yapılacak çok şey olduğunu sanmıyorum.

Bu giriş labirent geniş 80 karakteri aşmayan varsayar ve bir labirent dosya o olan komut hattı üzerinde geçirildi ve parametre sayısı c başlangıç değeri için bir hareket komutu değildir yeterince düşük olduğu.

  • Önerilen karakterlerin küçük harfli ilk harfi olarak tek karakterli yön komutları alması bakımından standarttan farklıdır.

  • Bilinmeyen bölgeleri '?' Olarak gösteriyor mu?

Yorumlar ile daha okunabilir:

#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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.