1
votes

I have a problem with prolog predicate.

I have one board and i want to check when one player dont have pieces with values between 1 and 10 called mobile pieces. The code are showed above:

test_board([
      [piece('   ',12,blk),piece('R2 ',2,red),piece('RB ',11,red),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('   ',12,blk),piece('RB ',11,red),piece('RF ',0,red),piece('RB ',11,red),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('RB ',11,red),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('   ',12,blk),piece('   ',12,blk),piece('RB ',11,red),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('   ',12,blk),piece('   ',12,blk),piece('X  ',13,for),piece('X  ',13,for),piece('   ',12,blk),piece('   ',12,blk),piece('X  ',13,for),piece('X  ',13,for),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('   ',12,blk),piece('   ',12,blk),piece('X  ',13,for),piece('X  ',13,for),piece('   ',12,blk),piece('   ',12,blk),piece('X  ',13,for),piece('X  ',13,for),piece('   ',12,blk),piece('   ',12,blk)],
      [piece('B6 ', 6,blue),piece('B4 ', 4,blue),piece('B5 ', 5,blue),piece('B10',10,blue),piece('B7 ', 7,blue),piece('B4 ', 4,blue),piece('B8 ', 8,blue),piece('B9 ', 9,blue),piece('B5 ', 5,blue),piece('B4 ', 4,blue)],
      [piece('B7 ', 7,blue),piece('B2 ', 2,blue),piece('B5 ', 5,blue),piece('BB ',11,blue),piece('B3 ', 3,blue),piece('B6 ', 6,blue),piece('B3 ', 3,blue),piece('B1 ', 1,blue),piece('B2 ', 2,blue),piece('B3 ', 3,blue)],
      [piece('B3 ', 3,blue),piece('B2 ', 2,blue),piece('BB ',11,blue),piece('B3 ', 3,blue),piece('BB ',11,blue),piece('B2 ', 2,blue),piece('BB ',11,blue),piece('B6 ', 6,blue),piece('B2 ', 2,blue),piece('B7 ', 7,blue)],
      [piece('B2 ', 2,blue),piece('B6 ', 6,blue),piece('B5 ', 5,blue),piece('B4 ', 4,blue),piece('B2 ', 2,blue),piece('BB ',11,blue),piece('BF ',0,blue),piece('BB ',11,blue),piece('B8 ', 8,blue),piece('B2 ', 2,blue)]]
).

check_mobile_pieces([],_):-
  fail.

check_mobile_pieces([BoardHead|BoardTail],Opponent):-
  check_mobile_pieces_line(BoardHead,Opponent);
  check_mobile_pieces(BoardTail,Opponent).

check_mobile_pieces_line([],_):-
  fail.

check_mobile_pieces_line([LineHead|LineTail],Opponent):-
  piece(_,PieceValue,Opponent)=LineHead,
  ((PieceValue > 0, PieceValue<11) -> true
                                   ;check_mobile_pieces_line(LineTail,Opponent)).

In this example the result should be "yes" but is "no"..Why? Anyone can get the error in code?

Regards

1

1 Answers

1
votes

You should say what query you issue, isn't apparent to me. Indeed much of the Prolog behaviour is controlled with instantiation of variables, and without knowing what's Opponent binding it's hard to answer.

Anyway, I think you will get false because Opponent keep changing for each element in a line, then piece(_,PieceValue,Opponent)=LineHead, will make check_mobile_pieces_line/2 will fail before performing the test you are interested in.

edit the simplest way to search in a list is using member/2. Then to see if a Player has movable pieces:

has_movable(Player) :-
  test_board(Board),
  member(Row, Board),                    % peek a row
  member(piece(_, Value, Player), Row),  % peek a Player'piece
  Value > 0, Value < 11.

To say that a Player has no movables:

....
\+ has_movable(Player),
....