Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'game.rb'
- class Player
- attr_reader :game
- def initialize(game=nil)
- @game = game
- @game ||= Game.new
- end
- def play
- # find the numbers in play
- numbers = []
- 1.upto(9) do |i|
- (bulls,cows) = game.secret.score(Array.new(4) { i })
- if ( bulls > 0 || cows > 0 )
- numbers << i
- end
- end
- # try a forward rotating approach
- #
- # keep track of the scoring, if we can't find a match in mere rotating we
- # must be able to calculate the best results
- #
- bulls = -1
- count = 0
- high = {}
- while bulls != 4
- (bulls, cows) = game.secret.score(numbers)
- high[numbers] = bulls if bulls >= 2
- numbers = rotate(numbers, count += 1) if bulls != 4
- break if count > 20
- end
- if bulls != 4
- numbers = must_be(high)
- end
- puts "#{numbers.join} -- #{game.secret.secret} : #{numbers == game.secret.s\
- ecret}"
- end
- # figure out what it must be, given the high scoring combinations
- #
- def must_be(high)
- # make a list of positions and numbers
- pos = { 0 => [], 1 => [], 2 => [], 3 => [] }
- high.each_key { |key|
- key.each_index { |i| pos[i] << key[i] }
- }
- # find double occurences on the given position, they must be right
- must_be = Array.new(4) { 0 }
- pos.each_key { |i|
- prev = 0
- pos[i].sort { |a,b| a <=> b }.each do |n|
- must_be[i] = n if n == prev
- prev = n
- end
- }
- if must_be.include? 0
- # There are still empty positions we have figured out only 2.
- # The other 2 numbers are known - try them at each available position
- #
- # First copy the must be positions
- #
- could_be = [ must_be.dup ]
- could_be[0].each_index { |i|
- # substract any already known numbers from the pool
- pos[i] -= must_be
- while could_be[0][i] == 0
- # assume the first number is right unless it already occurs
- candidate = pos[i].shift
- could_be[0][i] = candidate unless could_be[0].include? candidate
- end
- }
- # The newly found numbers might be reversed, fix that
- could_be[1] = could_be[0].dup
- must_be.each_index { |i|
- if must_be[i] == 0
- could_be[1][
- i == 0 ? 3 : i == 1 ? 2 : i == 2 ? 1 : 0
- ] = could_be[0][i]
- end
- }
- # Check if the first guess fits
- (bulls, cows) = game.secret.score(could_be[0])
- must_be = bulls == 4 ? could_be[0] : could_be[1]
- end
- must_be
- end
- # Rotate the numbers forward
- #
- def rotate(array,count)
- pos = count % 4
- return array if pos == 0
- dup = array.dup
- dup[pos] = dup[pos-1]
- dup[pos-1] = array[pos]
- return dup
- end
- end
Add Comment
Please, Sign In to add comment