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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.