% Tetris in Prolog (C) Paul Tarau 1989-2001 % ALGORITHM: % minimize the energy of the surface of the block profile % = the sum of the heights of the blocs - empty spaces included % (after a hypothetical fall) % Tetris 10.2 dims(19,10). max(L,C):-dims(L,C). play:-go(game),println(end),scr_end. go:-go(demo). go(Mode):- init(State), play(Mode,State), !. init(surface(N,[])):- init_best, scr_init(N). % logic rtest:-for(_,1,50),random(20,R),println(R),fail. random(Max,R):- random(N), R is N mod Max. cputime(X):-statistics(runtime,[X,_]). % directions and axes: Dir -> p(DeltaL,DeltaC) dir_move(0,p( 0, 1)). % right *---> p(_,C) dir_move(1,p( 1, 0)). % down | dir_move(2,p( 0,-1)). % left | dir_move(3,p(-1, 0)). % right \/ % ---------------------------- %p(L,_) % movements next(Dir,p(L1,C1),p(L2,C2)):- max(MaxL,MaxC), dir_move(Dir,p(DL,DC)), L2 is L1+DL,C2 is C1+DC, L2>=0,L2=0,C2Full=1 ; Full=0 ) ), BLCs), !, eliminate(BLCs,LCs,N), !, N>0,N2 is N1+N, elements(LCs,R2). element(LCs,p(L,C)):-member(L-Cs,LCs),member(C,Cs). elements(LCs,Ps):-findall(P,element(LCs,P),Ps). eliminate([],[],0):-!. eliminate([L|Ls],Rs2,N2):- eliminate(Ls,Rs1,N1), remove(L,Rs1,Rs2,N1,N2). remove(surface(1,_),Rs,Rs,N1,N2):-N2 is N1+1,!. remove(surface(0,L-Cs),Rs1,[L1-Cs|Rs1],N,N):-L1 is L+N. touch(p(L,_),_):-max(M,_),L>=M,!. % no free space down touch(P,Ps):-member(P,Ps),!. % try try_animate_block(B,surface(N,R1),surface(N,R2)):- block2parts(B,Ps), try_let_fall_block(Ps,R1,R2). try_let_fall_block(Ps1,R1,R2):- try_change_block(Ps1,Ps2,R1), !, try_let_fall_block(Ps2,R1,R2). try_let_fall_block(Ps,R1,R3):- det_append(Ps,R1,R2), !, try_reduce(R2,R3). try_reduce(R1,R2):- compress_surface(surface(0,R1),surface(_,R2)), !. try_reduce(R,R). let_fall([],[],_):-!. let_fall([p(L1,C)|Ps1],[p(L2,C)|Ps2],MaxL):- L2 is L1+1, L2fail ; true ), !. % evaluer minimize_surface_energy(B0,_,surface(N,R1)):- B0=block(Type,_,_), re_init_best(B0), generate_block(Type,B), try_animate_block(B,surface(N,R1),surface(_,R2)), energy(R2,Val), the_best(OldB,OldVal), Val