% A minesweeper end game
% In the last few steps of a minesweeper game you have a single mine to flag
% It is somewhere in the 4 squares in the bottom right hand corner of the board
% The corner looks like this ( f is a flag, W, X, Y, Z are unknown squares)
% f 2 1
% 2 W X
% 1 Y Z
% where is the last mine?
% Encode W, X, Y , Z is 1 for a mine and 0 for no mine on that square
% unique: u(...) is true if precisely one argument is 1 and the rest are 0
u(1,0,0,0). u(0,1,0,0). u(0,0,1,0). u(0,0,0,1).
% orginal problem
where(Field):-Field=[W, X, Y, Z], u(W,X,Y,Z),
1 is W+X,
2 is 1+W+X,
2 is 1+W+Y,
1 is W+Y.
% suppose whe don't know how many mines are in the corner
where2(Field) :- Field=[W, X, Y, Z],
(X=1;X=0), (W=1; W=0), (Y=1; Y=0), (Z=1; Z=0),
1 is W+X,
2 is 1+W+X,
2 is 1+W+Y,
1 is W+Y.
% optimized with unknown number of mines
where3(Field):-Field=[W, X, Y, Z],
(X=1;X=0), (W=1; W=0),
1 is W+X,
2 is 1+W+X,
(Y=1; Y=0),
2 is 1+W+Y,
1 is W+Y ,
(Z=1; Z=0).
go:-where3(Field), count(Field), fail.
results:-counters(W,X,Y,Z), total(T),
W1 is 100.0*W/T, write(W1), write('\t'),
X1 is 100.0*X/T, write(X1), nl,
Y1 is 100.0*Y/T, write(Y1), write('\t'),
Z1 is 100.0*Z/T, write(Z1), nl.
reset:-retract(counters(_,_,_,_)), assert(counters(0,0,0,0)), retract(total(_)), assert(total(0)).
:-dynamic(counters/4).
counters(0,0,0,0).
:-dynamic(total/1).
total(0).
count(Field):-retract(total(T0)), T1 is T0+1, assert(total(T1)),
retract(counters(W0, X0, Y0, Z0)), Field=[W,X,Y,Z],
W1 is W0+W, X1 is X0+X, Y1 is Y0+Y, Z1 is Z0+Z,
assert(counters(W1,X1,Y1,Z1)).