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