রুবি - 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) দূরে।
@.......................................
........................................
........................................
........................................
........................................
............ ...........................
.............. ........................
............ ... ..... ...............
.............. ... ..... ...........
............... ... ..... .......
................. ... ..... ...
.................. ... .....
..... . ............ ... .....
..................... ... ...
...... . .............. ...
...... .. .............. ...
....... . ................ ...
....... .. ............. .. ...
....... . ................. ...
........ .. ............... .. ...
........ . ............... ... .
........ .. ................ ..
......... . ................. ...
......... .. ................. ..
....... . . . ................ ...
.......... .. ................... ..
.......... . ................... ..
........ . .. . ..................
........ .. . .. ..................
........... .. .....................
......... . . . ..................
......... .. .. .. .................
......... .. . .. ................
.......... . .. . ................
.......... .. . .. ...............
.......... .. .. .. ..............
.......... . . . .............
........... .. .. .. .............
........... .. . .. ............
........... . .. . ...........