Solution: Knight's Tour
Go over the solution to the knight's tour puzzle.
We'll cover the following...
Knight's tour
Press + to interact
# Board (5 x 5), Start:[1, 0] No solution@start_pos = [0, 0]@chessboard = [5, 5]@steps = 1@squares = {}@moves_log = []@knight_moves = [[-2, -1], [-1, -2], [1, -2], [2, -1],[2, 1], [1, 2], [-1, 2], [-2, 1]]def print_chessboard( current_pos)puts "\nBoard (#{@chessboard[0]} x #{@chessboard[1]}), Start:[#{@start_pos[0]}, #{@start_pos[1]}]: Done in #{@steps} steps\n\n"@chessboard[0].times do |row|puts " #{@squares[row].join(" | ")}"puts "---- " * @squares[row].sizeendenddef mark_as_visited(knight_pos, step)@squares[knight_pos[0]][knight_pos[1]] = step.to_s.rjust(2, " ")@moves_log << "Moving to: #{knight_pos}"enddef mark_as_unvisited(knight_pos)@squares[knight_pos[0]][knight_pos[1]] = "."@moves_log << "Backtracking: #{knight_pos}"enddef visited_every_square?flattened_squares = @squares.values.flattenflattened_squares.all?{ |x| x.strip != '.' }enddef tour(knight_pos, step = 1)if ( @steps == 1)@chessboard[0].times do |row|@squares[row] = @chessboard[1].times.collect{|x| '.'}endendmark_as_visited(knight_pos, step)if visited_every_square? # end causeprint_chessboard(knight_pos)exitend# checking constraintspossible_moves = @knight_moves.select { |m|next_pos = [ knight_pos[0] + m[0], knight_pos[1] + m[1] ]next_pos[0] >= 0 &&next_pos[1] >= 0 &&next_pos[0] < @chessboard[0] &&next_pos[1] < @chessboard[1] &&@squares[next_pos[0]][next_pos[1]] == "."}# trying all possible movespossible_moves.each do |next_move|next_pos = [ knight_pos[0] + next_move[0], knight_pos[1] + next_move[1] ]@steps += 1tour(next_pos, step + 1) # recursive callmark_as_unvisited(next_pos) # back tracking the visited squaresendreturn # no more solutionsendtour(@start_pos)# only executes when no solution can be foundputs "No solution found showing log:"puts @moves_log
Explanation
Lines 3–12: The following instance variables are defined:
@start_pos
stores the starting position of the knight. The default position[0,0]
refers to the top left corner.@chessboard
stores the dimensions of the chessboard.@steps
is for storing the number of recursive calls made by our algorithm.@squares
is a hash to track if squares of the chessboard have been visited and the order in which they were visited. The state of the squares in row...