Acciones

Bag puzzle

De Lógica computacional y teoría de modelos (2019-20)

%% Bag puzzle.

%% Juego que consiste en hacer un camino que rodee todos los números del tablero
%% siguiendo unas reglas:

%% R1: El camino tiene que ser cerrado.
%% R2: Todos los números tienen que estar rodeados por el camino.
%% R3: El número de casillas visibles en toda dirección de una casilla enumerada
%% tiene que ser igual al número de la casilla.

x(0..n). y(0..m). direccion(v;h).
pos(X,Y) :- x(X), y(Y).
%% Generación.

{linea(S,X,Y)} :- direccion(S), x(X), y(Y). 
:- linea(h,n,Y), y(Y).
:- linea(v,X,m), x(X).

%% Restricciones:

%% R1: El camino tiene que ser cerrado.
%% Cada punto del camino esta conectado exactamente a otros dos

:- 3 {linea(h,X-1,Y); linea(h,X,Y); linea(v,X,Y); linea(v,X,Y-1)}, en(X,Y).
:- {linea(h,X-1,Y); linea(h,X,Y); linea(v,X,Y); linea(v,X,Y-1)} 1, en(X,Y).

en(X,Y) :- linea(S,X,Y).
en(X+1,Y) :- linea(h,X,Y).
en(X,Y+1) :- linea(v,X,Y).

%% Todo punto del camino es alcanzable por cualquier otro.

:- en(X,Y), en(Z,W), not alcanzable(X,Y,Z,W).

adj(X,Y,X,Y+1) :- linea(v,X,Y).
adj(X,Y,X+1,Y) :- linea(h,X,Y).
adj(X,Y,Z,W) :- adj(Z,W,X,Y).

alcanzable(X,Y,X,Y) :- en(X,Y).
alcanzable(X,Y,Z,W) :- alcanzable(I,J,Z,W), adj(X,Y,I,J).



%% R3: El número de casillas visibles en toda dirección de una casilla enumerada
%% tiene que ser igual al número de la casilla.

:- N {visible(X,Y,Z,T): pos(Z,T)}, numero(N,X,Y).
:- {visible(X,Y,Z,T): pos(Z,T)} N-2, numero(N,X,Y). 

% Visibilidad en casillas adyacentes.

visible0(X,Y,X,Y+1) :- pos(X,Y), not linea(h,X,Y+1), Y<m-1.
visible0(X,Y,X,Y-1) :- pos(X,Y), not linea(h,X,Y), Y>0.
visible0(X,Y,X+1,Y) :- pos(X,Y), not linea(v,X+1,Y), X<n-1.
visible0(X,Y,X-1,Y) :- pos(X,Y), not linea(v,X,Y), X>0.

% Visibilidad general

visible(X,Y,Z,T) :- visible0(X,Y,Z,T).
visible(X,Y,Z,Y) :- visible(X,Y,Z+1,Y), visible0(Z,Y,Z+1,Y), Z<X-1, X>1, X<n, Y<m.
visible(X,Y,Z,Y) :- visible(X+1,Y,Z,Y), visible0 (X,Y,X+1,Y), Z>X+1, X<n-2, Y<m.
visible(X,Y,X,T) :- visible(X,Y+1,X,T), visible0(X,Y,X,Y+1), T>Y+1, Y<m-2, X<n.
visible(X,Y,X,T) :- visible(X,Y,X,T+1), visible0(X,T,X,T+1), T<Y-1, Y>1, Y<m, X<n.


%% R2: Todos los números tienen que estar rodeados por el camino.

:- numero(M,X,Y), fuera(X,Y).

fuera(X,Y) :- Y=m-1, X<n, numero(M,X,Y), not linea(h,X,Y+1).
fuera(X,Y) :- Y=0, X<n, numero(M,X,Y), not linea(h,X,Y).
fuera(X,Y) :- X=n-1, Y<m, numero(M,X,Y), not linea(v,X+1,Y).
fuera(X,Y) :- X=0, Y<m, numero(M,X,Y), not linea(v,X,Y).

fuera(X,Y) :- X<n-1, X>0, Y<m-1, Y>0, numero(M,X,Y),visible(X,Y,0,Y), not linea(v,0,Y).
fuera(X,Y) :- X<n-1, X>0, Y<m-1, Y>0, Z=n-1, numero(M,X,Y),visible(X,Y,Z,Y), not linea(v,n,Y).
fuera(X,Y) :- X<n-1, X>0, Y<m-1, Y>0, numero(M,X,Y),visible(X,Y,X,0), not linea(h,X,0).
fuera(X,Y) :- X<n-1, X>0, Y<m-1, Y>0, T=m-1, numero(M,X,Y),visible(X,Y,X,T), not linea(h,X,m).

%Presentación.

#show linea/3.