1

In the following code, I am trying to get the indices of the occurrences of the letter guess in array secret_word, store the indices in an array indices, then, using indices, insert the same letter into another array user_word without disturbing the other letters that might already be in user_word.

if secret_word.include?(guess) #secret_word is an array of chars. guess is a char.
  indices = Array.new
  indices<< secret_word.each_index.select{ |letter| secret_word[letter] == guess } #verified that this array fills correctly
  indices.each do |e|
    user_word[e] = guess
  end
end

The error message implies that each element of indices is an array, not a fixnum as expected. It will not let me use the element from indices to index into user_word. Help?

2
  • You didn't say what the error message is. Commented Sep 30, 2013 at 2:56
  • Arrays are indexed by number, not objects (.each_index would yield 0, 1, ... up to the length of the array minus 1). A Hash would be referenced using objects. Is secret_word really an Array? Commented Sep 30, 2013 at 3:03

2 Answers 2

2

.select returns an array which you are trying to add as an element to indices so you have an array of arrays with one element, correct way:

indices = secret_word.each_index.select{ |letter| secret_word[letter] == guess }

or

indices += ...

But I would do something like this:

user_word =
  user_word.split("") 
    .zip(secret_word)
    .map { |u, s| s == guess ? s : u }
    .join
Sign up to request clarification or add additional context in comments.

1 Comment

I'm not allowed to upvote yet, so let me say "thanks!" Zip is perfect!
0

Playtime!

DOSRW="gooxdenql9qdc9uhkdobjqsdcnmj9xdnqbghcdsnrs9qdrsxkhrsdbghqdataak9dbyqdghbbtodonmxshkdlsy"

def guess_the_word
  words = ''
  DOSRW.each_byte {|b| words += b.succ.chr}
  words = words.gsub('e',' ').gsub(':','e').split
  @sw = words[rand(words.size)].chars
  fini = 2**@sw.size - 1
  so_far(v=0)
  loop do
    print 'Guess a letter: '
    letter = gets.chomp.downcase
    b = @sw.inject('') {|w,c| w + (c == letter ? '1' : '0')}.to_i(2)
    b > 0 ? (puts "#{b.to_s(2).chars.map(&:to_i).inject(&:+)} of those!") : (puts "Sorry")
    v |= b
    so_far(v)
    break if v == fini 
  end  
  puts "Congratulations!"  
end

def so_far(v)
  s = v.to_s(2)
  s = ((?0 * (@sw.size-s.size)) + s).chars   
  puts "#{@sw.zip(s).inject('') {|m,e| m + (e.last=='1' ? e.first : '-')}}"
end

Notice that I'm bit-twiddling to keep track of the positions of the currently-selected letter (b) and of all correctly-guessed letters so far (y). The game continues until all of y's bits equal one: break if v == fini.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.