#!/usr/bin/ruby require "aitask.rb" # See http://sartak.katron.org/nh/mastermind.html for a discussion of this # code, including figures for the average and max number of attempts we'll # need. class TaskFindCastleTune < ElAITask @@tune = "" @@notes = %w(A B C D E F G) @@seen = {}; def desire() return 0 end def execute() instrument = inventory.find_tonal_instrument() # apply instrument, no we don't want to improvise response = send "a" + instrument.invletter + "n" # Ack! if response !~ /What tune are you playing\?/ return end # we've seen five unique notes, so remove any others if (@@seen.keys.size == 5) @@notes.delete_if {|note| not @@seen.has_key?[note] } end if (@@notes.size == 1) # easy optimization to make, so why not :) @@tune += @@notes[0] * (5 - @@tune.length) send @@tune return end response = send @@tune + @@notes[0] if response =~ /You hear \d tumblers? click/ # "You hear 1 tumbler click and 1 gear turn." # "You hear 1 tumbler click." # Move this note to the end of the list (so we're sure to get the # correct note before we see this one again) note = @@notes.delete_at(0) @@seen[note] = 1 @@notes.push(note) elsif response =~ /You hear (\d) gears? turn\./ && $1.to_i > @@tune.length() # Got the correct note, yay! # We check for tune length because as soon as we get the first note, # all responses will have this text. # Consider correct tune "AGGGG" and we play "AB" # It'll say "You hear 1 gear turn." even though the current note ("B") # isn't in the tune at all. @@seen[@@notes[0]] = 1 @@tune += @@notes[0] else # No tumblers, no new gears, so this note is no longer possible in the # rest of the tune. @@notes.delete_at(0) end end end if __FILE__ == $0 require "../utils/assert.rb" print "unit test succeeded\n" end