ส่องสว่าง Roguelike


14

ให้บอร์ดเขียนโปรแกรมหรือฟังก์ชั่นที่สั้นที่สุดเพื่อแสดงหรือย้อนกลับไปว่าตัวละครใดที่อยู่ในสายตาของผู้เล่น ตัวละครอยู่ในสายตาถ้าเป็นไปได้ที่จะลากเส้นระหว่างมันกับผู้เล่นโดยไม่ต้องข้ามตัวละครใด ๆ ที่ขวางการมองเห็น

การป้อนข้อมูล:

  • @แสดงถึงตำแหน่งของผู้เล่น จะมีเพียงหนึ่งในสิ่งเหล่านี้ในอินพุต
  • อักขระใด ๆ ที่ตรงกับ regex [#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
โอเค ... ค้างคาวทุกชนิดเห็ดราและงูและแม้กระทั่งสิ่งกีดขวางต่างก็ขวางกั้นมุมมอง แต่การเลียนแบบขนาดใหญ่, ผี, เนินเขา, มาสโทดอนสิ่งมีชีวิตอื่น ๆ หรือแม้แต่ไฟไหม้ vortices ไม่?
John Dvorak

@JanDvorak ฉันขี้เกียจและเลือกอักษรตัวใหญ่สำหรับการปิดกั้น สัตว์ประหลาดที่ชอบ TALL และสัตว์ประหลาดสั้น ๆ ; สิ่งที่คุณจะได้เห็น ใช่.
Justin

1
ฉันไม่รู้เกี่ยวกับกลศาสตร์ควอนตัม แต่ค้างคาวและมัมมี่มัมมี่อาจเป็นเรื่องง่าย การเลียนแบบอาจทำให้สิ่งต่าง ๆ ซับซ้อนขึ้นอีก นอกจากนี้มดสามตัวนั้นอาจสนุกและสัตว์ประหลาดกลุ่มใหญ่ที่อยู่ทางตะวันออกเฉียงเหนืออาจรู้จักคุณอยู่แล้ว ใช่ ... มันอาจจะน่ารังเกียจ สำหรับ # 3 - การเลื่อนกระแสจิตของฉันอยู่ที่ไหน โอ๊ะนั่นคือการทำลายเกราะ
John Dvorak

3
เป็นเพียงการสังเกตที่แปลกประหลาด แต่ถ้าฉันเข้าใจคำจำกัดความของคุณของ "บรรทัด" ขวาดูเหมือนว่ามีบางช่องที่ไม่สามารถมองเห็นได้แม้ไม่มีอุปสรรคใด ๆ ตัวอย่างเช่นหากผู้เล่นอยู่ที่ (0, 0) ดังนั้นจะไม่สามารถเข้าถึงจตุรัสที่ (5, 12) ได้ทุกบรรทัด มันอาจจะเหมาะสมกว่าที่จะพูดระบุการใช้งานตามมาตรฐานของ Bresenham สำหรับการวาดเส้นระหว่างจุดสองจุดใด ๆ และกำหนดสี่เหลี่ยมจัตุรัสหากถูกบดบังหากเส้นแบ่งระหว่างมันกับผู้เล่นตัดกับสิ่งกีดขวาง
Ilmari Karonen

1
@IlmariKaronen คุณถูกต้องอย่างแน่นอน นั่นเป็นเพียงวิธีที่ฉันชอบ :-)
Justin

คำตอบ:


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*

อินพุตต้องถูกจัดเตรียมไว้ใน STDIN

เอาต์พุตสำหรับตัวอย่างที่ระบุด้านบนแตกต่างกันเล็กน้อย ฉันยืนยันการตอบกลับด้วยมือและคิดว่าถูกต้อง

ตัวอย่างที่ 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+รหัส
Howard

4

Ruby - 510 ตัวอักษร

ค่อนข้างมหึมา; แต่นี่เป็นครั้งแรกที่ฉันพยายามตีกอล์ฟ

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

คุณแน่ใจไหม? ฉันจะได้ทำผิดพลาด ...
จัสติน

ค่อนข้างแน่ใจ - ฉันเห็นวีหลังกำแพง! ฉันคิดว่าฉันไม่ได้ตรวจพบบรรทัดใหม่หลังจากบรรทัดก่อนหน้า
Chowlett

แน่นอนไม่ควรจะเห็นว่า ...
จัสติน

อามันเป็นปัญหากับอินพุตของฉัน XqQผมมีพื้นที่พิเศษหลังจาก ที่กล่าวว่าคำตอบที่ได้รับของคุณสำหรับ 3 ไม่ตรงกับ testcase ที่ทุกคน - มันอย่างน้อยมีสายพิเศษที่ด้านบนและมีเพียงหนึ่งช่องว่างระหว่างและO l
Chowlett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.