From: Dennis Ranke Date: 2005-01-24T02:10:54+09:00 Subject: Re: [QUIZ] Paper Rock Scissors (#16) --------------010203080703070805000705 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Here is my history based solution. It tries to guess the most probable choice based on the last few rounds and then counters that. --------------010203080703070805000705 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="dr_pattern_player.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dr_pattern_player.rb" class DRPatternPlayer < Player MAX_PATTERN_LENGTH = 6 def initialize(opponent) super @stat = {} @history = [] end def choose paper = rock = scissors = 0 (1..MAX_PATTERN_LENGTH).each do |i| break if i > @history.size*2 stat = @stat[@history[0, i*2]] next unless stat p = stat[:paper] r = stat[:rock] s = stat[:scissors] count = (p + r + s).to_f sig = [p, r, s].max / count - 1.0 / 3 f = sig * (1 - 1/count) p /= count r /= count s /= count if p > 0.4 && r > 0.4 r += p p = s s = 0 end if r > 0.4 && s > 0.4 s += r r = p p = 0 end if s > 0.4 && p > 0.4 p += s s = r r = 0 end paper += p * f rock += r * f scissors += s * f end case rand(3) when 0: paper += 0.2 when 1: rock += 0.2 when 2: scissors += 0.2 end paper *= rand() rock *= rand() scissors *= rand() return :scissors if paper > rock && paper > scissors return :paper if rock > scissors return :rock end def result(you, them, result) (1..MAX_PATTERN_LENGTH).each do |i| break if i > @history.size*2 key = @history[0, i*2] @stat[key] ||= {:paper => 0, :rock => 0, :scissors => 0} @stat[key][them] += 1 end @history = ([you, them] + @history)[0, MAX_PATTERN_LENGTH*2] end end --------------010203080703070805000705--