-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathadjoxo.erl
69 lines (56 loc) · 1.48 KB
/
adjoxo.erl
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
% Adjudicator for naughts and crosses
bestOf(win, V) -> win;
bestOf(loss, V) -> V;
bestOf(draw, V) ->
case V of
win -> win;
draw -> draw;
loss -> draw
end.
inverse(loss) -> win;
inverse(draw) -> draw;
inverse(win) -> loss.
insert(X, []) -> [X];
insert(X, [Y|Ys]) ->
if X <= Y -> [X|[Y|Ys]];
true -> [Y|insert(X,Ys)]
end.
diff([], Ys) -> [];
diff([X|Xs], YYs) ->
case YYs of
[] -> [X|Xs];
[Y|Ys] ->
if X < Y -> [X|diff(Xs, YYs)];
X > Y -> diff([X|Xs], Ys);
true -> diff(Xs, Ys)
end
end.
subset(Xs, Ys) -> null(diff(Xs, Ys)).
hasLine(P) ->
subset([1,2,3], P) or subset([4,5,6], P) or
subset([7,8,9], P) or subset([1,4,7], P) or
subset([2,5,8], P) or subset([3,6,9], P) or
subset([1,5,9], P) or subset([3,5,7], P).
gridFull(AP, PP) -> (length(AP) + length(PP)) == 9.
analysis(AP, PP) ->
if hasLine(PP) -> loss;
gridFull(AP, PP) -> draw;
true -> foldr1(bestOf, map(moveval(AP, PP), diff(diff([1..9], AP), PP)))
end.
moveval(AP, PP) ->
fun (M) -> inverse(analysis(PP, insert(M, AP))) end.
adjudicate(Os, Xs) ->
LenOs = length(Os),
LenXs = length(Xs),
if LenOs < LenXs -> report(analysis(Os, Xs), o);
LenOs > LenXs -> report(analysis(Xs, Os), x);
hasLine(Xs) -> report(win, x);
hasLine(Os) -> report(win, o);
true -> report(analysis(Xs, Os), x)
end.
report(loss, S) -> opp(S);
report(win, S) -> S;
report(draw, P) -> draw.
opp(o) -> x;
opp(x) -> o.
start() -> adjudicate([], []).