Knight’s tour is a sequence of moves of a knight on a chessboard such that the knight visits every square only once, for more info please check Wikipedia.
So assuming we have N*N chessboard, say N=5 for simplicity, whose squares are numbered from 0 to 24, as shown:
I wrote the code below to get random array tour_indices for possible indices of the movements, i.e.
tour_indices[0] is the square index of the first move (e.g. 6).
tour_indices[1] is the square index of the second move (e.g. 13).
tour_indices[2] is the square index of the third move (e.g. 22).
tour_indices[24] is the square index of the last move.
But I got solver timeout from 3 out of 4 commercial simulator :-) (EDA playground: Edit code - EDA Playground)
So I do appreciate your reply if you have a better solution that doesn’t disturb the solver :-)
`define size 5
class knightTour #(int N = 5);
rand byte tour_indices[N*N];
rand byte curr_row_idx[N*N];
rand byte curr_col_idx[N*N];
rand byte next_row_diff[N*N];
rand byte next_col_diff[N*N];
constraint c_next_diff {
foreach(next_row_diff[i]){
next_row_diff[i] inside {-2, -1, 1, 2};
curr_row_idx[i] == 0 -> next_row_diff[i] inside {1, 2};
curr_row_idx[i] == 1 -> next_row_diff[i] inside {-1, 1, 2};
curr_row_idx[i] == N-2 -> next_row_diff[i] inside {-2, -1, 1};
curr_row_idx[i] == N-1 -> next_row_diff[i] inside {-2, -1};
}
foreach(next_col_diff[i]){
next_col_diff[i] inside {-2, -1, 1, 2};
curr_col_idx[i] == 0 -> next_col_diff[i] inside {1, 2};
curr_col_idx[i] == 1 -> next_col_diff[i] inside {-1, 1, 2};
curr_col_idx[i] == N-2 -> next_col_diff[i] inside {-2, -1, 1};
curr_col_idx[i] == N-1 -> next_col_diff[i] inside {-2, -1};
}
foreach(next_col_diff[i]){
next_row_diff[i] inside {-2, 2} -> next_col_diff[i] inside {-1, 1};
next_row_diff[i] inside {-1, 1} -> next_col_diff[i] inside {-2, 2};
}
}
constraint c_row_indices {
foreach(curr_row_idx[i]){
curr_row_idx[i] inside {[0:N-1]};
(i>0) -> curr_row_idx[i] == curr_row_idx[i-1]+next_row_diff[i-1];
}
}
constraint c_col_indices {
foreach(curr_col_idx[i]){
curr_col_idx[i] inside {[0:N-1]};
(i>0) -> curr_col_idx[i] == curr_col_idx[i-1]+next_col_diff[i-1];
}
}
constraint c_tour_indices {
unique {tour_indices};
foreach(tour_indices[i]){
tour_indices[i] inside {[0:N*N-1]};
tour_indices[i] == N*curr_row_idx[i]+curr_col_idx[i];
}
}
endclass
module testbench;
knightTour #(`size) m_knightTour;
initial begin
m_knightTour = new();
repeat(3) begin
if(m_knightTour.randomize()) begin
$write("tour_indices ");
for (int i = 0; i < `size*`size; i++) $write( "%d ", m_knightTour.tour_indices[i]);
$display("\n=====================================\n");
end
else
$error("ERROR");
end
end
endmodule