From: Gordon Thiesfeld Date: 2006-12-19T22:10:05+09:00 Subject: Re: Chess960 (#106) I wrote two solutions. The first one finds all solutions, but it is slow (takes about 12 seconds on my machine). I got around this by writing the results to a yaml file and using that for subsequent runs. My second solution just picks a random permutation until if finds one that meets the requirements. # chess960.rb require 'permutation' require 'yaml' file = 'positions.yml' def create_positions_file(file, pieces) positions = Permutation.for(pieces).map{|p| p.project}.uniq positions = positions.select do |p| are_bishops_on_opposite_colors?(p) && is_king_between_rooks?(p) end File.open(file ,'w+'){|f| f.write(YAML::dump(positions))} end def are_bishops_on_opposite_colors?(a) (a.index('B') + a.rindex('B')).modulo(2) != 0 end def is_king_between_rooks?(a) (a.index('R') < a.index('K')) && (a.index('K') < a.rindex('R')) end create_positions_file(file, %w{R N B K Q B N R}) unless File.exist?(file) positions = YAML::load_file(file) random = rand(positions.size) puts "Starting position #{random}:" {1 => 'White', 8 => 'Black'}.sort.each do |k, color| place = ('a'..'h').to_a.join(k.to_s + ' ') + k.to_s puts "\n#{color}\n\n#{place}\n #{positions[random].join(' ')}" end #eof #chess960_2.rb require 'permutation' def bishops_on_opposite_colors?(a) (a.index('B') + a.rindex('B')).modulo(2) != 0 end def king_between_rooks?(a) (a.index('R') < a.index('K')) && (a.index('K') < a.rindex('R')) end pieces = %w{R N B K Q B N R} loop do @positions = Permutation.for(pieces).random.project(pieces) break if bishops_on_opposite_colors?(@positions) && king_between_rooks?(@positions) end {1 => 'White', 8 => 'Black'}.sort.each do |k, color| place = ('a'..'h').to_a.join(k.to_s + ' ') + k.to_s puts "\n#{color}\n\n#{place}\n #{@positions.join(' ')}" end