Bangun mesin untuk permainan labirin

9

Ini adalah tindak lanjut dari Mencetak pertanyaan labirin . Jika Anda menyukai pertanyaan ini, silakan tambahkan lebih banyak algoritma pembuatan labirin;).

Untuk tugas ini Anda harus menerapkan mesin permainan untuk satu pemain yang harus menemukan harta karun di labirin dan keluar dari penjara bawah tanah.

Mesin mulai dengan membaca labirin dari input standar diikuti oleh baris yang berisi .(titik) file yang diberikan sebagai argumen di baris perintah. Selanjutnya pemain @ditempatkan di lokasi acak di peta. Kemudian engine mulai berinteraksi dengan pemain melalui standar io:

Perintah dari mesin ke pemain :

  • continue: Game belum selesai. Lingkungan dicetak diikuti oleh a .. Pemain diwakili oleh @karakter. Sel yang tidak dapat diobservasi diwakili oleh ?.
  • finished: Game selesai. Jumlah langkah dicetak dan permainan berhenti.

Perintah dari pemain ke mesin :

  • north: Memindahkan pemain ke atas.
  • south: Memindahkan pemain ke bawah.
  • west: Pindahkan pemain ke kiri.
  • east: Pindahkan pemain ke kanan.

Perintah yang tidak valid (seperti menabrak dinding) dari pemain diabaikan, tetapi masih dihitung. Anda bebas menentukan lingkungan yang Anda sukai.

  • Poin untuk kode terpendek.
  • Poin untuk lingkungan yang kompleks (mis. Cetak wilayah besar dan ganti sel yang tidak terlihat oleh ?).
  • Tidak ada poin untuk kode yang tidak menghormati format io

Contoh :

Dalam contoh ini, lingkungan didefinisikan sebagai sel 3x3 dengan pemain di tengah.

$ cat maze
+-+-+
  |#|
|   |
+---+
$ python engine.py maze
 |#
 @ 
---
.
east
|#|
 @|
--+
.
north
+-+
|@|
  |
.
south
|#|
 @|
--+
.
west
 |#
 @ 
---
.
west
  |
|@ 
+--
.
north
+-+
 @|
|  
.
west
finished
7
Alexandru
sumber
@Alexandru: Apa yang kita gunakan untuk menghasilkan labirin kita? Bisakah kita menggunakan algoritma labirin orang lain (jelas dengan kredit jatuh tempo)? Atau haruskah kami menyelesaikan tugas pertama Anda?
snmcdonald
@ snmcdonald: Memperbaiki kesalahan ketik. Gunakan labirin orang lain. Ingat bahwa mesin membaca labirin dari input standar.
Alexandru
Blog ini memiliki artikel yang luar biasa tentang pembuatan labirin menggunakan beragam dan beragam algoritma weblog.jamisbuck.org Lihat algoritma pohon yang tumbuh khususnya weblog.jamisbuck.org/2011/1/27/…
Dve
Saya bingung bagaimana baik labirin dan interaksi pengguna berasal dari input standar. Apakah pengguna harus mengetikkan labirinnya dan menyelesaikannya? Agak mengalahkan tujuan hanya menunjukkan sebagian dari labirin ...
Keith Randall
Anda dapat membangun aplikasi (tugas ini dibiarkan untuk pertanyaan lain) di atasnya untuk memisahkan input maze dari input perintah.
Alexandru

Jawaban:

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

Membutuhkan dan memanfaatkan ncurses. Hanya satu makroisasi panjang, dan makro N dan M adalah untuk menggantikan opperator minimum dan maksimum yang hilang, dan saya tidak berpikir ada banyak yang harus dilakukan tentang itu.

Ini mengasumsikan labirin masukan tidak melebihi 80 karakter lebar, dan bahwa labirin nama file telah disahkan pada baris perintah, dan bahwa jumlah parameter yang cukup rendah bahwa nilai awal c bukan perintah gerakan.

  • Menyimpang dari standar karena dibutuhkan perintah arah karakter tunggal seperti huruf kecil pertama dari yang disarankan.

  • Apakah menampilkan wilayah yang tidak dikenal sebagai '?'

Lebih mudah dibaca dengan komentar:

#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();
}
dmckee --- mantan kucing moderator
sumber