Advertisement
Guest User

Untitled

a guest
Nov 27th, 2021
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 6.94 KB | None | 0 0
  1. :- use_module(library(clpfd)).  % Finite domain constraints
  2. :- use_module(library(dif)).    % Sound inequality
  3.  
  4. width(5).
  5. height(6).
  6. next_team(red, green).
  7. next_team(green, red).
  8. winpos(red, [(1, 1), (2, 1), (3, 1), (4, 1)]).
  9. winpos(green, [(1, 5), (2, 5), (3, 5), (4, 5)]).
  10.  
  11. base_game(game(
  12.               red,
  13.               [
  14.         red - 12,
  15.                 green - 12
  16.               ],
  17.               [
  18.         octi(green, (1, 1), []), octi(green, (2, 1), []), octi(green, (3, 1), []), octi(green, (4, 1), []),
  19.         octi(red, (1, 5), []), octi(red, (1, 4), []), octi(red, (3, 5), []), octi(red, (4, 5), [])
  20.               ]
  21.               )).
  22.  
  23. label_game(game(_, _, Board)) :-
  24.     term_variables(Board, Vars),
  25.     labeling([ff], Vars).
  26.  
  27. add_vectors((X0, Y0), (X1, Y1), (X, Y)) :-
  28.     X #= X0 + X1,
  29.     Y #= Y0 + Y1.
  30.  
  31. map_get([Key - Value | _], Key - Value).
  32. map_get([Key0 - _| Rest], Key - Value) :-
  33.     dif(Key0, Key),
  34.     map_get(Rest, Key - Value).
  35.  
  36. map_set([], [], _ - _).
  37. map_set([Key - _ | Rest], [Key - Value | Cont], Key - Value) :-
  38.     map_set(Rest, Cont, Key - Value).
  39. map_set([Key0 - Value0 | Rest], [Key0 - Value0 | Cont], Key - Value) :-
  40.     dif(Key0, Key),
  41.     map_set(Rest, Cont, Key - Value).
  42.  
  43.  
  44. valid_pos((X, Y)) :-
  45.     width(W), height(H),
  46.     X in 0..W, Y in 0..H.
  47.  
  48. valid_vector((A, B)) :-
  49.     A in -1..1, B in -1..1,
  50.     abs(A) + abs(B) #\= 0.
  51.  
  52. % place arrow
  53. turn_1(
  54.         game(Team0, Arrows0, Board0),
  55.         game(Team1, Arrows1, Board1),
  56.         move(place, (X, Y), (A, B))
  57.      ) :-
  58.     next_team(Team0, Team1),
  59.     valid_pos((X, Y)),
  60.     valid_vector((A, B)),
  61.  
  62.     % update arrow count
  63.     map_get(Arrows0, Team0 - Team0Arrows),
  64.     Team0Arrows #> 0,
  65.     NextTeam0Arrows #= Team0Arrows - 1,
  66.     map_set(Arrows0, Arrows1, Team0 - NextTeam0Arrows),
  67.  
  68.     % check octi doesn't already have arrow
  69.     select(octi(Team0, (X, Y), Vectors), Board0, State0),
  70.     maplist(dif((A, B)), Vectors),
  71.  
  72.     % update board
  73.     append(Vectors, [(A, B)], NextVectors),
  74.     append(State0, [octi(Team0, (X, Y), NextVectors)], Board1).
  75.  
  76. % move octigon in case no blocking
  77. turn_1(
  78.         game(Team0, Arrows0, Board0),
  79.         game(Team1, Arrows0, Board1),
  80.         move(move, (X0, Y0), (X1, Y1))
  81.      ) :-
  82.     next_team(Team0, Team1),
  83.     valid_pos((X0, Y0)), valid_pos((X1, Y1)),
  84.  
  85.     % get octi
  86.     select(octi(Team0, (X0, Y0), Vectors), Board0, State0),
  87.     member(NeededVector, Vectors),
  88.  
  89.     add_vectors(NeededVector, (X0, Y0), (X1, Y1)),
  90.  
  91.     % check that nothing is blocking
  92.     \+ select(octi(_, (X1, Y1), _), Board0, _),
  93.  
  94.     append(State0, [octi(Team0, (X1, Y1), Vectors)], Board1).
  95.  
  96. % move octigon in case blocking but of own team (jump no eat)
  97. turn_1(
  98.         game(Team0, Arrows0, Board0),
  99.         game(Team1, Arrows0, Board1),
  100.         move(jump, (X0, Y0), (X1, Y1))
  101.      ) :-
  102.     next_team(Team0, Team1),
  103.     valid_pos((X0, Y0)), valid_pos((X1, Y1)),
  104.  
  105.     % get octi
  106.     select(octi(Team0, (X0, Y0), Vectors), Board0, State0),
  107.     member(NeededVector, Vectors),
  108.  
  109.     % get blocking pos
  110.     add_vectors(NeededVector, (X0, Y0), BlockingPos),
  111.     add_vectors(BlockingPos, NeededVector, (X1, Y1)),
  112.  
  113.     % check that own team blocking and no octigon after jump
  114.     select(octi(Team0, BlockingPos, _), Board0, _),
  115.     \+ select(octi(_, (X1, Y1), _), Board0, _),
  116.  
  117.     append(State0, [octi(Team0, (X1, Y1), Vectors)], Board1).
  118.  
  119. % move octigon in case blocking but of other team (jump and eat)
  120. turn_1(
  121.         game(Team0, Arrows0, Board0),
  122.         game(Team1, Arrows1, Board1),
  123.         move(jump, (X0, Y0), (X1, Y1))
  124.      ) :-
  125.     next_team(Team0, Team1),
  126.     valid_pos((X0, Y0)), valid_pos((X1, Y1)),
  127.  
  128.     % get octi
  129.     select(octi(Team0, (X0, Y0), Vectors), Board0, State0),
  130.     member(NeededVector, Vectors),
  131.  
  132.     % get blocking pos
  133.     add_vectors(NeededVector, (X0, Y0), BlockingPos),
  134.     add_vectors(BlockingPos, NeededVector, (X1, Y1)),
  135.  
  136.     % get arrow count of octi at blocking pos
  137.     select(octi(Team1, BlockingPos, OtherArrows), Board0, _),
  138.  
  139.     % update arrow count
  140.     length(OtherArrows, AddedArrows),
  141.     map_get(Arrows0, Team0 - Team0Arrows),
  142.     NextTeam0Arrows #= Team0Arrows + AddedArrows,
  143.     map_set(Arrows0, Arrows1, Team0 - NextTeam0Arrows),
  144.  
  145.     % check that no octigon after jump
  146.     \+ select(octi(_, (X1, Y1), _), Board0, _),
  147.  
  148.     append(State0, [octi(Team0, (X1, Y1), Vectors)], State1),
  149.  
  150.     % remove eaten octi
  151.     select(octi(_, BlockingPos, _), State1, Board1).
  152.  
  153. % chain move 2
  154. turn_1(
  155.         game(Team0, Arrows0, Board0),
  156.         game(Team1, Arrows1, Board1),
  157.         move(chain, [(X0, Y0), (X1, Y1), (X2, Y2)])
  158.      ) :-
  159.     turn_1(
  160.             game(Team0, Arrows0, Board0),
  161.             game(Team1, Arrows0_1, Board0_1),
  162.             move(jump, (X0, Y0), (X1, Y1))
  163.         ),
  164.     turn_1(
  165.             game(Team0, Arrows0_1, Board0_1),
  166.             game(Team1, Arrows1, Board1),
  167.             move(jump, (X1, Y1), (X2, Y2))
  168.         ).
  169.  
  170. % chain move N
  171. turn_1(
  172.         game(Team0, Arrows0, Board0),
  173.         game(Team1, Arrows1, Board1),
  174.         move(chain, [(X0, Y0), (X1, Y1), (X2, Y2) | Cont])
  175.      ) :-
  176.     turn_1(
  177.             game(Team0, Arrows0, Board0),
  178.             game(Team1, Arrows0_1, Board0_1),
  179.             move(jump, (X0, Y0), (X1, Y1))
  180.         ),
  181.     turn_1(
  182.             game(Team0, Arrows0_1, Board0_1),
  183.             game(Team1, Arrows1, Board1),
  184.             move(chain, [(X1, Y1), (X2, Y2) | Cont])
  185.          ).
  186.  
  187. % team0 wins if team1 doesn't have any moves
  188. win(game(_, _, Board), Team0) :-
  189.     next_team(Team0, Team1),
  190.     \+ select(octi(Team1, _, _), Board, _).
  191.  
  192. % team wins if one of the octis are in winpos
  193. win(game(_, _, Board), Team) :-
  194.     winpos(Team, WinPos),
  195.     member(Pos, WinPos),
  196.     select(octi(Team, Pos, _), Board, _).
  197.  
  198. % team0 wins if team1 at their turn doesn't have any move
  199. win(game(Team1, Arrows, Board), Team0) :-
  200.     next_team(Team0, Team1),
  201.     findall(game(Team1, Arrows, Board), turn_1(game(Team1, Arrows, Board), _, _), []).
  202.  
  203. any(Goal, [Arg | Rest]) :-
  204.     call(Goal, Arg);
  205.     any(Goal, Rest).
  206.  
  207. % Team wins the game if the game is already won
  208. wins(Game, Team) :- win(Game, Team).
  209.  
  210. % Team wins the game if it is currently their turn,
  211. % and they have at least one move that results in a game where they win
  212. wins(game(Team, Arrows, Board), Team) :-
  213.     findall(Game1, turn_1(game(Team, Arrows, Board), Game1, _), Games),
  214.     any(rwins(Team), Games).
  215.  
  216. % Team0 wins the game if it isn't their turn,
  217. % and all possible games that come after are won by Team0
  218. wins(game(Team1, Arrows, Board), Team0) :-
  219.     next_team(Team0, Team1),
  220.     findall(Game1, turn_1(game(Team1, Arrows, Board), Game1, _), Games),
  221.     maplist(rwins(Team0), Games).
  222.  
  223. rwins(Team, Game) :- wins(Game, Team).
  224.  
  225. tabwritenl(X) :-
  226.     write('  '), write(X), nl.
  227.  
  228. print_game(game(Team, Arrows, Board)) :-
  229.     nl,
  230.     write('turn: '), write(Team), nl,
  231.     write('arrows: '), write(Arrows), nl,
  232.     write('octis: '), nl,
  233.     maplist(tabwritenl, Board), nl.
  234.  
  235.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement