미로 게임용 엔진 구축


9

이것은 미로 질문 인쇄 의 후속 조치입니다 . 이 질문이 마음에 드시면 더 많은 미로 생성 알고리즘을 추가하십시오;).

이 작업을 위해서는 미로에서 보물을 찾아 지하 감옥에서 나가야하는 한 명의 플레이어를 위해 게임 엔진을 구현해야합니다.

엔진은 표준 입력. 에서 미로를 읽은 다음 명령 행에 인수로 제공된 파일을 포함하는 (점) 행으로 시작합니다. 다음으로 플레이어 @는지도에서 임의의 위치에 배치됩니다. 그런 다음 엔진은 표준 io를 통해 플레이어와 상호 작용하기 시작합니다.

엔진에서 플레이어로의 명령 :

  • continue: 게임이 완료되지 않았습니다. 주변이 인쇄 된 후 .. 플레이어는 @캐릭터 로 표시됩니다 . 관찰 할 수없는 셀은로 표시됩니다 ?.
  • finished: 게임이 끝났습니다. 단계 수가 인쇄되고 게임이 중지됩니다.

플레이어에서 엔진으로의 명령 :

  • north: 플레이어를 위로 이동합니다.
  • south: 플레이어를 아래로 이동합니다.
  • west: 플레이어를 왼쪽으로 이동합니다.
  • east: 플레이어를 오른쪽으로 움직입니다.

플레이어의 유효하지 않은 명령 (예 : 벽에 부딪 치기)은 무시되지만 계속 계산됩니다. 원하는대로 주변 환경을 자유롭게 정의 할 수 있습니다.

  • 포인트 짧은 코드.
  • 복잡한 환경에 대한 포인트 (예 : 큰 영역을 인쇄하고로 보이지 않는 셀을 대체 ?)
  • 어떤 점하지 IO의 형식을 존중하지 않는 코드에 대한

:

이 예제에서 주변은 플레이어가 중간에있는 3x3 셀로 정의됩니다.

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

@Alexandru : 미로를 생성하기 위해 무엇을 사용하고 있습니까? 다른 사람들의 미로 알고리즘을 사용할 수 있습니까? 아니면 첫 번째 과제를 완료해야합니까?
snmcdonald

@ snmcdonald : 오타가 수정되었습니다. 다른 사람의 미로를 사용하십시오. 엔진은 표준 입력에서 미로를 읽습니다.
Alexandru

이 블로그는 다양한 혼합 알고리즘 weblog.jamisbuck.org를 사용하여 미로 생성에 관한 훌륭한 기사를 가지고 있습니다. 특히 weblog.jamisbuck.org/2011/1/27/…
Dve

미로와 사용자 상호 작용이 표준 입력에서 어떻게 나오는지 혼란 스럽습니다. 사용자는 자신의 미로를 입력 한 다음 해결해야합니까? 킨다는 미로의 일부만 보여주기위한 목적을 무너 뜨립니다.
Keith Randall

미로 입력과 명령 입력을 분리하기 위해 앱을 빌드 할 수 있습니다 (이 작업은 다른 질문으로 남습니다).
Alexandru

답변:


7

C99, 771 자

#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가 필요하고 사용합니다. 길이에 대한 단 하나의 매크로 화와 N 및 M 매크로는 누락 된 최소 및 최대 연산기를 대체해야하며 그에 대해 더 많은 것이 없다고 생각합니다.

입력 미로의 너비가 80자를 초과하지 않으며 미로 파일 이름 명령 행에 전달되었고 매개 변수의 수가 c의 초기 값이 이동 명령이 아닌 것으로 가정합니다.

  • 제안 된 문자의 첫 번째 소문자로 단일 문자 방향 명령을 사용한다는 점에서 표준과 다릅니다.

  • 알 수없는 영역을 '?'로 표시합니다.

주석으로 더 읽기 쉽다 :

#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();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.