Awarded Programs for "Entry Category"
(Problem:Lights Out)
:- module lo.
% [BD] Column
% | 0 1 2 3 4
% ---+----------------
% 0 | 0 1 2 3 4
% R 1 | 5 6 7 8 9
% O 2 | 10 11 12 13 14
% W 3 | 15 16 17 18 19
% 4 | 20 21 22 23 24
%---------------------------------------------------------------------------------
game(Es) :- % Es = [click(Row,Col,Rs),redraw(Rs),...]
new_vector(BD,25), % all ON (ON = 0, OFF = 1)
game(Es,BD).
% Rs = [set(Row,Col),reset(Row,Col),...]
game([click(Row,Col,Rs)|Es],BD) :- 0 =< Row, Row =< 4, 0 =< Col, Col =< 4 |
Pos := Row * 5 + Col, swapPUDLR(Pos,Row,Col,Rs,BD,BD2),
game(Es,BD2).
game([redraw(Rs)|Es],BD) :-
redraw(0,0,0,BD,Rs),
game(Es,BD).
game([],_).
otherwise.
game([click(_,_,Rs)|Es],BD) :- Rs = [], game(Es,BD). % out of range
%---------------------------------------------------------------------------------
swapPUDLR(Pos,Row,Col,Rs,BD,BD6) :-
swap(Pos,Row,Col,Rs,Rs2,BD,BD2), % P
swap(~(Pos-5),~(Row-1),Col,Rs2,Rs3,BD2,BD3), % U U
swap(~(Pos+5),~(Row+1),Col,Rs3,Rs4,BD3,BD4), % D L P R
swap(~(Pos-1),Row,~(Col-1),Rs4,Rs5,BD4,BD5), % L D
swap(~(Pos+1),Row,~(Col+1),Rs5,[],BD5,BD6). % R
swap(Pos,Row,Col,Rs,Rs2,BD,BD2) :-
0 =< Row, Row =< 4, 0 =< Col, Col =< 4, vector_element(BD,Pos,0) | % ON
Rs = [reset(Row,Col)|Rs2],
set_vector_element(BD,Pos,_,1,BD2). % ON -> OFF
swap(Pos,Row,Col,Rs,Rs2,BD,BD2) :-
0 =< Row, Row =< 4, 0 =< Col, Col =< 4, vector_element(BD,Pos,1) | % OFF
Rs = [set(Row,Col)|Rs2],
set_vector_element(BD,Pos,_,0,BD2). % OFF -> ON
otherwise.
swap(_,_,_,Rs,Rs2,BD,BD2) :- % out of range
Rs = Rs2, BD = BD2.
%---------------------------------------------------------------------------------
redraw(Pos,Row,Col,BD,Rs) :- Pos < 25, Col < 4, vector_element(BD,Pos,0) | % ON
redraw(~(Pos+1),Row,~(Col+1),BD,Rs).
redraw(Pos,Row,Col,BD,Rs) :- Pos < 25, Col < 4, vector_element(BD,Pos,1) | % OFF
Rs = [reset(Row,Col)|Rs2],
redraw(~(Pos+1),Row,~(Col+1),BD,Rs2).
redraw(Pos,Row,Col,BD,Rs) :- Pos < 25, Col =:= 4, vector_element(BD,Pos,0) | % ON
redraw(~(Pos+1),~(Row+1),0,BD,Rs).
redraw(Pos,Row,Col,BD,Rs) :- Pos < 25, Col =:= 4, vector_element(BD,Pos,1) | % OFF
Rs = [reset(Row,Col)|Rs2],
redraw(~(Pos+1),~(Row+1),0,BD,Rs2).
redraw(Pos,_,_,_,Rs) :- Pos >= 25 | Rs = [].

for
programs