地牢爬行者


40

输入项

  • 表示地牢壁的二进制矩阵中号
  • 玩家在地牢中的位置(X,ÿ)。
  • 玩家当前面对的方向d(0 =北,1 =东,2 =南,3 =西)

输出量

播放器视场中墙壁的伪3D表示形式,为30×10字符的ASCII艺术。

下面是几个可能的输出框架,以及相应的地图和指南针,以帮助您掌握其窍门(但绘制地图和指南针并不是挑战的一部分)。

动画

规格

视场

玩家在其视野中有13面墙,从一种到中号标记。以下是在所有可能的方向上墙相对于播放器的位置(黄色)。

视场

画墙

墙壁应该从一种画到中号任何部分都可能被更靠近的墙壁覆盖,则应按照此精确顺序绘制墙壁。只要最终结果相同,您当然可以实施不同的方法。

整个输出画有7点不同的字符:" ","'",".","|","-","_"和":"。

由于详细说明此挑战主体中的墙壁形状会使其过长,因此可以在以下TIO链接中提供它们:

在线尝试!

"?"在这些图中,不属于给定墙的字符用标记。必须将它们视为完全不绘制的“透明”字符。另一方面,墙内的所有空间都是“实体”,并且必须覆盖以前可能在此绘制的任何其他字符。

规则

关于输入

  • 您可以采用任何合理格式的中号,X,ÿ和d。
  • 您可以使用0索引或1索引的坐标。
  • 您可以为指示使用4个不同的值。
  • 保证矩阵至少为3×3。
  • 您可能会假设边缘上总是有围墙。
  • 保证播放器位于一个空的正方形上。
  • 输入保证有效。

关于输出

  • 墙壁必须完全按照描述绘制。
  • 但是,输出格式也很灵活:单个字符串,字符串数组,字符矩阵等。
  • 只要前后空格一致,就可以接受。

这是。

测试用例

所有测试用例都使用以下矩阵:

