Ruby - 510 ký tự
Khá là một con voi ma mút; nhưng đó là lần đầu tiên tôi thử chơi gôn.
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
Đầu vào là bởi tệp được chỉ định làm đối số; Tôi giả sử tệp đầu vào bao gồm một khối ký tự hình chữ nhật (vì vậy, bao gồm các khoảng trắng ở cuối) và để có một dòng mới.
Phiên bản này sử dụng rộng rãi catch-throwđể thoát khỏi các vòng lặp sâu; Thay vào đó, tôi có thể cải thiện các vấn đề với các vòng kiểm tra giới hạn.
Mã không được kiểm tra:
# 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
Biên tập
Ilmari Karonen lưu ý trong các câu hỏi nhận xét rằng thuật toán thị giác đã cho không nhìn thấy tất cả các hình vuông, ngay cả khi không có chướng ngại vật. Đây là một minh chứng cho điều đó, cách xa người chơi (40,40).
@.......................................
........................................
........................................
........................................
........................................
............ ...........................
.............. ........................
............ ... ..... ...............
.............. ... ..... ...........
............... ... ..... .......
................. ... ..... ...
.................. ... .....
..... . ............ ... .....
..................... ... ...
...... . .............. ...
...... .. .............. ...
....... . ................ ...
....... .. ............. .. ...
....... . ................. ...
........ .. ............... .. ...
........ . ............... ... .
........ .. ................ ..
......... . ................. ...
......... .. ................. ..
....... . . . ................ ...
.......... .. ................... ..
.......... . ................... ..
........ . .. . ..................
........ .. . .. ..................
........... .. .....................
......... . . . ..................
......... .. .. .. .................
......... .. . .. ................
.......... . .. . ................
.......... .. . .. ...............
.......... .. .. .. ..............
.......... . . . .............
........... .. .. .. .............
........... .. . .. ............
........... . .. . ...........