- %przykladowe testy
- %przem(a,1,b,1),
- %przem(a,1,c,1),
- %przem(a,1,c,2).
- %
- %przem(a,1,X,Y).
- board([[w, w, w, w, w, w, w],
- [w, a, b, x, x, x, w],
- [w, x, b, x, x, x, w],
- [w, x, x, b, x, x, w],
- [w, w, w, w, w, w, w]]).
- steps(2).
- steps(4).
- steps(8).
- steps(16).
- steps(32).
- block(a).
- block(b).
- direction(down).
- direction(right).
- direction(up).
- direction(left).
- height(a, X):- X is 1.
- height(b, X):- X is 2.
- height(c, X):- X is 3.
- height(a).
- height(b).
- height(c).
- width(1).
- width(2).
- width(3).
- width(4).
- width(5).
- xydiff(D, Y, X):-
- D = 'left',
- Y is 0,
- X is -1.
- xydiff(D, Y, X):-
- D = 'right',
- Y is 0,
- X is 1.
- xydiff(D, Y, X):-
- D = 'up',
- Y is -1,
- X is 0.
- xydiff(D, Y, X):-
- D = 'down',
- Y is 1,
- X is 0.
- % PREDICATS
- %------------------
- max_steps(MaxSteps):-
- board(Board),
- find_all_objects(Board, Objects, 'x'),
- length(Objects, MaxSteps).
- %------------------
- %------------------
- n_character(N, Chars, Char):-
- string_chars(Chars, Str),
- nth0(N, Str, Char).
- %------------------
- %------------------
- position(Board, Y, X, Character):-
- nth0(Y, Board, Column),
- nth0(X, Column, Character).
- %------------------
- %------------------
- find_corner(Board, Y, X, Character):-
- position(Board, Y, X, Character), !.
- %------------------
- %------------------
- is_position_free(Board, Y, X):-
- position(Board, Y, X, 'x').
- %------------------
- %------------------
- is_position_wall(Board, Y, X):-
- position(Board, Y, X, 'w').
- %------------------
- %------------------
- add_element(List, Element, [Element|List]).
- %------------------
- %------------------
- change_in_list(Index, Elem, [_|T], [Elem|T]):-
- Index = 0,
- !.
- change_in_list(Index, Elem, [H|T], [H|Out]):-
- Index1 is Index - 1,
- change_in_list(Index1, Elem, T, Out).
- %------------------
- %------------------
- insert_into_two_dimensional_array(Y, X, Object, Board, NewBoard):-
- nth0(Y, Board, ColFrom),
- change_in_list(X, Object, ColFrom, NewColFrom),
- change_in_list(Y, NewColFrom, Board, NewBoard).
- %------------------
- %------------------
- unpack_one_element_list([H|_], H).
- unpack_two_element_list([H|T], H, B):-
- unpack_one_element_list(T, B).
- unpack_three_element_list([H|T], H, B, C):-
- unpack_two_element_list(T, B, C).
- %------------------
- %------------------
- find_all_objects(Board, Objects, Character):-
- append(Board, L),
- find_all_objects_unwrap(L, [], Objects, Character).
- find_all_objects_unwrap([], ObjectsTemp, ObjectsTemp, _).
- find_all_objects_unwrap([H|T], ObjectsTemp, Objects, Character):-
- n_character(_, H, Character),
- add_element(ObjectsTemp, H, ObjectsTemp1),
- find_all_objects_unwrap(T, ObjectsTemp1, Objects, Character),!.
- find_all_objects_unwrap([_|T], ObjectsTemp, Objects, Character):-
- find_all_objects_unwrap(T, ObjectsTemp, Objects, Character), !.
- %------------------
- %------------------
- find_all_cords_of_block_unwrap(_, [], ListOfCords, ListOfCords).
- find_all_cords_of_block_unwrap(Board, [H|T], ListOfCordsTemp, ListOfCords):-
- position(Board, Y, X, H),
- insert_into_two_dimensional_array(Y, X, 'T', Board, NewBoard),
- add_element(ListOfCordsTemp, [Y, X], ListOfCordsTemp1),
- find_all_cords_of_block_unwrap(NewBoard, T, ListOfCordsTemp1, ListOfCords), !.
- find_all_cords_of_block(Board, Character, ListOfCords):-
- find_all_objects(Board, Objects, Character),
- find_all_cords_of_block_unwrap(Board, Objects, [], ListOfCords).
- %------------------
- %------------------
- replace_cords_with_character(Board, Board, [], _).
- replace_cords_with_character(Board, NewBoard, [H|T], BlockCharacter):-
- unpack_two_element_list(H, Y, X),
- insert_into_two_dimensional_array(Y, X, BlockCharacter, Board, Board1),
- replace_cords_with_character(Board1, NewBoard, T, BlockCharacter).
- %------------------
- %------------------
- move_cordinates([], NewListOfCords, NewListOfCords , _, _).
- move_cordinates([H|T], TemporaryListOfCords, NewListOfCords, Ydiff, Xdiff):-
- unpack_two_element_list(H, Y, X),
- Y1 is Y + Ydiff,
- X1 is X + Xdiff,
- add_element(TemporaryListOfCords, [Y1, X1], TemporaryListOfCords1),
- move_cordinates(T, TemporaryListOfCords1, NewListOfCords, Ydiff, Xdiff).
- %------------------
- %------------------
- get_new_cords(ListOfCords, NewListOfCords, Direction):-
- xydiff(Direction, Ydiff, Xdiff),
- move_cordinates(ListOfCords, [], NewListOfCords, Ydiff, Xdiff).
- %------------------
- %------------------
- can_single_cell_move(Board, Y, X, Ydiff, Xdiff):-
- position(Board, Y, X, BlockCharacter),
- Y1 is Y + Ydiff,
- X1 is X + Xdiff,
- position(Board, Y1, X1, CellCharacter),
- (CellCharacter = BlockCharacter ; CellCharacter = 'x').
- %------------------
- %------------------
- can_every_cell_move(_, [], _, _).
- can_every_cell_move(Board, [H|T], Xdiff, Ydiff):-
- unpack_two_element_list(H, Y, X),
- can_single_cell_move(Board, Y, X, Xdiff, Ydiff),
- can_every_cell_move(Board, T, Xdiff, Ydiff).
- %------------------
- %------------------
- can_block_move(Board, Direction, ListOfCords):-
- xydiff(Direction, Ydiff, Xdiff),
- can_every_cell_move(Board, ListOfCords, Ydiff, Xdiff).
- %------------------
- %------------------
- move_block(Board, BlockCharacter, Direction, NewBoard):-
- find_all_cords_of_block(Board, BlockCharacter, ListOfCords),
- can_block_move(Board, Direction, ListOfCords),
- replace_cords_with_character(Board, Board1, ListOfCords, x),
- get_new_cords(ListOfCords, ListOfCords1, Direction),
- replace_cords_with_character(Board1, NewBoard, ListOfCords1, BlockCharacter).
- %------------------
- %------------------
- %best move for the game
- one_step(Board, NewBoard):-
- move_block(Board, a, right, NewBoard), !.
- %random move
- one_step(Board, NewBoard):-
- direction(Dir),
- block(BlockCharacter),
- move_block(Board, BlockCharacter, Dir, NewBoard).
- %------------------
- %------------------
- make_move(Board, Board, Steps, MaxSteps, Final_Y, Final_X, []):-
- not(Steps > MaxSteps),
- find_corner(Board, Y, X, a),
- Y is Final_Y,
- X is Final_X,
- !.
- make_move(Board, NewBoard, Steps, MaxSteps, Final_Y, Final_X, MOVES):-
- not(Steps > MaxSteps),
- one_step(Board, BoardT),
- IncSteps is Steps + 1,
- make_move(BoardT, NewBoard, IncSteps, MaxSteps, Final_Y, Final_X, MOVEST),
- MOVES = [BoardT | MOVEST],
- !.
- %------------------
- %------------------
- rozwiaz(FinalY, FinalX, FinalBoard, MOVES):-
- height(FinalY, Y),
- board(B),
- steps(MaxSteps),
- make_move(B, FinalBoard, 0, MaxSteps, Y, FinalX, MOVES), !.
- %------------------
- max_height_width(MaxHeight, MaxWidth):-
- board(B),
- last(B, Row),
- length(B, Height),
- length(Row, Width),
- MaxHeight is Height - 2,
- MaxWidth is Width - 2.
- walidate_cords(StartY, StartX, EndY, EndX):-
- height(EndY),
- width(EndX),
- height(StartY),
- width(StartX).
- translate_cords(StartY, EndY, SY, EY):-
- height(StartY, SY),
- height(EndY, EY).
- %------------------
- przem(StartY, StartX, EndY, EndX):-
- walidate_cords(StartY, StartX, EndY, EndX),
- translate_cords(StartY, EndY, SY, EY),
- max_steps(MaxSteps),
- board(B),
- przem_unwrap(B, SY, StartX, EY, EndX, 0, MaxSteps).
- przem_unwrap(_, StartY, StartX, EndY, EndX, Steps, MaxSteps):-
- not(Steps > MaxSteps),
- StartX = EndX,
- StartY = EndY,!.
- przem_unwrap(Board, StartY, StartX, EndY, EndX, Steps, MaxSteps):-
- not(Steps > MaxSteps),
- position(Board, StartY, StartX, Char),
- direction(Dir),
- move_block(Board, Char, Dir, NewBoard),
- position(NewBoard, TempY, TempX, Char),
- IncSteps = Steps + 1,
- przem_unwrap(NewBoard, TempY, TempX, EndY, EndX, IncSteps, MaxSteps).
- %------------------