地牢爬行者


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 ] ]

00

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,md用于修改xy值以搜索数组a。如果x超出范围,nil则返回超出范围的单元格,并且不会引发任何错误,但是如果y超出范围,nil则将为该行返回错误,并且Ruby在尝试搜索该单元格时将引发类型错误。为了避免这种情况,在搜索之前将阵列在垂直方向上一式三份。如果找到真实值,则会绘制一个块。

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

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