Guest User

Untitled

a guest
Jun 19th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.77 KB | None | 0 0
  1. require 'game.rb'
  2.  
  3. class Player
  4. attr_reader :game
  5.  
  6. def initialize(game=nil)
  7. @game = game
  8. @game ||= Game.new
  9. end
  10.  
  11. def play
  12. # find the numbers in play
  13. numbers = []
  14. 1.upto(9) do |i|
  15. (bulls,cows) = game.secret.score(Array.new(4) { i })
  16. if ( bulls > 0 || cows > 0 )
  17. numbers << i
  18. end
  19. end
  20.  
  21. # try a forward rotating approach
  22. #
  23. # keep track of the scoring, if we can't find a match in mere rotating we
  24. # must be able to calculate the best results
  25. #
  26. bulls = -1
  27. count = 0
  28. high = {}
  29.  
  30. while bulls != 4
  31. (bulls, cows) = game.secret.score(numbers)
  32. high[numbers] = bulls if bulls >= 2
  33. numbers = rotate(numbers, count += 1) if bulls != 4
  34.  
  35. break if count > 20
  36. end
  37.  
  38. if bulls != 4
  39. numbers = must_be(high)
  40. end
  41.  
  42. puts "#{numbers.join} -- #{game.secret.secret} : #{numbers == game.secret.s\
  43. ecret}"
  44. end
  45.  
  46. # figure out what it must be, given the high scoring combinations
  47. #
  48. def must_be(high)
  49. # make a list of positions and numbers
  50. pos = { 0 => [], 1 => [], 2 => [], 3 => [] }
  51. high.each_key { |key|
  52. key.each_index { |i| pos[i] << key[i] }
  53. }
  54.  
  55. # find double occurences on the given position, they must be right
  56. must_be = Array.new(4) { 0 }
  57. pos.each_key { |i|
  58. prev = 0
  59. pos[i].sort { |a,b| a <=> b }.each do |n|
  60. must_be[i] = n if n == prev
  61. prev = n
  62. end
  63. }
  64.  
  65. if must_be.include? 0
  66. # There are still empty positions we have figured out only 2.
  67. # The other 2 numbers are known - try them at each available position
  68. #
  69. # First copy the must be positions
  70. #
  71. could_be = [ must_be.dup ]
  72. could_be[0].each_index { |i|
  73.  
  74. # substract any already known numbers from the pool
  75. pos[i] -= must_be
  76.  
  77. while could_be[0][i] == 0
  78. # assume the first number is right unless it already occurs
  79. candidate = pos[i].shift
  80. could_be[0][i] = candidate unless could_be[0].include? candidate
  81. end
  82. }
  83.  
  84. # The newly found numbers might be reversed, fix that
  85. could_be[1] = could_be[0].dup
  86. must_be.each_index { |i|
  87. if must_be[i] == 0
  88. could_be[1][
  89. i == 0 ? 3 : i == 1 ? 2 : i == 2 ? 1 : 0
  90. ] = could_be[0][i]
  91. end
  92. }
  93.  
  94. # Check if the first guess fits
  95. (bulls, cows) = game.secret.score(could_be[0])
  96. must_be = bulls == 4 ? could_be[0] : could_be[1]
  97. end
  98.  
  99. must_be
  100. end
  101.  
  102. # Rotate the numbers forward
  103. #
  104. def rotate(array,count)
  105. pos = count % 4
  106.  
  107. return array if pos == 0
  108.  
  109. dup = array.dup
  110. dup[pos] = dup[pos-1]
  111. dup[pos-1] = array[pos]
  112.  
  113. return dup
  114. end
  115. end
Add Comment
Please, Sign In to add comment