2016-10-29 1 views
3

Я пытаюсь найти способ фильтровать два массива в один, основываясь на угадывании букв в пределах одного из них .. так что в основном палач. Но если бы я быллучший способ фильтровать две строки в 1 в рубине

word_array = ["b", "u", "s", "b", "o", "i"] 
hidden_array = Array.new(word_array.length, "-") 

p hidden_array 

Я хотел бы, чтобы печатать на консоли [ «Ъ», «-», «-», «б», «-», «-»], если «б» были догадывался. Что было бы хорошим начинающим способом создания этого массива, который со временем изменится? Может быть, это хэш? Благодаря!

+0

В каком состоянии удалить u, s, o, i? – Gopal

+0

Какая черта 'busboi'? Должно быть, это настоящее слово? –

+0

Я предполагаю, что 'busboi' - всего лишь пример, @TomLord! LOL –

ответ

3

Вы можете следить за найденных писем в массиве и сделать метод, чтобы сделать печать

word_array = ["b", "u", "s", "b", "o", "i"] 
found_letters = [] 
def hangman_prompt(found_letters) 
    word_array.map do |char| 
    found_letters.include?(char) ? char : "-" 
    end.join(" ") 
end 

Тогда вы могли бы использовать это в цикле ввода следующим образом:

loop do 
    puts hangman_prompt(found_letters) 
    puts "what is your guess?" 
    input = gets.chomp 
    if word_array.include? input 
    found_letters << input 
    end 
end 

I Здесь используется Array#map, который создает новый массив той же длины. Каждый из исходных элементов массива передается блоку, который определяет способ их копирования в новый массив.

+0

Awesome. Спасибо Макс! Все имеет смысл для меня, кроме как .join (""), помеченного в конце метода hangman_prompt. Я видел .join before .. просто никогда в конце определения метода. Должно быть легко понять это, хотя! выглядит как его более короткий способ включить необходимый .join –

+0

Да, это просто синтаксический трюк, я думаю. Причина в том, что если вы «кладете» массив, у него будут новые строки, которые вам не нужны. Вы можете «распечатать» его или присоединиться до 'puts'. –

2

Один из способов сделать это:

word_array = ["b", "u", "s", "b", "o", "i"] 
word_array_i = word_array.map.with_index { |e,i| [e,i] }             
#=> [["b", 0], ["u", 1], ["s", 2], ["b", 3], ["o", 4], ["i", 5]] 
p hidden_array = Array.new(word_array.length, "_") 

until hidden_array == word_array 
    puts 'make a guess' 
    guess = gets.chomp 
    if word_array.include? guess 
    puts 'correct guess' 
    ar = word_array_i.select { |arr| arr.first == guess } 
        .flatten.select { |e| e.class == Fixnum } 
    ar.each { |e| hidden_array[e] = guess } 
    else 
    puts 'incorrect guess' 
    end 
    p hidden_array 
    puts 
end 
puts 'game complete' 

Основные методы исследования hereArray#include?, Enumerator#with_index.

5

Все решения пока вращаются вокруг массивов, но не забывайте, что строка в основном представляет собой массив символов . Просто используйте строки:

word = 'busboi' 
guesses = 'bs' 

word.tr('^'+guesses, '-') 
# => "b-sb--" 

Метод String#tr преобразует все буквы в первом аргументе отображения во втором аргументе, так что вы можете делать такие вещи, как ROT13, простые шифры и такую, или в данном случае использовать функцию отрицания ^, чтобы инвертировать первый набор и заменить все несоответствующие символы.

+0

Мне нравится. 'word.gsub (/ [^ # {догадки}] + /, '-')' является вариантом. –

+0

@CarySwoveland Да, это тоже работает, но 'tr' идеально подходит для этой работы. – tadman

2

Я бы не использовал массивы, просто строки.

Код

def replace_underscores(word, hidden_word, guess) 
    word.scan(Regexp.new(guess)) { hidden_word[Regexp.last_match.begin(0)] = guess } 
    hidden_word 
end 

Пример

word = "busboi" 
hidden_word = "_" * word.length 
    #=> "______" 

replace_underscores(word, hidden_word, "a") # guess "a" 
    #=> "______" 
replace_underscores(word, hidden_word, "b") # guess "b" 
    #=> "b__b__"            
replace_underscores(word, hidden_word, "r") # guess "r" 
    #=> "b__b__" 
replace_underscores(word, hidden_word, "o") # guess "o" 
    #=> "b__bo_" 
replace_underscores(word, hidden_word, "u") # guess "u" 
    #=> "bu_bo_" 
replace_underscores(word, hidden_word, "s") # guess "s" 
    #=> "busbo_" 

Чтобы проверить, если hidden_word было догадаться: больше разрешение одно предположение

def guessed?(hidden_word) 
    hidden_word.count('_').zero? 
end 

guessed?(hidden_word) 
    #=> false 

Обратим.

replace_underscores(word, hidden_word, "i") # guess "i" 
    #=> "busboi" 

guessed?(hidden_word) 
    #=> true 

Примечание

Я использовал метод String#scan с блоком, который выполняется для каждого матча. Внутри блока объект MatchData извлекается с помощью метода класса Regexp::last_match. (В качестве альтернативы можно было бы заменить глобальную переменную $~ на Regexp.last_match. Подробнее см. «Специальные глобальные переменные» на Regexp.) Метод MatchData.begin используется для получения индекса символа в str, который должен быть заменен только что угадываемой буквой.

Смежные вопросы