pastebin light

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

pastebin light //misacek

Posted by chess.rb on Sun 4 Dec 2011 10:16:55 CET
download | new post

  1.  
  2. #!/usr/bin/env ruby
  3.  
  4. # Desk info:
  5. # 0,7 1,7 ... 7,7
  6. # ... ... ... ...
  7. # 0,1 1,1 ... 7,1
  8. # 0,0 1,0 ... 7,0
  9. SIZE = 8
  10.  
  11. # finished example: 6 3 1 4 7 0 2 5
  12.  
  13. class VariantList
  14.  
  15. attr_accessor :validator
  16. attr_accessor :list
  17.  
  18. def initialize
  19. @validator = [ ]
  20. @list = [ ]
  21. end
  22.  
  23. def size?
  24. return list.size
  25. end
  26.  
  27. def add(t)
  28. @list << t
  29. worker = @validator
  30. t.each do|i|
  31. worker[i] = [] if worker[i] == nil
  32. worker = worker[i]
  33. end
  34. # TODO: implement second attribute with
  35. # a) conflict counts
  36. # b) conflicts sum
  37. # to allow: worker << [information about variant]
  38. end
  39.  
  40. def include?(t)
  41. worker = @validator
  42. t.each do|i|
  43. return false if worker[i] == nil
  44. worker = worker[i]
  45. end
  46. return true if worker.class == Array && worker.size == 0
  47. return false
  48. end
  49.  
  50. def info()
  51. print 'Found ', @list.size, ' variants total.', "\n"
  52. end
  53.  
  54. end
  55.  
  56. class Board
  57.  
  58. attr_accessor :members
  59.  
  60. def initialize
  61. @members = [ ]
  62. end
  63.  
  64. def <<(m)
  65. @members << m
  66. end
  67.  
  68. def variant
  69. r = [ ]
  70. @members.each{|m| r << m.y }
  71. return r
  72. end
  73.  
  74. def in_conflict?(q1, q2)
  75. diff = q1.x - q2.x
  76. return (q1.x == q2.x || q1.y == q2.y || q1.y == q2.y+diff || q1.y == q2.y-diff)
  77. end
  78.  
  79. def field_conflicts?(x, y)
  80. pseudo = Queen.pseudo(x,y)
  81. return conflicts?(pseudo)-1
  82. end
  83.  
  84. def conflicts?(queen)
  85. sum = 0
  86. @members.each{|m|
  87. next if m == queen
  88. sum += 1 if in_conflict?(queen, m)
  89. }
  90. return sum
  91. end
  92.  
  93. def finished?
  94. @members.each{|m| return false if conflicts?(m) != 0 }
  95. true
  96. end
  97.  
  98. def draw
  99. line = '.'
  100. 2.upto(SIZE){ line += " ." }
  101. line += "\n"
  102. out = ''
  103. 1.upto(SIZE){ out += line }
  104.  
  105. members.each{|m|
  106. # m.info()
  107. out[ SIZE*SIZE*2 - SIZE*m.y*2 - SIZE*2 + m.x*2 ] = conflicts?(m).to_s #'@'
  108. }
  109. print out
  110. end
  111.  
  112. end
  113.  
  114. class Queen
  115.  
  116. attr_accessor :x
  117. attr_accessor :y
  118.  
  119. def initialize(x)
  120. @x = x
  121. @y = (rand*255).to_i % SIZE
  122. end
  123.  
  124. def self.pseudo(x, y)
  125. q = Queen.new(x)
  126. q.y = y
  127. return q
  128. end
  129.  
  130. def name
  131. pos = axis2pos(@x, @y)
  132. return "D" + pos[0] + pos[1].to_s
  133. end
  134.  
  135. end
  136.  
  137. def axis2pos(x,y)
  138. s = 'a'
  139. s[0] = ?a + x
  140. y += 1
  141. return [s, y]
  142. end
  143.  
  144. STDOUT.sync = true
  145. begin
  146.  
  147. # Initialize
  148. variants = VariantList.new
  149. board = Board.new
  150. 0.upto(SIZE-1){|w| board << Queen.new(w) }
  151. if ARGV.size > 0 then
  152. board.members.each_with_index{|m,i|
  153. m.y = ARGV[i].to_i
  154. }
  155. end
  156. variants.add(board.variant())
  157.  
  158. puts 'Initial board:'
  159. board.draw()
  160. puts
  161.  
  162. #Start processing
  163. puts 'Processing...'
  164.  
  165. while (!board.finished?) do
  166. if variants.size? % 1 == 0 then
  167. print ". "
  168. print variants.size?, "\n" if variants.size? % 35 == 0
  169. end
  170.  
  171. # Put figures in order of conflicts number
  172. order = [ ]
  173. 0.upto(SIZE-1){|i| order[i] = [ ] }
  174.  
  175. board.members.each{|m|
  176. order[board.conflicts?(m)] << m
  177. }
  178.  
  179. # Walk-through in reverse order to eliminate bad ones first
  180. changed = false
  181. order.reverse.each_with_index{|o,oi|
  182. next if o.size == 0
  183. break if changed
  184. o.each{|m|
  185. break if changed
  186. # print 'Examining member [', m.x, ',', m.y, '] with conflict rate ', SIZE-1-oi, "...\n"
  187.  
  188. # Put fields in row in order of conflicts with other figures
  189. positions = [ ]
  190. 0.upto(SIZE-1){|y|
  191. confs = board.field_conflicts?(m.x, y)
  192. positions[confs] = [ ] if positions[confs] == nil
  193. positions[confs] << y if y != m.y
  194. }
  195.  
  196. # Walk through fields, starting with least conflicting first
  197. positions.each_with_index{|c,ci|
  198. break if changed
  199. next if c == nil
  200. c.each{|f|
  201. # next if ci > oi # TODO: Why does this i-loops 7-6-5-...-0 start tile?
  202. # print 'Examining field with conflict rate ', ci, "...\n"
  203. # check whether moving member here isn't in variants already
  204. current = board.variant()
  205. current[m.x] = f
  206. break if variants.include?(current)
  207. # move figure
  208. m.y = f
  209. changed = true
  210. # print 'New board ', variants.size?, ":\n"
  211. # board.draw()
  212. variants.add(current)
  213. break
  214. }
  215. }
  216.  
  217. }
  218. }
  219.  
  220. end
  221.  
  222. # Board is now in finished state
  223. print "[done!]\n\n"
  224. print "Task finished in ", variants.size?-1, " steps.\n"
  225. puts 'Finished board:'
  226. board.draw()
  227. puts
  228.  
  229. end
  230.  

Syntax highlighting: