สร้างเอ็นจิ้นสำหรับเกมเขาวงกต


9

นี่คือการติดตามพิมพ์คำถามเขาวงกต หากคุณชอบคำถามนี้โปรดเพิ่มอัลกอริธึมการสร้างเขาวงกตให้มากขึ้น;)

สำหรับภารกิจนี้คุณจะต้องสร้างเอ็นจิ้นเกมสำหรับผู้เล่นที่ต้องค้นหาขุมทรัพย์ในเขาวงกตและออกจากคุกใต้ดิน

เอ็นจิ้นเริ่มต้นด้วยการอ่านเขาวงกตจากอินพุตมาตรฐานตามด้วยบรรทัดที่มีไฟล์.(dot)ที่กำหนดเป็นอาร์กิวเมนต์ในบรรทัดคำสั่ง ถัดไปผู้เล่น@จะอยู่ในตำแหน่งสุ่มบนแผนที่ จากนั้นเอ็นจิ้นจะเริ่มโต้ตอบกับผู้เล่นผ่านทาง 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.