Skip to content

Instantly share code, notes, and snippets.

@yxhuvud
Created September 20, 2010 12:32
Show Gist options
  • Save yxhuvud/587833 to your computer and use it in GitHub Desktop.
Save yxhuvud/587833 to your computer and use it in GitHub Desktop.
class KnightTravails
def initialize size=8
@size = size
@board = Array.new(@size) { Array.new(@size)}
end
def knight_path start_node, end_node, forbidden_nodes
mark_forbidden forbidden_nodes
path = breadth_first_search start_node, end_node
print_path path
end
def mark_forbidden forbidden_nodes
forbidden_nodes.each do |el|
@board[ el[0].ord - 97 ][ Integer(el[1,1]) - 1 ] = :forbidden
end
end
def breadth_first_search start_node,end_node
queue = [end_node] #searches from end to start
queue.each do |i,j|
generate_new_moves(i,j).map do |k,l|
queue << [k,l]
return get_path(start_node,end_node) if [k,l] == start_node
end
end
return false
end
def print_path path
if path
path.each do |i,j|
print (i+97).chr
puts j + 1
end
else
puts "Path not found"
end
end
def get_path start_node,end_node
node = start_node
path = [node]
while node != end_node
node = @board[node[0]][node[1]]
path << node
end
path
end
def in_bounds? k,l
k >= 0 && l >= 0 && k < @size && l < @size
end
def moves
[[1,2],[-1,2],[1,-2],[-1,-2],
[2,1],[-2,1],[2,-1],[-2,-1]]
end
def generate_new_moves i,j
new_moves = moves.map do |k,l|
[i+k, j+l]
end.reject do |k,l|
!in_bounds?(k,l) || (@board[k][l] ) #marked or outside the board
end
new_moves.each do |k,l|
#mark as used and store origin
@board[k][l] = [i,j]
end
new_moves
end
end
if __FILE__ == $0
start_node, end_node,*forbidden = ARGV
start_node = [start_node[0].ord - 97, Integer(start_node[1,1]) - 1]
end_node = [end_node[0].ord - 97, Integer(end_node[1,1]) - 1]
KnightTravails.new.knight_path start_node, end_node, forbidden
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment