From: Daniel Finnie Date: 2006-12-19T12:31:58+09:00 Subject: Re: [QUIZ] Chess960 (#106) --Boundary_(ID_ZFfEe0zfyRXvGL7iUxL91g) Content-type: text/plain; charset=ISO-8859-1; format=flowed Content-transfer-encoding: 7BIT This is the full version of the quiz that I wrote first. It uses the ArrayValues class which is described in my previous email. I think it is adequately documented as it is, especially because the algorithm and main logic parts are described in the previous email. Run with no options to get the usage. One thing to say, though is that the facets bracket method is basically this: class String def bracket(wrapper) wrapper + self + wrapper end end It is actually more complex, there is a second argument you can pass in. daniel@daniel-desktop:~$ cat chess960.rb #! /usr/bin/ruby -w require 'arrayvalue.rb' require 'rubygems' require 'facet/string/bracket' # Represents a row ("rank") on a chess board class ChessRow < Array def initialize replace(Array.new(8)) end # Sets the specified vacant square to the specified piece, with nthVacant starting at 0. def setVacantSquare(nthVacantSquare, piece) to_av.select{|x| x.nil?}[nthVacantSquare].set(piece) end def to_s collect{|x| x.bracket(" ")}.join("|").bracket("|") end end class Chess960Row < ChessRow KeRN = <<-END.split("\n").collect{|x| x.split(" ")} N N R K R N R N K R N R K N R N R K R N R N N K R R N K N R R N K R N R K N N R R K N R N R K R N N END def setFromNum(id) # Set the bishops, light first then dark. 1.downto(0) do |x| self[(id % 4)*2 + x] = "B" id /= 4 end # Set the queen setVacantSquare(id % 6, "Q") id /= 6 # Set everything else using KeRN codes. KeRN[id].each do |currentPiece| setVacantSquare(0, currentPiece) end self end end Pawns = ChessRow.new.fill("p").to_s EmptyRows = [ChessRow.new.fill {|i| i % 2 == 0? " " : "#" }.to_s, ChessRow.new.fill {|i| i % 2 == 1? " " : "#" }.to_s] Spacer = "+---" * (Pawns.to_s.length / 4) + "+" def parseInput(input) case input when nil puts "Usage:", "\tchess960 all - Print all the possible Chess960 lineups", "\tchess960 rnd - Print a random Chess960 lineup", "\tchess960 ID - Print ID Chess960 lineup" when /all/ 0.upto(959) {|x| parseInput(x) } when /(ra?nd)/ parseInput(rand(960).to_i) else # is a number input = input.to_i % 960 # Change 960 into 0. mainRow = Chess960Row.new.setFromNum(input).to_s [input.to_s + ": ", mainRow.downcase, Pawns.downcase, EmptyRows * 2, Pawns.upcase, mainRow.upcase]. flatten.each{|x| puts x, Spacer} end end parseInput(ARGV[0]) Ruby Quiz wrote: > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this quiz until > 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz by submitting ideas as often as you can: > > http://www.rubyquiz.com/ > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone > on Ruby Talk follow the discussion. Please reply to the original quiz message, > if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= > > 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. > > Output could be as follows. > > Starting Position 432: > > White > > a1 b1 c1 d1 e1 f1 g1 h1 > N B B R K R Q N > > Black > > a8 b8 c8 d8 e8 f8 g8 h8 > N B B R K R Q N > > Or some better output. > > --Boundary_(ID_ZFfEe0zfyRXvGL7iUxL91g) Content-type: application/x-ruby; name=chess960.rb Content-transfer-encoding: base64 Content-disposition: inline; filename=chess960.rb IyEgL3Vzci9iaW4vcnVieSAtdwpyZXF1aXJlICdhcnJheXZhbHVlLnJiJwpyZXF1aXJlICdy dWJ5Z2VtcycKcmVxdWlyZSAnZmFjZXQvc3RyaW5nL2JyYWNrZXQnCgojIFJlcHJlc2VudHMg YSByb3cgKCJyYW5rIikgb24gYSBjaGVzcyBib2FyZApjbGFzcyBDaGVzc1JvdyA8IEFycmF5 CglkZWYgaW5pdGlhbGl6ZQoJCXJlcGxhY2UoQXJyYXkubmV3KDgpKQoJZW5kCgkJCgkjIFNl dHMgdGhlIHNwZWNpZmllZCB2YWNhbnQgc3F1YXJlIHRvIHRoZSBzcGVjaWZpZWQgcGllY2Us IHdpdGggbnRoVmFjYW50IHN0YXJ0aW5nIGF0IDAuCglkZWYgc2V0VmFjYW50U3F1YXJlKG50 aFZhY2FudFNxdWFyZSwgcGllY2UpCgkJdG9fYXYuc2VsZWN0e3x4fCB4Lm5pbD99W250aFZh Y2FudFNxdWFyZV0uc2V0KHBpZWNlKQoJZW5kCgkKCWRlZiB0b19zCgkJY29sbGVjdHt8eHwg eC5icmFja2V0KCIgIil9LmpvaW4oInwiKS5icmFja2V0KCJ8IikKCWVuZAplbmQKCmNsYXNz IENoZXNzOTYwUm93IDwgQ2hlc3NSb3cKCUtlUk4gPSA8PC1FTkQuc3BsaXQoIlxuIikuY29s bGVjdHt8eHwgeC5zcGxpdCgiICIpfQoJTiBOIFIgSyBSCglOIFIgTiBLIFIKCU4gUiBLIE4g UgoJTiBSIEsgUiBOCglSIE4gTiBLIFIKCVIgTiBLIE4gUgoJUiBOIEsgUiBOCglSIEsgTiBO IFIKCVIgSyBOIFIgTgoJUiBLIFIgTiBOCglFTkQKCQoJZGVmIHNldEZyb21OdW0oaWQpCgkJ IyBTZXQgdGhlIGJpc2hvcHMsIGxpZ2h0IGZpcnN0IHRoZW4gZGFyay4KCQkxLmRvd250bygw KSBkbyB8eHwKCQkJc2VsZlsoaWQgJSA0KSoyICsgeF0gPSAiQiIKCQkJaWQgLz0gNAoJCWVu ZAoJCQoJCSMgU2V0IHRoZSBxdWVlbgoJCXNldFZhY2FudFNxdWFyZShpZCAlIDYsICJRIikK CQlpZCAvPSA2CgkJCgkJIyBTZXQgZXZlcnl0aGluZyBlbHNlIHVzaW5nIEtlUk4gY29kZXMu CgkJS2VSTltpZF0uZWFjaCBkbyB8Y3VycmVudFBpZWNlfAoJCQlzZXRWYWNhbnRTcXVhcmUo MCwgY3VycmVudFBpZWNlKQoJCWVuZAoJCXNlbGYKCWVuZAplbmQKClBhd25zID0gQ2hlc3NS b3cubmV3LmZpbGwoInAiKS50b19zCkVtcHR5Um93cyA9IFtDaGVzc1Jvdy5uZXcuZmlsbCB7 fGl8IGkgJSAyID09IDA/ICIgIiA6ICIjIiB9LnRvX3MsCgkJCUNoZXNzUm93Lm5ldy5maWxs IHt8aXwgaSAlIDIgPT0gMT8gIiAiIDogIiMiIH0udG9fc10KU3BhY2VyID0gIistLS0iICog KFBhd25zLnRvX3MubGVuZ3RoIC8gNCkgKyAiKyIKCmRlZiBwYXJzZUlucHV0KGlucHV0KQoJ Y2FzZSBpbnB1dAoJCXdoZW4gbmlsCgkJCXB1dHMgIlVzYWdlOiIsCgkJCQkiXHRjaGVzczk2 MCBhbGwgLSBQcmludCBhbGwgdGhlIHBvc3NpYmxlIENoZXNzOTYwIGxpbmV1cHMiLAoJCQkJ Ilx0Y2hlc3M5NjAgcm5kIC0gUHJpbnQgYSByYW5kb20gQ2hlc3M5NjAgbGluZXVwIiwKCQkJ CSJcdGNoZXNzOTYwIElEIC0gUHJpbnQgSUQgQ2hlc3M5NjAgbGluZXVwIgoJCXdoZW4gL2Fs bC8KCQkJMC51cHRvKDk1OSkge3x4fCBwYXJzZUlucHV0KHgpIH0KCQl3aGVuIC8ocmE/bmQp LwoJCQlwYXJzZUlucHV0KHJhbmQoOTYwKS50b19pKQoJCWVsc2UgIyBpcyBhIG51bWJlcgoJ CQlpbnB1dCA9IGlucHV0LnRvX2kgJSA5NjAgIyBDaGFuZ2UgOTYwIGludG8gMC4KCQkJbWFp blJvdyA9IENoZXNzOTYwUm93Lm5ldy5zZXRGcm9tTnVtKGlucHV0KS50b19zCgkJCVtpbnB1 dC50b19zICsgIjogIiwKCQkJCW1haW5Sb3cuZG93bmNhc2UsCgkJCQlQYXducy5kb3duY2Fz ZSwKCQkJCUVtcHR5Um93cyAqIDIsCgkJCQlQYXducy51cGNhc2UsCgkJCQltYWluUm93LnVw Y2FzZV0uCgkJCWZsYXR0ZW4uZWFjaHt8eHwgcHV0cyB4LCBTcGFjZXJ9CgllbmQKZW5kCnBh cnNlSW5wdXQoQVJHVlswXSk= --Boundary_(ID_ZFfEe0zfyRXvGL7iUxL91g) Content-type: application/x-ruby; name=arrayvalue.rb Content-transfer-encoding: base64 Content-disposition: inline; filename=arrayvalue.rb Y2xhc3MgQXJyYXlWYWx1ZQoJaW5zdGFuY2VfbWV0aG9kcy5lYWNoIGRvIHxtfAoJCXVuZGVm X21ldGhvZChtKSB1bmxlc3MgbSA9fiAvXl8qKG1ldGhvZF9taXNzaW5nfHNlbmR8aWQpXyok LwoJZW5kCgkKCWRlZiBpbml0aWFsaXplKG9yaWdBcnJheSwgb3JpZ0luZGV4KQoJCUBvcmln QXJyYXksIEBvcmlnSW5kZXggPSBvcmlnQXJyYXksIG9yaWdJbmRleAoJZW5kCgkKCWRlZiBz ZXQobmV3T2JqKQoJCUBvcmlnQXJyYXlbQG9yaWdJbmRleF0gPSBuZXdPYmoKCWVuZAoJCglk ZWYgZ2V0CgkJQG9yaWdBcnJheVtAb3JpZ0luZGV4XQoJZW5kCgkKCWRlZiBtZXRob2RfbWlz c2luZyhtZXRob2QsICphcmdzKQoJCQlnZXQuc2VuZChtZXRob2QsICphcmdzKQoJCXJlc2N1 ZQoJCQlzdXBlcgoJZW5kCgkKCWRlZmluZV9tZXRob2QoOic9ICcpIHt8b3RoZXJ8IHNldChv dGhlcil9CmVuZAoKY2xhc3MgQXJyYXkKCWRlZiB0b19hdigpCgkJcmV0ID0gW10KCQllYWNo X2luZGV4IHt8eHwgcmV0IDw8IEFycmF5VmFsdWUubmV3KHNlbGYsIHgpIH0KCQlyZXQKCWVu ZAplbmQKCl9fRU5EX18KJSBjYXQgdmlldy5yYgpjbGFzcyBBcnJheVZpZXcKICBjbGFzcyBB cnJheUluZGV4UmVmCiAgICBkZWYgaW5pdGlhbGl6ZSggYXJyYXksIGluZGV4ICkKICAgICAg QGFycmF5ID0gYXJyYXkKICAgICAgQGluZGV4ID0gaW5kZXgKICAgIGVuZAoKICAgIGRlZiB2 YWx1ZQogICAgICBAYXJyYXlbQGluZGV4XQogICAgZW5kCgogICAgZGVmIHZhbHVlPShuZXdf dmFsdWUpCiAgICAgIEBhcnJheVtAaW5kZXhdID0gbmV3X3ZhbHVlCiAgICBlbmQKICBlbmQK CiAgZGVmIGluaXRpYWxpemUoIGFycmF5ICkKICAgIEBhcnJheSA9IGFycmF5CiAgICBAcmVm ZXJlbmNlcyA9IFtdCiAgZW5kCgogIGRlZiBbXSgqYXJncykKICAgIGlmIGFyZ3MubGVuZ3Ro ID09IDEgYW5kIGFyZ3Mua2luZF9vZj8gUmFuZ2Ugb3IgYXJncy5sZW5ndGggPiAxCiAgICAg IEByZWZlcmVuY2VzWyphcmdzXS5tYXAgeyB8eHwgeC52YWx1ZSB9CiAgICBlbHNlCiAgICAg IEByZWZlcmVuY2VzWyphcmdzXS52YWx1ZQogICAgZW5kCiAgZW5kCgogIGRlZiBbXT0oaW5k ZXgsIHZhbHVlKQogICAgQHJlZmVyZW5jZXNbaW5kZXhdLnZhbHVlID0gdmFsdWUKICBlbmQK CiAgZGVmIGVhY2gKICAgIEByZWZlcmVuY2VzLmVhY2ggZG8gfHh8CiAgICAgIHlpZWxkIHgu dmFsdWUKICAgIGVuZAogIGVuZAoKCiAgZGVmIGFkZF9yZWYoIGluZGV4ICkKICAgIEByZWZl cmVuY2VzIDw8IEFycmF5SW5kZXhSZWYubmV3KCBAYXJyYXksIGluZGV4ICkKICBlbmQKZW5k CgoKY2xhc3MgQXJyYXkKICBkZWYgc2VsZWN0X3ZpZXcKICAgIHIgPSBBcnJheVZpZXcubmV3 KCBzZWxmICkKICAgIGVhY2hfd2l0aF9pbmRleCBkbyB8aXRlbSwgaW5kZXh8CiAgICAgIHIu YWRkX3JlZiggaW5kZXggKSBpZiB5aWVsZCggaXRlbSApICAgICBlbmQKICAgIHIKICBlbmQK ZW5kCgphID0gKDEuLjEwKS50b19hCgpwIGEKYiA9IGEuc2VsZWN0X3ZpZXcgeyB8eHwgKHgg JSAyKS56ZXJvPyB9CmJbMF0gPSA0MgpwIGEKCiUgcnVieSB2aWV3LnJiClsxLCAyLCAzLCA0 LCA1LCA2LCA3LCA4LCA5LCAxMF0KWzEsIDQyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMF0g --Boundary_(ID_ZFfEe0zfyRXvGL7iUxL91g)--