点亮Roguelike


14

给定一块板,编写最短的程序或函数以显示或返回玩家看到的字符。如果有可能,可以在角色和玩家之间划一条线,而不会越过阻碍视线的角色,则该角色就在视线范围内。

输入:

  • @代表玩家的位置。输入中将只有这些之一。
  • 任何与正则表达式匹配的字符都会[#A-Z]阻碍视觉。
  • 任何符合条件的字符都[ a-z]可以使人视觉。
  • 不会有无效字符
  • 您可以保证输入矩形

行定义如下:

  • 将向量定义为大小和方向
  • 方向是N,NE,E,SE,S,SW,W,NW之一
  • 数量级是沿该方向要计数的字符数
  • 令初始向量称为d 1;第二个向量称为d 2
  • d 1或d 2之一必须具有大小1; 另一个可能有任何大小
  • d 1的方向必须与d 2的方向相邻(例如:N和NE)

一条线被定义为沿路径通过应用d 1,然后d 2,d 1,d 2 ... 标记的所有字符。

采样线(由.s 给出):
d 1 =(幅度:4,方向:E)
d 2 =(幅度:1,NE方向)

               .....
          .....
     .....
@.... 

输出:

  • 每个可见字符都在正确的位置,.以空格代替。
  • 每个不可见字符的空间。

输入样例:

@         
    K     
 J        

    L   




         o

对应的输出:

@.........
....K.....
.J.....   
..........
.. .L.....
..  . ....
... .. ...
...  .. ..
...   .  .
....  ..  

样本输入:

 B###M#  by 
 #Q   # Zmpq
 # # aaa    
@  m #      
# ##P#      
# ####      
# ####      
#M ###      
######      

对应输出:

.B  #M      
.# ..   Z pq
.#.#.aaa..  
@..m.#      
#.##P#      
 .#         
 .#         
 M.         
  #         

输入样例:

  w                 

     O  l   gg  rT  
   QQL      Ag  #b  
   qqqqq         XqQ
 x     V# f@aa      
   Y        aaa     
   uU  E  l TaKK    
  e  dd  FF d opi   
   e       d        

对应的输出:

   ..........  .....
    ......... ..... 
     O..l...gg..rT  
...QQL......Ag..#b..
...qqqqq.........XqQ
        #.f@aa......
   Y........aaa.....
...uU..E..l.TaKK....
      d..FF.d.op    
     .... .d. ...   

3
好吧...蝙蝠,各种真菌,霉菌和蛇,甚至还有幽灵都挡住了视线,但是巨型模仿物,山地兽人,兽足,各种其他生物甚至是火涡流都不会吗?
约翰·德沃夏克

@JanDvorak我很懒,所以选择了大写字母来进行屏蔽。有点像矮小的怪物和矮小的怪物;您将能够看到。是的
贾斯汀2014年

1
我不了解量子力学,但是蝙蝠和侏儒木乃伊可能很容易。模仿可能会使事情进一步复杂化。另外,这三只蚂蚁可能很有趣,而东北的一大群各种各样的怪物可能已经了解您。是的...可能令人讨厌。至于#3-我的电话簿在哪里?糟糕,这是摧毁盔甲。
约翰·德沃夏克

3
只是一个奇怪的发现,但是如果我理解您对“线”的定义正确,那么看起来似乎有些正方形即使没有任何障碍也将不可见。例如,如果玩家在(0,0)处,则任何行都无法到达(5,12)处的正方形。例如,指定布雷森汉姆线算法的一些规范实现以在任意两点之间绘制一条线可能更有意义,并且将正方形定义为如果玩家和玩家之间的线与障碍物相交则被遮盖。
Ilmari Karonen 2014年

1
@IlmariKaronen你是完全正确的。这就是我喜欢的方式。:-)。
贾斯汀2014年

Answers:


5

GolfScript,171个字符

