Xây dựng một công cụ cho một trò chơi mê cung


9

Đây là phần tiếp theo của In một câu hỏi mê cung . Nếu bạn thích câu hỏi này, vui lòng thêm nhiều thuật toán tạo mê cung;).

Đối với nhiệm vụ này, bạn sẽ phải triển khai một công cụ trò chơi cho một người chơi phải tìm kho báu trong mê cung và thoát khỏi ngục tối.

Công cụ bắt đầu bằng cách đọc mê cung từ đầu vào tiêu chuẩn theo sau là một dòng chứa .(dấu chấm) một tệp được đưa ra làm đối số trong dòng lệnh. Tiếp theo người chơi @được đặt ở một vị trí ngẫu nhiên trên bản đồ. Sau đó, công cụ bắt đầu tương tác với người chơi thông qua io tiêu chuẩn:

Các lệnh từ động cơ đến trình phát :

  • continue: Trò chơi chưa kết thúc. Môi trường xung quanh được in theo sau a .. Người chơi được đại diện bởi @nhân vật. Các tế bào không quan sát được đại diện bởi ?.
  • finished: Trò chơi kết thúc. Số lượng các bước được in và trò chơi dừng lại.

Các lệnh từ người chơi đến động cơ :

  • north: Di chuyển người chơi lên.
  • south: Di chuyển người chơi xuống.
  • west: Di chuyển người chơi sang trái.
  • east: Di chuyển người chơi ngay.

Bất kỳ lệnh không hợp lệ nào (chẳng hạn như đập vào tường) từ người chơi đều bị bỏ qua, nhưng vẫn được tính. Bạn có thể tự do xác định môi trường xung quanh theo ý thích của bạn.

  • Điểm cho mã ngắn nhất.
  • Điểm cho môi trường xung quanh phức tạp (ví dụ: in các vùng lớn và thay thế các ô không thể nhìn thấy bằng ?).
  • Không có điểm nào cho mã không tôn trọng định dạng io

Ví dụ :

Trong ví dụ này, môi trường xung quanh được định nghĩa là ô 3x3 với trình phát ở giữa.

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

@Alexandru: Chúng ta đang sử dụng cái gì để tạo ra mê cung của mình? Chúng ta có thể sử dụng các thuật toán mê cung của người khác (rõ ràng là có tín dụng đáo hạn) không? Hay chúng ta phải hoàn thành nhiệm vụ đầu tiên của bạn?
snmcdonald

@snmcdonald: Sửa lỗi chính tả. Sử dụng mê cung của người khác. Hãy nhớ rằng động cơ đọc mê cung từ đầu vào tiêu chuẩn.
Alexandru

Blog này có các bài viết tuyệt vời về việc tạo mê cung bằng các thuật toán khác nhau và hỗn hợp weblog.jamisbuck.org Kiểm tra thuật toán cây đang phát triển cụ thể là weblog.jamisbuck.org/2011/1/27/
Dve

Tôi bối rối không biết làm thế nào cả mê cung và tương tác người dùng đến từ đầu vào tiêu chuẩn. Là người dùng có nghĩa vụ gõ vào mê cung của mình và sau đó giải quyết nó? Kinda đánh bại mục đích chỉ hiển thị một phần của mê cung ...
Keith Randall

Bạn có thể xây dựng một ứng dụng (nhiệm vụ này được để lại cho một câu hỏi khác) trên đầu ứng dụng để tách đầu vào mê cung khỏi đầu vào lệnh.
Alexandru

Câu trả lời:


7

C99, 771 ký tự

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

Yêu cầu và sử dụng ncurses. Chỉ có một vĩ mô hóa cho chiều dài và các macro N và M là để thay thế các trình điều khiển tối thiểu và tối thiểu bị thiếu, và tôi không nghĩ còn nhiều việc phải làm về điều đó.

Nó giả sử mê cung đầu vào không vượt quá 80 ký tự và tên tệp mê cung đã được truyền trên dòng lệnh và số lượng tham số đủ thấp để giá trị ban đầu của c không phải là lệnh di chuyển.

  • Khác với tiêu chuẩn ở chỗ nó nhận các lệnh hướng ký tự đơn làm chữ cái đầu tiên viết thường của các chữ cái được đề xuất.

  • Không hiển thị các vùng chưa biết là '?'.

Dễ đọc hơn với các bình luận:

#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();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.