迷路ゲームのエンジンを構築する


9

これは「迷路印刷」の質問のフォローアップです。この質問が気に入ったら、迷路生成アルゴリズムを追加してください;)。

このタスクでは、迷路で宝物を見つけてダンジョンから抜け出さなければならない1人のプレーヤー用のゲームエンジンを実装する必要があります。

エンジンは、標準入力.から迷路を読み取り、続いてコマンドラインで引数として指定され(ドット)ファイルを含む行を読み取ります。次に、プレイヤー@はマップ上のランダムな場所に配置されます。次に、エンジンは標準の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:タイプミスを修正しました。他の人の迷路を使用してください。エンジンは標準入力から迷路を読み取ることに注意してください。
アレクサンドル

このブログは様々と混合アルゴリズムを使用して迷路世代の優れた記事がある weblog.jamisbuck.org 成長ツリーアルゴリズムで、特定のチェックアウト weblog.jamisbuck.org/2011/1/27/...
DVE

迷路とユーザーインタラクションの両方が標準入力からどのようにもたらされるかについて、私は混乱しています。ユーザーは迷路を入力して解決する必要がありますか?ちょっと、迷路の一部だけを表示するという目的を破ります...
キースランドール

その上にアプリ(このタスクは別の質問のために残されています)を構築して、コマンド入力から迷路入力を分離できます。
アレクサンドル

回答:


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を必要とし、使用します。長さのマクロ化は1つだけであり、NマクロとMマクロは、欠落している最小および最大の演算子を置き換えるものであり、それ以上のことはないと思います。

入力迷路の幅が80文字を超えず、コマンドラインで迷路のファイル名渡され、パラメーターの数が十分に少ないため、cの初期値が移動コマンドではないと想定しています。

  • 提案されているコマンドの最初の小文字が1文字の方向コマンドであるという点で、標準から逸脱しています。

  • 不明な領域を「?」として表示しますか?

コメントでさらに読みやすく:

#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.