最近在學 Ruby,而要學一個 programming language 最快的方法就是動手去寫,可是工作之餘我又沒太多時間可以寫大一點的程式,因此我通常會找 Programming Challenges 裡面的題目來自娛。
下面的程式就是我的第一個 Ruby 程式: 解 Check The Check 這個問題:
class Chess
@@capture =
{
'p' => [[-1, 1, 1], [ 1, 1, 1]],
'P' => [[-1, -1, 1], [ 1, -1, 1]],
'r' => [[ 1, 0, 8], [-1, 0, 8], [0, 1, 8], [ 1, 0, 8]],
'b' => [[-1, 1, 8], [ 1, 1, 8], [1, -1, 8], [-1, -1, 8]],
'n' => [[-2, -1, 1], [-1, -2, 1], [1, -2, 1], [ 2, -1, 1], [2, 1, 1], [1, 2, 1], [-1, -2, 1], [-2, -1, 1]],
'k' => [[-1, 1, 1], [ 1, 1, 1], [1, -1, 1], [-1, -1, 1], [1, 0, 1], [0, 1, 1], [-1, 0, 1], [ 0, -1, 1]],
'q' => [[-1, 1, 8], [ 1, 1, 8], [1, -1, 8], [-1, -1, 8], [1, 0, 8], [0, 1, 8], [-1, 0, 8], [ 0, -1, 8]],
}
@@capture.each_key {|p| @@capture[p.upcase] = @@capture[p] unless @@capture.has_key?(p.upcase)}
def initialize
@board = Array.new(8) { loop { line = gets.chomp.strip; break line if line.length >= 8 } }
end
def is_empty
@board.select{|row| row == '.' * 8}.length == 8
end
def in_check
0.upto(7) do |y|
0.upto(7) do |x|
piece = @board[y][x..x]
if @@capture[piece]:
cap = check_capture(piece, x, y)
return cap[0] if cap.length > 0
end
end
end
"no"
end
def check_capture(piece, col, row)
@@capture[piece].collect{|dir| check_dir(piece, col, row, dir)}.compact
end
def check_dir(piece, x, y, dir)
dir[2].times do
x += dir[0]
y += dir[1]
break if !(0..7).include?(x) or !(0..7).include?(y)
case @board[y][x..x]
when 'k': return 'black' if ('A'..'Z').include?(piece)
when 'K': return 'white' if ('a'..'z').include?(piece)
when '.': next
else break
end
end
nil
end
end
i = 1
loop do
c = Chess.new
break if c.is_empty
print "Game \##{i}: #{c.in_check} king is in check\n"
i += 1
end
結論是:code block 實在是太好用了,會讓你走火入魔每個地方都想用一下…