.n?):L)[n*.]*1/:I'@'?{\+[{1$+}*]..{I=26,{65+}%"#
"+\?)}??)<}+{[L~.).)1L)L.(-1L~]>2<`{[.[~\]]{1/~2$*+L*.-1%}%\;~}+L,%~}8,%%{|}*`{1$?)I@=.n=@|\.' '={;'.'}*' 'if}+I,,%''*n%n*

输入必须在STD​​IN上提供。

上面给出的示例的输出略有不同。我手动验证了回复,并认为它们是正确的。

范例1:

@.........
....K.....
.J.....   
..........
.. .L.....
..  . ....
... .. ...
...  .. ..
...   .  .
....  ..  

范例2:

.B  #M      
.# ..   Z pq
.#.#.aaa..  
@..m.#      
#.##P#      
 .#         
 .#         
 M.         
  #         

范例3:

   ..........  .....
    ......... ..... 
     O..l...gg..rT  
...QQL......Ag..#b..
...qqqqq.........XqQ
        #.f@aa......
   Y........aaa.....
...uU..E..l.TaKK....
      d..FF.d.op    
     .... .d. ...   

这似乎不适用于单行输入(这是有效的矩形...)
贾斯汀

@Quincunx代码假定您使用换行符来完成输入。或者n+,在代码之前。
2014年

4

红宝石-510个字符

猛ma象 但这是我第一次尝试高尔夫。

m=$<.read;w,s,o,p=m.index(?\n)+1,m.size,m.dup.gsub(/[^@\n]/,' '),m.index(?@);d=[-w,1-w,1,w+1,w,w-1,-1,-1-w];0.upto(7){|i|x=d[i];[i-1,i+1].each{|j|y=d[j%8];[1,nil].each{|l|t=0;catch(:a){loop{c,f,r=p,1,nil;catch(:b){loop{(l||r)&&(1.upto(t){|u|c+=x;n=!(0...s).include?(c)||m[c]==?\n;n&&throw(f ?:a: :b);o[c]=m[c]==" "??.: m[c];a=m[c]=~/[#A-Z]/;a&&throw(f ?:a: :b)};f=nil);r=1;c+=y;n=!(0...s).include?(c)||m[c]==?\n;n&&throw(f ?:a: :b);o[c]=m[c]==" "??.: m[c];a=m[c]=~/[#A-Z]/;a&&throw(f ?:a: :b)}};t+=1}}}}};$><<o

输入是通过指定为参数的文件进行的;我假设输入文件由矩形字符块组成(因此,包括尾随空格),并且具有尾随换行符。

此版本大量使用catch-throw退出深循环。我可能可以通过边界检查循环来改善问题。

不混淆的代码:

# Read the map in
map = $<.read

# Determine its width and size
width = map.index("\n")+1
size = map.size

# Create a blank copy of the map to fill in with visible stuff
output = map.dup.gsub /[^@\n]/,' '

# Locate the player
player = map.index('@')

dirs = [
  -width,   # N
  1-width,  # NE
  1,        # E
  width+1,  # SE
  width,    # S
  width-1,  # SW
  -1,       # W
  -1-width  # NW
]

0.upto(7) do |i1|
  d1 = dirs[i1]
  [i1-1, i1+1].each do |i2|
    d2 = dirs[i2%8]

    # Stepping by 0,1,2... in d1, work along the line.
    # Write the cell value into the duplicate map, then break if it's
    # a "solid" character.
    #
    # Extensive use of catch-throw lets us exit deep loops.

    # For convenience of notation, instead of having either d1 or d2
    # be magnitude 1, and always doing d1,d2,d1... - I have d2 always
    # being magnitude 1, and doing either d1,d2,d1 or d2,d1,d2...

    # Loop twice - first with d1,d2,d1... second with d2,d1,d2...
    [true,false].each do |long_first|
      step = 0

      catch(:all_done) do
        # This loop increments step each iteration, being the magnitude of d1
        loop do
          cell = player
          first = true  # True until we've done the first d1
          later = false # True once we've done the first d2

          catch(:done) do
            # This loop repeatedly applies d1 and d2
            loop do
              if long_first || later  # Don't apply d1 first if starting with d2
                1.upto(step) do |dd1|
                  cell += d1 # Move one cell in d1
                  invalid = !(0...size).include?(cell) || map[cell]=="\n" # Out of range
                  throw :all_done if first && invalid # No point trying a longer step if the
                                                      # first application of d1 is out of range
                  throw :done if invalid # No point continuing with this step length

                  output[cell]=map[cell] == " " ? '.' : map[cell] # Transfer visble character
                  wall = map[cell]=~/[#A-Z]/  # Hit a wall?
                  throw :all_done if first && wall # Drop out as before
                  throw :done if wall
                end
                first = false
              end
              later=true

              # Now repeat above for the single d2 step
              cell += d2
              invalid = !(0...size).include?(cell) || map[cell]=="\n"
              throw :all_done if first && invalid
              throw :done if invalid
              output[cell]=map[cell] == " " ? '.' : map[cell]
              wall = map[cell]=~/[#A-Z]/
              throw :all_done if first && wall
              throw :done if wall
            end
          end
          step += 1
        end
      end
    end
  end
end

puts output

编辑

Ilmari Karonen在问题注释中指出,即使没有障碍,给定的视觉算法也无法看到所有正方形。这是一个演示,距离播放器(40,40)远。

@.......................................
........................................
........................................
........................................
........................................
............ ...........................
..............  ........................
............ ...   ..... ...............
.............. ...    .....  ...........
...............  ...     .....   .......
.................  ...      .....    ...
..................   ...       .....
..... . ............   ...        .....
.....................    ...         ...
...... . ..............    ...
...... .. ..............     ...
....... . ................     ...
....... .. ............. ..      ...
.......  .  .................      ...
........ .. ............... ..       ...
........  .  ............... ...       .
........  ..  ................ ..
.........  .  ................. ...
.........  ..  .................  ..
....... .   .   . ................ ...
..........  ..  ...................  ..
..........   .   ...................  ..
........ .   ..   . ..................
........ ..   .   .. ..................
...........   ..   .....................
......... .    .    . ..................
......... ..   ..   .. .................
......... ..    .    .. ................
.......... .    ..    . ................
.......... ..    .    .. ...............
.......... ..    ..    .. ..............
..........  .     .     .  .............
........... ..    ..    .. .............
........... ..     .     .. ............
...........  .     ..     .  ...........

嗯 测试失败3.需要调试。
Chowlett 2014年

你确定吗?我可能会犯一个错误...
Justin 2014年

可以肯定-我可以看到墙后的V!我想我没有在上一行之后检测到换行符。
Chowlett 2014年

绝对不应该看到……
贾斯汀

啊,我的输入有问题。之后我有多余的空间XqQ。这就是说,对于3您给出的答案并不测试用例都匹配-它至少在顶部一个额外的行,只有一个之间的空间Ol
Chowlett 2014年
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.