एक Roguelike ऊपर प्रकाश


14

एक बोर्ड को देखते हुए, खिलाड़ी की दृष्टि में कौन से वर्ण हैं या प्रदर्शित करने के लिए सबसे छोटा कार्यक्रम या फ़ंक्शन लिखें। एक चरित्र दृष्टि में है अगर दृष्टि को अवरुद्ध करने वाले किसी भी चरित्र को पार किए बिना, इसके और खिलाड़ी के बीच एक रेखा खींचना संभव है।

इनपुट:

  • @खिलाड़ी की स्थिति का प्रतिनिधित्व करता है। इनपुट में इनमें से केवल एक ही होगा।
  • कोई भी चरित्र जो रेगेक्स [#A-Z]ब्लॉक की दृष्टि से मेल खाता है ।
  • किसी भी वर्ण से मेल खाता है [ a-z]जो दृष्टि की अनुमति देता है।
  • कोई अमान्य वर्ण नहीं होगा
  • आपको एक आयताकार इनपुट की गारंटी है

लाइनों को निम्नानुसार परिभाषित किया गया है:

  • एक परिमाण और एक दिशा होने के लिए वेक्टर को परिभाषित करें
  • एक दिशा N, NE, E, SE, S, SW, W, NW में से एक है
  • एक परिमाण है कि गिनती करने के लिए उस दिशा में कितने वर्ण हैं
  • प्रारंभिक वेक्टर को d 1 कहा जाता है ; दूसरा वेक्टर d 2 कहलाता है
  • डी 1 या डी 2 में से एक का परिमाण होना चाहिए 1; दूसरे के पास जो भी परिमाण हो सकता है
  • d 1 की दिशा d 2 दिशा के समीप होनी चाहिए (उदाहरण: N और NE)

एक पंक्ति को डी 1 , फिर डी 2 , डी 1 , डी 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 मैं आलसी था और अवरुद्ध करने के लिए बड़े अक्षरों को चुना। छोटे राक्षसों बनाम छोटे राक्षसों की तरह; जिसे आप देख पाएंगे। तो हाँ।
जस्टिन

1
मैं क्वांटम यांत्रिकी के बारे में नहीं जानता, लेकिन चमगादड़ और सूक्ति माँ एक आसान सौदा हो सकता है। नकल हालांकि चीजों को और जटिल कर सकती है। इसके अलावा, वे तीन चींटियाँ मज़ेदार हो सकती हैं, और उत्तर-पूर्व में मिश्रित राक्षसों के बड़े समूह को पहले से ही आपके बारे में पता चल सकता है। हाँ ... यह बुरा हो सकता है। # 3 के लिए - मेरा टेलिस्कोपिक स्क्रॉल कहां है? उफ़, वह कवच नष्ट कर रहा था।
जॉन ड्वोरक

3
बस एक जिज्ञासु अवलोकन, लेकिन अगर मैं "लाइन" की आपकी परिभाषा को सही समझता हूं, तो ऐसा लगता है कि कुछ ऐसे वर्ग हैं जो बिना किसी बाधा के भी दिखाई नहीं देंगे । उदाहरण के लिए, यदि खिलाड़ी (0, 0) पर है, तो वर्ग (5, 12) किसी भी रेखा से नहीं जा सकता है। यह कहने में अधिक समझ में आता है, किसी भी दो बिंदुओं के बीच एक रेखा खींचने के लिए ब्रेसेनहैम की लाइन एल्गोरिथ्म के कुछ विहित कार्यान्वयन को निर्दिष्ट करें, और एक वर्ग को अस्पष्ट रूप में परिभाषित करें यदि इसके और खिलाड़ी के बीच की रेखा एक बाधा को पार करती है।
इल्मरी करोनें

1
@IlmariKaronen आप बिल्कुल सही हैं। बस मुझे यह पसंद है। :-)।
जस्टिन

जवाबों:


5

गोल्फस्क्रिप्ट, 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. ...   

यह सिंगल लाइन इनपुट्स (जो कि मान्य आयताकार हैं ...) के लिए काम नहीं करता है
जस्टिन 4

@Quincunx कोड मानता है कि आप अपने इनपुट को एक नई रेखा के साथ अंतिम रूप देते हैं। वैकल्पिक रूप n+से कोड के लिए प्रस्तुत करना।
हावर्ड

4

रूबी - 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

संपादित करें

इल्मरी करोनन ने टिप्पणी में टिप्पणी की है कि दी गई दृष्टि एल्गोरिदम सभी वर्गों को नहीं देखती है, भले ही कोई बाधा न हो। यहाँ खिलाड़ी से दूर (40,40) तक का प्रदर्शन है।

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

हम्म। यह परीक्षण विफल रहता है। डीबगिंग की आवश्यकता है।
चौलेट

क्या आपको यकीन है? मैं एक गलती कर सकता था ...
जस्टिन

बहुत यकीन है - मैं दीवार के पीछे वी देख सकता हूं! मुझे लगता है कि मैं पिछली पंक्ति के बाद नई लाइन का पता नहीं लगा रहा हूं।
चौलेट २ Chow

निश्चित रूप से यह नहीं देखा जाना चाहिए ...
जस्टिन

आह, यह मेरे इनपुट के साथ एक समस्या थी; मेरे पास एक अतिरिक्त जगह थी XqQ। जिसके अनुसार, 3 के लिए अपने दिए गए जवाब बिल्कुल testcase का मिलान नहीं करती - यह कम से कम शीर्ष पर एक अतिरिक्त पंक्ति है, और के बीच केवल एक ही जगह Oऔर l
चौलेट्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.