/*
Generate a list [1, 2, ..., N] to L.
Permute L to Board.
Check Board if it is safe.
*/
queens( N, Board ) :- !,
range( N, L ),
permutation( L, Board ),
safe( Board ).
range( N, L ) :- decrease( N, Temp ),
reverse( Temp, L ). % Generate a increasing list.
decrease( 0, [] ) :- !.
decrease( N, [H | L] ) :- N = H,
Next is N - 1,
decrease( Next, L ).
safe( [_] ) :- !. % Check if all queens are safe.
safe( [Queen | Others] ) :- !,
nohit( Queen, 1, Others ),
safe( Others ).
nohit( _, _, [] ) :- !. % Check if queens could not attack each other.
nohit( Column, Row_D, [Queen | Others] ) :- !,
nohit( Column, Row_D, Queen ),
Row_D_Next is Row_D + 1,
nohit( Column, Row_D_Next, Others ).
nohit( Column, Row_D, Target ) :- !,
Diag1 is Column + Row_D,
Diag1 =\= Target,
Diag2 is Column - Row_D,
Diag2 =\= Target.
之後只要用
以四佾來說,它會印出:
queens( 4, B ).就可以列出當棋盤大小為四佾時,四個皇后不會互相攻擊的縱座標或橫座標[?]。以四佾來說,它會印出:
B = [2,4,1,3] B = [3,1,4,2]意即第一組解為(1,2)(2,4)(3,1)(4,3)和第二組解為(1,3)(2,1)(3,4)(4,2)。
引數的數字可以依棋盤大小任意更改。由於Prolog是採DFS的方式搜尋,太大的棋盤會跑很久。
沒有留言:
張貼留言