:- 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 = [].