Skip to content

Instantly share code, notes, and snippets.

@Average-user
Created December 28, 2017 22:02
Show Gist options
  • Save Average-user/6264d8a7a2f8483505ee3e0e9dcd5587 to your computer and use it in GitHub Desktop.
Save Average-user/6264d8a7a2f8483505ee3e0e9dcd5587 to your computer and use it in GitHub Desktop.
Gnereator of Fischer Random Chess positions
% Using SWI-Prolog 7.2.3
% see https://en.wikipedia.org/wiki/Chess960 to understant what is this about.
:- use_module(library(random)).
even(N) :- 0 is N mod 2.
odd(N) :- \+even(N).
index_of(Xs, X, N) :- nth0(N, Xs, X).
start_position(P) :-
Pieces = ['N','N','K','B','b','T','t','Q'],
permutation(Pieces, P),
index_of(P, 'T', IT),
index_of(P, 't', It),
index_of(P, 'K', IK),
IT < IK, IK < It, % The King must be between the two towers
index_of(P, 'B', IB),
index_of(P, 'b', Ib),
even(Ib), odd(IB). % Bishops must be in different colored squares
turn(t, 'T') :- !.
turn(b, 'B') :- !.
turn(X, X).
% All valid Fischer Random Chess positions
all_pos(Ps) :-
setof(P, start_position(P), Ps1),
maplist(maplist(turn), Ps1, Ps).
% Randomly picks one of the 960 different positions.
random_960_position(P) :-
all_pos(Ps),
random_member(P, Ps).
/*
| Example:
| ?- all_pos(Ps), length(Ps, L).
| Ps = ... L = 960
|
| ?- random_960_position(X).
| X = ['N', 'B', 'N', 'T', 'B', 'K', 'Q', 'T'].
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment