'Determine next state predicate prolog

I have a list with 5 elements, 2 black elements, 2 white, and an empty spot ("v"). I have a state represented by [w, w, v, b, b] with White player and Black player.

Each player plays turn by turn, and can move one of his element forward. He can't move it backward.

I want to write a predicate that determines all possible states after player P played.

For exemple, we'll have:

next_state([w, w, v, b, b], W, L).
 L = [v, w, w, b, b];
 L = [w, v, w, b, b];
 false.

But I don't know how to procede. Thanks



Solution 1:[1]

If the skipping-over-same-player's-piece rule is limited to moving a maximum of 2 positions forward, then this should suffice:

player(w, forwards).
player(b, backwards).


state_player_next(State, Player, State1) :-
    player(Player, Direction),
    (   Direction == forwards ->
        state_player_next_(State, Player, State1)
    ;   reverse(State, StateReverse),
        state_player_next_(StateReverse, Player, State1Reverse),
        reverse(State1Reverse, State1)
    ).


% Make move in correct direction, leaving behind space (v)
state_player_next_([Player, Next|T], Player, [v, Player|T]) :-
    % Can't take own piece
    dif(Player, Next).

% Jump over the player's 1 other piece
state_player_next_([Player, Player, Next|T], Player, [v, Player, Player|T]) :-
    % Can't take own piece
    dif(Player, Next).

% Piece (or space) stays where it is
state_player_next_([P|T], Player, [P|State1]) :-
    state_player_next_(T, Player, State1).

Result in swi-prolog:

?- state_player_next([w, w, v, b, b], Player, LstNext).
Player = w,
LstNext = [v,w,w,b,b] ;
Player = w,
LstNext = [w,v,w,b,b] ;
Player = b,
LstNext = [w,w,b,b,v] ;
Player = b,
LstNext = [w,w,b,v,b] ;
false.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 brebs