chess/chess.pl

204 lines
5.2 KiB
Prolog

color(white).
color(black).
files([a, b, c, d, e, f, g, h]).
file(X) :-
files(Files),
member(X, Files).
file_index(File, Index) :-
files(Files),
nth0(Index, Files, File).
rank(X) :-
between(1, 8, X).
piece(X) :-
member(X, [ queen, king, rook, bishop, knight, pawn ]).
valid_coor(coor(File, Rank)) :-
rank(Rank),
file(File).
piece(Piece, Color) :-
color(Color),
piece(Piece).
piece(Piece, Color, Coor) :-
piece(Piece, Color),
valid_coor(Coor).
valid_piece(piece(Piece, Color, Coor)) :-
piece(Piece, Color, Coor).
% Movement
% Consider renaming to offset
direction(n, n, vector(0, 1)).
direction(n, e, vector(1, 1)).
direction(n, w, vector(-1, 1)).
direction(s, s, vector(0, -1)).
direction(s, e, vector(1, -1)).
direction(s, w, vector(-1, -1)).
direction(w, w, vector(-1, 0)).
direction(e, e, vector(1, 0)).
coor_vector(Coor, vector(Index, Rank)) :-
valid_coor(Coor),
Coor = coor(File, Rank),
file_index(File, Index).
vector_sum(vector(A, B), vector(X, Y), vector(R, Z)) :-
plus(A, X, R),
plus(B, Y, Z).
direction(knight, direction(Cardinal, Ordinal, Vector)) :-
direction(diagonal, direction(Cardinal, Ordinal, V1)),
( D = Cardinal; D = Ordinal ),
direction(D, D, V2),
vector_sum(V1, V2, Vector).
direction(diagonal, direction(A, B, V)) :-
direction(A, B, V),
A \= B.
direction(straight, direction(A, A, V)) :-
direction(A, A, V).
valid_direction(B) :-
direction(A, B).
jump(Coor, To, Direction) :-
neighbors(Coor, To, Direction);
neighbors(Coor, B, Direction),
jump(B, To, Direction).
neighbors(From, To, Direction) :-
valid_direction(Direction),
Direction = direction(_, _, V1),
coor_vector(From, V2),
vector_sum(V1, V2, V3),
coor_vector(To, V3).
move(piece(knight, C, From), piece(knight, C, To), Direction) :-
direction(knight, Direction),
writeln(Direction),
neighbors(From, To, Direction).
move(piece(pawn, black, From), piece(pawn, black, To), Direction) :-
Direction = direction(s, s, _),
neighbors(From, To, Direction).
move(piece(pawn, white, From), piece(pawn, white, To), Direction) :-
Direction = direction(n, n, _),
neighbors(From, To, Direction).
move(piece(pawn, white, coor(F, 2)), piece(pawn, white, coor(F, 4)), _).
move(piece(pawn, black, coor(F, 7)), piece(pawn, black, coor(F, 5)), _).
move(piece(queen, C, From), piece(queen,C, To), Direction) :-
direction(straight, Direction);
direction(diagonal, Direction),
jump(From, To, Direction).
move(piece(rook, C, From), piece(rook, C, To), Direction) :-
direction(straight, Direction),
jump(From, To, Direction).
move(piece(bishop, C, From), piece(bishop, C, To), Direction) :-
direction(diagonal, Direction),
jump(From, To, Direction).
move(piece(king, C, From), piece(king, C, To), Direction) :-
direction(straight, Direction);
direction(diagonal, Direction),
neighbors(From, To, Direction).
intersections(From, Inter, Inter, Direction) :-
move(From, Inter, Direction).
intersections(From, Inter, To, Direction) :-
move(From, Inter, Direction),
move(Inter, To, Direction).
% captures
% Should check if move does not have any pieces in the way.
move(BoardIn, move(Piece, To, Direction), Board) :-
member(Piece, BoardIn),
move(Piece, To, Direction),
writeln('called'),
\+ ( % check if not intersecting with anything in the line.
intersections(Piece, piece(_, _, Coor), To, Direction),
member(piece(_, _, Coor), BoardIn)
),
subtract([To|BoardIn], [Piece], Board).
board_piece(pawn, Pawn) :-
file(F), (
Pawn = piece(pawn, white, coor(F, 2));
Pawn = piece(pawn, black, coor(F, 7))
).
board_piece(rook, Rook) :-
(F = a; F = h), (
Rook = piece(rook, white, coor(F, 1));
Rook = piece(rook, black, coor(F, 8))
).
board_piece(knight, Knight) :-
(F = b; F = g), (
Knight = piece(knight, white, coor(F, 1));
Knight = piece(knight, black, coor(F, 8))
).
board_piece(bishop, Bishop) :-
(F = c; F = f), (
Bishop = piece(bishop, white, coor(F, 1));
Bishop = piece(bishop, black, coor(F, 8))
).
board_piece(queen, Queen) :-
Queen = piece(queen, white, coor(d, 1));
Queen = piece(queen, black, coor(d, 8)).
board_piece(king, King) :-
King = piece(king, white, coor(e, 1));
King = piece(king, black, coor(e, 8)).
board(Pieces) :-
findall(Piece, board_piece(_, Piece), Pieces).
% Pretty Printing boards
piece_unicode(white, king, "♔").
piece_unicode(white, queen, "♕").
piece_unicode(white, rook, "♖").
piece_unicode(white, bishop, "♗").
piece_unicode(white, knight, "♘").
piece_unicode(white, pawn, "♙").
piece_unicode(black, king, "♚").
piece_unicode(black, queen, "♛").
piece_unicode(black, rook, "♜").
piece_unicode(black, bishop, "♝").
piece_unicode(black, knight, "♞").
piece_unicode(black, pawn, "♟︎").
board_pp(Board, Print) :-
findall(Row, (rank(Rank), board_rank_pp(Board, Rank, Row)), Rows),
atomics_to_string(Rows, '\n', Print).
board_rank_pp(Board, Rank, Print) :-
findall(Square, (
file(File),
board_square_pp(Board, coor(File, Rank), Square)
), Squares),
atomics_to_string(Squares, " ", Print).
board_square_pp(Board, Coor, Print) :-
member(piece(Type, Color, Coor), Board)
-> piece_unicode(Color, Type, Print)
; Print = " ".