-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.pl
More file actions
executable file
·115 lines (102 loc) · 3.24 KB
/
utils.pl
File metadata and controls
executable file
·115 lines (102 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
:- module(utils, [filter/3, ground_move/2, dfs_empty/3, occupied/1,
draw/0, blue_lose/0, red_lose/0, connected_components/1,
red_on_board/1, blue_on_board/1,turn/1,change_turn/0,change_turn_red/0,
change_turn_blue/0,adjacent_to_hive/1,unique/2]).
:- use_module([adjacency, position, pieces]).
occupied(Position) :- position(_,Position), !.
filter([],_,[]).
filter([X|S],P,T) :-
Z =.. [P,X], call(Z),
!,
filter(S,P,Y),
append([X],Y,T).
filter([_|S],P,T) :- filter(S,P,T).
adjacent_to_hive(X) :-
adjacent(X,Y),
occupied(Y).
ground_move(_,End) :-
occupied(End),
!,
fail.
ground_move(Start,End) :-
adjacency(Start,D,End),
Prev is 6 - (6 - D + 1) mod 6,
adjacency(Start,Prev,P),
occupied(P),
Next is D mod 6 + 1,
adjacency(Start,Next,N),
occupied(N),
!,
fail.
ground_move(_,_).
dfs_empty(Seen,Cur,S) :-
findall(X,(adjacent(Cur,X),ground_move(Cur,X)),Y),
dfs_empty_visit(Seen,Y,S).
dfs_empty_visit(Seen,[],Seen).
dfs_empty_visit(Seen,[X|Y],S) :-
member(X,Seen) ->
dfs_empty_visit(Seen,Y,S);
(append([X],Seen,NS),
dfs_empty(NS,X,T),
dfs_empty_visit(T,Y,S)).
dfs_occupied(Seen,Cur,S) :-
append([Cur],Seen,NS),
findall(X,(adjacent(Cur,X),occupied(X)),Y),
dfs_occupied_visit(NS,Y,S).
dfs_occupied_visit(Seen,[],Seen).
dfs_occupied_visit(Seen,[X|Y],S) :-
member(X,Seen) ->
dfs_occupied_visit(Seen,Y,S);
(dfs_occupied(Seen,X,T),
dfs_occupied_visit(T,Y,S)).
connected_components(S) :- connected_components_visit([],0,S).
connected_components_visit(_,300,[]).
connected_components_visit(Seen,Pos,S) :-
Pos < 300,
(member(Pos,Seen) ; not(occupied(Pos))),
!,
P is Pos + 1,
connected_components_visit(Seen,P,S).
connected_components_visit(Seen,Pos,S) :-
Pos < 300,
dfs_occupied([],Pos,X),
append(X,Seen,NS),
P is Pos + 1,
connected_components_visit(NS,P,T),
append([X],T,S).
blue_lose :-
position(blue_bee,X),
findall(Y,(adjacency(X,_,Y),occupied(Y),Y =\= -1),S),
length(S,6).
red_lose :-
position(red_bee,X),
findall(Y,(adjacency(X,_,Y),occupied(Y),Y =\= -1),S),
length(S,6).
draw :- blue_lose, red_lose.
on_board(X) :- position(X,Y), Y > -1.
red_on_board(N) :-
findall(X,(piece(X),color(X,red)),Z),
filter(Z,on_board,S),
length(S,N).
blue_on_board(N) :-
findall(X,(piece(X),color(X,blue)),Z),
filter(Z,on_board,S),
length(S,N).
:- dynamic turn/1.
turn(red).
change_turn :- turn(X), X == blue, change_turn_red, !.
change_turn :- turn(X), X == red, change_turn_blue.
change_turn_red :- turn(X), P =.. [turn,X], retract(P),
Q =.. [turn,red], assert(Q).
change_turn_blue :- turn(X), P =.. [turn,X], retract(P),
Q =.. [turn,blue], assert(Q).
unique_visit([Cur|R],V,[Cur|S]) :-
not(member(Cur,V)), !,
append([Cur],V,NV),
unique_visit(R,NV,S).
unique_visit([Cur|R],V,S) :-
member(Cur,V), !,
unique_visit(R,V,S).
unique_visit([],_,[]).
unique(L,S) :-
unique_visit(L,[],S).