던전의지도를 만들어 봅시다 | | + | |

오래 전에 RPG 게임에 더 많은 시간을 할애했을 때 일부 플레이어의 문제 중 하나는 파티 움직임을 추적하고 적절한지도를 그리는 것이 었습니다. 그래서 나는 여러분 이이 문제를 어떻게 다루는 지 확인하기 위해 아이디어를 얻었습니다.

작업은 방향의 입력 매개 변수 목록 (선택한 구조로 전달됨) ^v<>, 던전의 표시 맵을 사용 하는 함수를 작성하는 것 입니다. 입력 예 : >>>vvv<<<^^^출력은 다음과 같습니다.

+----+               +----+
|    |               |>>>v|
| ++ |               |^++v|
| ++ |  because      |^++v|
|    |               |^<<<|
+----+               +----+

테스트 케이스

>>>>>>vvvvv<<<<^^^>>v



 +-------+
 |       |
 +-+---+ |
   |   | |
   | + | |
   | +-+ |
   |     |
   +-----+


^^^^^vvv<<<^^vv>>>>>>>>vv>><<^^^^v>>>>v^<^

          +-+
       +-+| | +-++-+
       | || | | ++ ++
       | ++ +-+     |
       |        +-+ |
       +--+ +-+ +-+-+
          | | |   |
          +-+ +---+

골프 코드 챌린지이므로 가장 짧은 코드가 승리합니다.

행복한 골프.

편집
늦게 편집해서 죄송합니다. 최근에 시간이 많지 않았습니다.

움직임에 따라 맵이 생성됩니다. 보행 중에 방문한 복도 만 포함해야합니다. 따라서 하나의 큰 방을 만드는 것은 올바른 대답이 아닙니다.

맵에는 세 가지 유효한 기호가 있습니다.

  • | 수 직벽
  • | 수평 벽
  • + 수직 및 수평 벽의 교차점.

경로의 최대 길이는 255 자입니다 (그러나 가능한 경우 자신을 제한하지 마십시오).

더 많은 테스트 사례 :

 ><><><><

 +--+
 |  |
 +--+

 >^<v

 +--+
 |  |
 |  |
 +--+

나는 이제 모든 것이 분명하기를 바랍니다.



답변

자바 스크립트 (ES6), 261 254 243 바이트

s=>{v=Array(w=32);p=526;b=n=>v[n>>5]&(1<<(n&31));B=(n,i)=>b(p+n)|b(p-n)?i:0;[...0+s].map(c=>v[(p+=[0,1,-1,w,-w]['0><v^'.indexOf(c)])>>5]|=1<<(p&31));for(z='',p=0;p<w*w;z+=' |-+'[b(p)?0:B(1,1)|B(w,2)||B(31,3)|B(33,3)],p++%w||(z+=`
`));return z}

JSFiddle


답변

C, 246 바이트

n,y,*g,*p;main(c,v)char**v;{for(n=c*2+3,g=calloc(n*n,8),p=g+(n+1)*(c+1);c--;y=*v[c],p-=(y>70?n:1)*(y%5%4?-1:1))*p=1;for(y=n-1;--y;)for(c=n-1;c--;putchar(c?" |-++|-+"[*p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4]:10))p=g+y*n+c;}

예를 들어 입력을 별도의 문자로 사용합니다.

./mapper '>' '>' '>' 'v' 'v' 'v' '<' '<' '<' '^' '^' '^'

또는 더 편리하게는 (의도적으로 인용되지 않은!) 형식입니다.

./mapper $(echo '>>>vvv<<<^^^' | fold -w1)

또는 (아주 비효율적 인) 임의 입력의 경우 :

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 10 | fold -w1)

마지막으로 awk결과를 자르기 위해 사용 하면 훨씬 더 커질 수 있습니다.

./mapper $(LC_CTYPE=C tr -dc '0-3' < /dev/urandom | tr '0123' '<>^v' | head -c 500 | fold -w1) | awk '/[^ ]/{l=match($0,"\\+");if(l&&(l<L||!L))L=l;v[i++]=$0}END{for(;j<i;){l=v[j++];print substr(l,L,match(l," *$")-L)}}'

 +-----+
 |     |
 |     +-+  +-----+
 |       |+-+     |
++       +|      ++
|         |      |
|         +      +-+
+--+               |
 +-+               +--+
 |     ++             |
 +-+  +-++           +-+
   ++   |+--+          |
    +-+ | |        ++  |
     ++ | ++   + +--+ ++
     |  |  +---|      |
     |  |     ++  +---+
     ++ |-+   |   |
      | | +--+-+  |
      | +    +    |
      |        +--+
      +--------+

stdout으로 출력합니다. 맵 주위에 패딩이 허용된다는 사실을 사용합니다 (가장자리 길이가 2 * n + 1 인 맵을 생성하여 최종 위치를 중간에 배치).

고장

이것은 인수를 역순으로 반복하고 역순으로 이동하여 작동합니다. 실제로 arg 0은 프로그램 이름이라는 사실을 사용합니다. 이름이 무엇이든 중요하지 않지만 특별한 처리가 필요없이 초기 및 마지막 셀 (및 그 사이의 모든 셀)을 모두 방문 할 수 있습니다.

n,                                  // Size of internal grid
y,                                  // Loop counter / current character
*g,                                 // Internal grid memory
*p;                                 // Current working pointer
main(c,v)char**v;{                  // K&R style function declaration
    for(                            // Step 1: identify visited cells
        n=c*2+3,                    //  Set output grid size
        g=calloc(n*n,8),            //  Allocate map storage space
        p=g+(n+1)*(c+1);            //  Start at centre
        c--;                        //  Loop over directions in reverse
        y=*v[c],                    //  Get current direction
        p-=(y>70?n:1)*(y%5%4?-1:1)  //  Move in reverse
    )*p=1;                          //  Mark cell visited
    for(y=n-1;--y;)                 // For each row (except edges)
        for(c=n-1;c--;              //   For each column (except edges, +1 for \n)
            putchar(c?" |-++|-+"[   //   Print wall using lookup table
                *p?0:p[1]|p[-1]|(p[n]|p[-n])*2|(p[1+n]|p[1-n]|p[n-1]|p[-n-1])*4
            ]:10)                   //   Or newline
        )p=g+y*n+c;                 //   Set current cell (happens first)
}

답변