2016-10-04 60 views
2

我實現跳棋在SWI-Prolog的,並創建了一個檢查,如果給定的舉動是合法的謂詞:Prolog的等價算

check_piece_move(white, X/Y, NewX/NewY) :- 
    AcceptedX1 is X+1, AcceptedX2 is X-1,   % white can move to either next or previous column 
    AcceptedY is Y+1,        % and one row upwards 
    (AcceptedX1 == NewX; AcceptedX2 == NewX),  % make sure NewX is acceptable 
    AcceptedY == NewY.        % make sure NewY is acceptable 

此斷言效果很好,如果我足夠提前的所有變量(即給X/Y和NewX/NewY)。不過,我現在希望它執行相反的事情 - 給定X/Y,它將滿足NewX/NewY的可能性。 我能做些什麼改變? 謝謝。

+0

你怎麼知道什麼是可以接受的?不立即從您的問題或您的代碼清除。你有紙板尺寸嗎? – 2016-10-04 06:33:54

回答

3

您可以取代==與統一=(所以你的情況時NewsX是可變的,它沒有哪個成功的,如果條件是相同的):

check_piece_move(white, X/Y, NewX/NewY) :- 
    AcceptedX1 is X+1, AcceptedX2 is X-1,   
    AcceptedY is Y+1,        
    (AcceptedX1 = NewX; AcceptedX2 = NewX),  
    AcceptedY = NewY.        

例子:

?- check_piece_move(white,1/2,NewX/NewY). 
NewX = 2, 
NewY = 3 ; 
NewX = 0, 
NewY = 3. 

一個更好的途徑將通過使用CLPFD:

:- use_module(library(clpfd)). 

check_piece_move(white, X/Y, NewX/NewY) :- 
     abs(X-NewX) #= 1, 
     Y+1 #= NewY. 

如果提供了X/Y或NewX/NewY中的任何一個,則此功能可用:

?- check_piece_move(white,X/Y,3/1). 
X = 4, 
Y = 0 ; 
X = 2, 
Y = 0. 

?- check_piece_move(white,3/1,NewX/NewY). 
NewX = NewY, NewY = 2 ; 
NewX = 4, 
NewY = 2. 

?- check_piece_move(white,X/Y,3/1). 
X = 4, 
Y = 0 ; 
X = 2, 
Y = 0. 

?- check_piece_move(white,3/Y,NewX/1). 
Y = 0, 
NewX = 2 ; 
Y = 0, 
NewX = 4. 

?- check_piece_move(white,X/1,3/NewY). 
X = 4, 
NewY = 2 ; 
X = NewY, NewY = 2. 

?- check_piece_move(white,X/Y,NewX/NewY). 
NewX+1#=X, 
Y+1#=NewY ; 
X+1#=NewX, 
Y+1#=NewY. 
+0

零件仍可能脫落。如果董事會規模也被作爲一個論點,我想這會更好一些。 – 2016-10-04 06:49:57

+0

你可以簡單地將'Y'與'NewY'統一起來。 – 2016-10-04 06:50:35

+0

但他希望統一AccYYY = Y + 1與NewY,所以他需要計算AcceptedY? – coder