[ [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
  [ 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 ],
  [ 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 1, 1, 0, 1 ],
  [ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 ],
  [ 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 ],
  [ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] ]

(0,0)

x=3, y=3, d=0
x=6, y=4, d=3
x=4, y=4, d=1
x=1, y=5, d=2
x=7, y=7, d=3
x=6, y=6, d=1
x=8, y=1, d=2
x=7, y=6, d=1

预期产出:

------------------------------    ------------------------------
 x=3, y=3, d=0:                    x=6, y=4, d=3:
------------------------------    ------------------------------
__                          __    '.                          .'
  |'.                    .'|        |                        |  
  |   '.--------------.'   |        |----.                   |  
  |    |              |    |        |    | '.--------.       |  
  |    |              |    |        |    |  |        |       |  
  |    |              |    |        |    |  |        |       |  
  |    |              |    |        |    | .'--------'       |  
  |   .'--------------'.   |        |----'                   |  
__|.'                    '.|__      |                        |  
                                  .'                          '.
------------------------------    ------------------------------
 x=4, y=4, d=1:                    x=1, y=5, d=2:
------------------------------    ------------------------------
                            .'    __ ________________________ .'
                           |        |                        |  
-------.              .----|        |                        |  
       | '.--------.' |    |        |                        |  
       |  |        |  |    |        |                        |  
       |  |        |  |    |        |                        |  
       | .'--------'. |    |        |                        |  
-------'              '----|        |                        |  
                           |      __|________________________|  
                            '.                                '.
------------------------------    ------------------------------
 x=7, y=7, d=3:                    x=6, y=6, d=1:
------------------------------    ------------------------------
'.                                '.                            
  |'.                               |'.                         
  |   '.                            |   '.                      
  |    | '.                 .-      |    |--.--------.--------.-
  |    |  |:               :|       |    |  |        |        | 
  |    |  |:               :|       |    |  |        |        | 
  |    | .'                 '-      |    |--'--------'--------'-
  |   .'                            |   .'                      
  |.'                               |.'                         
.'                                .'                            
------------------------------    ------------------------------
 x=8, y=1, d=2:                    x=7, y=6, d=1:
------------------------------    ------------------------------
'.                          __    '.                            
  |'.                    .'|        |                           
  |   '.              .'   |        |----.--------------.-------
  |    | '.        .' |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    | .'        '. |    |        |    |              |       
  |   .'              '.   |        |----'--------------'-------
  |.'                    '.|__      |                           
.'                                .'                            

相关挑战:

2013年的这一挑战密切相关。但是它有一个不同的获胜标准(代码挑战),输出规范宽松得多,并且需要交互式I / O。


这立即使我想起了3D Monster Maze,尽管它当然使用了块图形。
— 尼尔

9
您的挑战是如此有趣且写得很好!
— 奥利弗

在Minecraft中等待解决方案...

还有其他人记得Windows屏幕保护程序吗?当我5或6岁时是一个如此有趣的“游戏” ...
— 魔术章鱼缸

Answers:


10

清洁(带的Snappy),800个 785 670 644字节

460个 402字节的代码+ 360 242字节的字符串文字
(这里和TIO逃出,因为它不是有效的UTF-8)

您可以在此处验证文字的长度。

import StdEnv,Data.List,Data.Maybe,Codec.Compression.Snappy,Text
@a b|b<'~'=b=a
$m x y d=map(@' ')(foldl(\a b=[@u v\\u<-a&v<-b])['~~'..][join['
']k\\Just(Just 1)<-[mapMaybe(\e=e!?(x+[u,v,~u,~v]!!d))(m!?(y+[~v,u,v,~u]!!d))\\u<-[-2,2,-1,1,0,-1,1,0,-1,1,0,-1,1]&v<-[3,3,3,3,3,2,2,2,1,1,1,0,0]]&k<-nub[q\\w<-split"#"(snappy_uncompress"\211\6\44\41\41\41\55\56\40\41\40\174\72\5\4\60\55\47\40\41\41\41\43\41\41\41\176\56\55\r\1\24\56\40\41\176\174\40\r\1\4\174\72\72\r\0\0\47\r\46\35\72\25\1\31\103\0\41\25\24\35\113\176\25\0\31\133\11\224\r\152\20\56\40\40\40\41\21\217\10\40\47\56\31\14\4\40\174\126\14\0\4\56\47\21\74\0\47\1\74\1\340\r\220\25\242\11\1\25\250\25\360\11\1\25\253\376\30\0\21\30\25\333\11\1\24\47\41\41\43\137\137\11\154\20\41\40\40\174\47\r\344\1\157\5\341\1\11\5\336\172\11\0\34\56\47\41\137\137\174\56\47\1\347\20\43\176\176\40\137\132\1\0\4\40\41\75\211\76\1\0\1\356\5\150\116\1\0\376\35\0\376\35\0\126\35\0\132\347\0\20\137\174\41\43\47\101\337\51\74\41\133\122\4\0\10\56\47\40"),q<-let l=[[c\\c<-:rpad s 30'~']\\s<-split"!"w]in[l,map reverse l]]])

在线尝试!

尽管专注于速度,但在这种情况下,Snappy压缩实际上确实做得很好,因为要压缩的字符串中有太多的单字符运行。

未压缩的字符串(为方便起见,将其#替换\n为):

!!!-. ! |:! |:!-' !!!
!!!~.--------. !~|        |:!~|        |:!~'--------' !!!
!!!~~~~~~~~~~.--------.!~~~~~~~~~~|        |!~~~~~~~~~~|        |!~~~~~~~~~~'--------'!!!
!!-------.   !       | '.!       |  |!       |  |!       | .'!-------'   !!
!!~~~~~~~.--------------.!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~'--------------'!!
__      !  |'.   !  |   '.!  |    |!  |    |!  |    |!  |    |!  |   .'!__|.'   !
~~ ________________________ !~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|________________________|!
'. !  |!  |!  |!  |!  |!  |!  |!  |!.' 

这会使用!而不是换行符和~代替来编码不同屏幕组件的左侧版本,?然后~在将其自身和它们的行反转添加到查找列表之前,将其右填充至30个字符。

其余代码仅处理坐标查找,而忽略了超出边界的情况。


5

Python 2中,864个 854 848 826 810字节

L=[zip(*[iter(w)]*30)for w in zip(*[iter("eJzdllESgyAMRL+5Rf7yRQ7AZbhIDl9BwTqzSVtHrbKffR0Mm13HEM5SFHIoadpNI3snDyaS6NCknhU+JfZOvq8kLoIBU1oEI+RTbiePGzBa3QM0rf78TGl17+CZr5ZrUXBN+ECfY1GvGKEqtDsSI4s6xTn5jgqyqNcTTnUjTQO2FAEqTC0ngCrtpywenX5le6or1SsGi9ZLBKt0HuXtVEeUNGdzG6EsRNmo2EzLxuBbqFH8njmfwnqGcl+VY+s5+5ezSYXVel4dxaRK/6F15SatK1frvm//y4aoT4Ckj6XWfY2cbvz2fLSCPiiVvR+3ZuerzDwPSqeSvgAP9woa".decode('base64').decode('zip'))]*300)]
E=enumerate
def f(m,x,y,d):
 D=eval(`[[' ']*30]*10`);w,h=len(m[0]),len(m);a=[m,zip(*m)[::-1]][d%2];x,y=[x,y,w+~x,h+~y,y,w+~x,h+~y,x][d::4];X=sum([[0]*(x<2)+list(l)[x-2+(x<2):x+3]for l in[l*2for l in[a,[l[::-1]for l in a[::-1]]][d/2]*2][y:y+4]],[])
 for d,w in zip(L,'sropqmklhfgca'):
  for j,l in E(d):
   for i,q in E(l):
    if q*X[ord(w)%32]>=' ':D[j][i]=q
 for l in D:print''.join(l)

在线尝试!


4

木炭,500个 332字节

F⁴≔⮌E§θ⁰⁺00⭆θ§μλθ≔E✂θ⊖ζ⁺⁶ζ¹✂ι⊖η⁺⁶η¹θFε≔⮌E§θ⁰⭆θ§μλθB³⁰χ F²«‖FΦ⪪⟦“ |0⟧P+N?⟧‹G”³¦⁰”{➙d⊟EX⍘k↧D({Vt⍘gRd◨ⅉ^δ#T;”³¦¹“ ¶↖+9G₂pF^c1e⌈¬;”³χω⁰χ”{➙∧⊟∧◨ηü∧↖z↨⁸\G'λI∧¡∕⪫θJoΣ³⊖I⊟ζ⊙”²¦⁰”{➙∧⊟∧◨ηü∨§·◧﹪d‹⟲ OzºκFⅉRï⎇”²¦⁷ω⁰χ”{➙∧⊟≔⊘⬤|↔3Zθ✂≔÷t⍘ε✂↨≔⧴×ld≕≡⌕m⟧6ψ=Z”⁰¦⁰”}∧80KυgCAêJm⟦↘/§‖Ck⮌C₂¡μ↗W”⁰¦²ω⁰χ”{⊟∨·◧¤∨¶⧴⬤2GL▷⁸ê5Gψ”⁰¦⁰⟧³I§⭆θ⭆³§μ⎇ι⊕ξ⁻⁵ξλ«J⁻⊟κײ⁹¬ι⊟κ⊟κ

在线尝试!链接是详细版本的代码。恐怕有点无聊。大量打印压缩字符串文字。说明:

F⁴≔⮌E§θ⁰⁺00⭆θ§μλθ

在阵列的两边各加两个额外的0s。

≔E✂θ⊖ζ⁺⁶ζ¹✂ι⊖η⁺⁶η¹θ

7x7以给定坐标为中心切片数组的一个子部分。

Fε≔⮌E§θ⁰⭆θ§μλθ

根据给定方向旋转阵列。

B³⁰χ 

(请注意尾随空格)画一个空30×10框,以便输出始终是一致的大小。

F²«‖

分别画出各半部分,并在中间画出。

FΦ⪪⟦...⟧³I§⭆θ⭆³§μ⎇ι⁻⁵ξ⊕ξλ«

取得一个墙描述符数组,将其分成(字符串,y坐标,x坐标)大块,过滤在数组的相关部分的相关位置处有墙的那些块,然后在墙上循环。通过从数组中提取12面墙并使用块索引对它们进行索引来计算位置,因为与使用块索引直接定位壁相比,这更具高尔夫精神。

J⁻⊟κײ⁹¬ι⊟κ⊟κ

跳到墙的坐标并打印。请注意,反射会将X坐标从否定为负[0, 30),(-30, 0]因此在一次传递中,画布实际上向左移动了29个字符。


1
@Arnauld的确,我完全没有利用对称性,我应该能够通过分别画出一半来减少三分之一。
— 尼尔,

1
+1为168字节的高尔夫击球。我认为这是我在这里看到的最大的单场高尔夫。
— ElPedro '18

2

红宝石,412个391 385 383字节

->a,x,y,d{b=Array.new(97){[" "]*10}
e=[-1,0,1,0]
14.times{|i|m=-i%3-1
w=[31,25,15,9][n=i>2?4-i/3:(m*=2;3)]
(a*3)[y+n*e[d]+m*c=e[d-3]][x+n*c-m*e[d]]&&[p=w*(m*2-1)/2,r=[12,7,4,3][n]*m*m.abs+m/3].min.upto([q=w*(m*2+1)/2,r].max){|j|t=" .'"*9
b[j+15]=(p<j&&j<q ?%w{-%2s- -%4s- _%7s_}[-n]%"":t[k=(j^j>>9)%(36/-~n)]+"   :|  |    |"[k%13]*(k/3*2)+t[-k]).center(10).chars}}
b[0,30].transpose}

在线尝试!

将输入作为真值/假值的数组输入(注意0在Ruby中是真值,但是nil假的。)

输出字符数组。

说明

块以从前到后的方式绘制,距离n减小,并且左右位置m在-1,1,0左右,中间循环。实际上,最远一行的中间块E被绘制了两次,因为我们需要检查块A / B和块C / D。n,m和d用于修改x和y值以搜索数组a。如果x超出范围,nil则返回超出范围的单元格,并且不会引发任何错误,但是如果y超出范围,nil则将为该行返回错误,并且Ruby在尝试搜索该单元格时将引发类型错误。为了避免这种情况,在搜索之前将阵列在垂直方向上一式三份。如果找到真实值,则会绘制一个块。

输出建立在b代表输出列的10个元素的数组中,并在函数末尾转换为10行。绘制了所有块的整个正面(无论它是否出现在视口中),因此数组中需要额外的空间,以避免超出范围的错误。的范围j在视口中的值是从-15对+14,这是通过15保存到阵列时,得到的范围内的偏移0到29。对于每个绘制的块,将计算三个值:p和q分别r用于前壁的左和右角以及侧壁的后侧。j从这三个值的最小值到最大值依次进行迭代。

有3种类型的线:水平-或_,垂直|或:,以及具有重复" .'"图案的对角线。在其中p < j < q包含以-或覆盖的空格的列_被绘制以形成正面。在j此范围之外的地方,包含空格的列|或:用符号从上绘制t=" .'"以形成边缘和/或侧面。这是通过可变管理k=j,其中j为正或k=-j-1其中j为负。大写字母和大写字母之间的字符数是k/3*2。为了正确处理最远的块的外边缘n=3,k必须以9为模,但是对于较小的,则不能这样做。n。k因此取取模为。36/-~n,-~nn+1

非高尔夫代码

->a,x,y,d{
  b=Array.new(97){[" "]*10}                                        #Set up array for output, allow space for plotting outside viewport
  e=[-1,0,1,0]                                                     #Direction offsets from player position
  14.times{|i|                                                     #Iterate through all blocks including block E twice 
    m=-i%3-1                                                       #Cycle -1,1,0 = left, right, centre
    n=i>2?4-i/3:(m*=2;3)                                           #Distance n=4-i/3. But if i/3==0 n=3 and double m for blocks A,B 
    w=[31,25,15,9][n]                                              #Width of front face of block
    r=[12,7,4,3][n]*m*m.abs+m/3                                    #Value of j for back edge of block. m/3 offsets by -1 when m negative 
    (a*3)[y+n*e[d]+m*c=e[d-3]][x+n*c-m*e[d]]&&(                    #If a block is present at the location then
      [p=w*(m*2-1)/2,r].min.upto([q=w*(m*2+1)/2,r].max){|j|        #Calculate left and right edges of front of block p,q and iterate
        t=" .'"*9                                                  #t=character constant for diagonal lines 
        k=(j^j>>9)%(36/-~n)                                        #k=j for positive j=distance from centre. For negative j, k=-1-j by XOR with j>>9=-1. If n=3 take modulo 9 for correct output of outer side of block. 
        b[j+15]=(p<j&&j<q ?%w{-%2s- -%4s- _%7s_}[-n]%"":           #If j between p&q, draw horizontal lines separated by 2,4 or 7 spaces depending on value of n
        t[k]+"   :|  |    |"[k%13]*(k/3*2)+t[-k]).center(10).chars #else draw space or vertical line capped by diagonal markers
      }
    )
  }
b[0,30].transpose}                                                 #Truncate values outside viewport, transpose, and return value.

好答案!我喜欢以编程方式生成所有线条的方式,包括对角线。
— Arnauld
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.