From: Rob Biedenharn Date: 2006-12-18T22:27:57+09:00 Subject: Re: [QUIZ] Chess960 (#106) [SOLUTION] I found the Wikipedia article that described the Chess960_Enumbering_Scheme and used its direct derivation of the placement from the number. The relevant portion of the article is mixed in as comments in the code below. -Rob Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com #!/usr/bin/env ruby -w # # Solution by: Rob Biedenharn # # From: james@grayproductions.net # Subject: [QUIZ] Chess960 (#106) # Date: December 15, 2006 8:50:58 AM EST # To: ruby-talk@ruby-lang.org # # by Kieran Wild # # Chess960, is a chess variant produced by Grandmaster Bobby Fischer by # formalizing the rules of Shuffle Chess. Its goal was to create a chess # variant in which chess creativity and talent would be more important than # memorization and analysis of opening moves. His approach was to create a # randomized initial chess position, which would thus make memorizing chess # opening move sequences far less helpful. The initial position is set up in a # special way and there are 960 such positions, thus the name Chess960. # # The starting position for Chess960 must meet certain rules. White pawns are # placed on the second rank as in chess. All remaining white pieces are placed # randomly on the first rank, but with the following restrictions: # # * The king is placed somewhere between the two rooks. # * The bishops are placed on opposite-colored squares. # # The black pieces are placed equal-and-opposite to the white pieces. For # example, if the white king is placed on b1, then the black king is placed on # b8. Note that the king never starts on file a or h, because there would be # no room for a rook # # Can I suggest a nice little ruby program to generates all 960 possible # starting positions and outputs a random one on request. # ------------------------------------------------------------------------ ---- # From wikipedia: # http://en.wikipedia.org/wiki/Chess960_starting_position # # http://en.wikipedia.org/wiki/Chess960_Enumbering_Scheme # # Direct Derivation # # The accurate sequence of White's Chess960 starting array could be derived # from its number as follows: # debug=ENV['DEBUG'] puts "ARGV: #{ARGV.join(', ')}" if debug starting_position = ARGV.empty? ? rand(960) : ARGV[0].to_i string = '-' * 8 # a) Divide the number by 960, determine the remainder (0 ... 959) and use # that number thereafter. temp = starting_position % 960 puts "starting_position #{starting_position}" if debug puts "a) #{string}" if debug # b) Divide the number by 4, determine the remainder (0 ... 3) and # correspondingly place a Bishop upon the matching bright square (b, d, f, h). temp,lb = temp.divmod 4 string[2*lb+1]='B' puts "b) #{lb} #{string} #{temp}" if debug # c) Divide the number by 4, determine the remainder (0 ... 3) and # correspondingly place a Bishop upon the matching dark square (a, c, e, g). temp,db = temp.divmod 4 string[2*db]='B' puts "c) #{db} #{string} #{temp}" if debug # d) Divide the number by 6, determine the remainder (0 ... 5) und # correspondingly place the Queen upon the matching of the six free squares. n,q = temp.divmod 6 print "d) #{q} " if debug string.gsub!(/-/) { |p| p='Q' if q.zero?; q -= 1; p } puts "#{string} #{n}" if debug # e) Now only one digit (0 ... 9) is left on hand; place the both Knights upon # the remaining five free squares according to following scheme: # # Digit Knights' Positioning # 0 N N - - - # 1 N - N - - # 2 N - - N - # 3 N - - - N # 4 - N N - - # 5 - N - N - # 6 - N - - N # 7 - - N N - # 8 - - N - N # 9 - - - N N require 'enumerator' class Integer def comb(r=1) if self < r or r < 1 elsif r == 1 0.upto(self-1) { |x| yield [x] } else (0...self).each_cons(1) do |i| (self-1).comb(r-1) do |j| next if j.last + i.last >= self-1 bump=i.last+1 yield(i + j.map! { |e| e+bump }) end end end end end print "e) #{n} " if debug 5.comb(2) do |c| # puts "comb: #{c.join(' ')}" if debug if n.zero? c.reverse.each do |q| string.gsub!(/-/) { |p| p='N' if q.zero?; q -= 1; p } end break end n -= 1 end puts "#{string}" if debug # f) The now still remaining three free squares will be filled in the # following sequence: Rook, King, Rook. puts "f)" if debug %w[ R K R ].each do |p| string[string.index('-')] = p puts " #{string}" if debug end fen = "#{string.downcase}/#{'p'*8}/8/8/8/8/#{'P'*8}/#{string} w KQkq - 0 1" puts %{[Event "Starting Position #{starting_position}"]} puts %{[SetUp "1"]} puts %{[FEN "#{fen}"]} __END__