I am making a simple program that censors a users input based on the words chosen.
puts "Enter your Text: "
text = gets.chomp.downcase!
puts "Word to censor: "
censor1 = gets.chomp
censor1.downcase!
puts "Second word to censor: "
censor2 = gets.chomp
censor2.downcase!
words = text.split(" ")
words.each do |letter|
if letter == censor1
print "CENSORED "
else
print words + " "
end
end
So, is it possible to set: 'if letter == censor1 and censor 2' ?
You can check if object present in array with the help of Array#include?
if [censor1, censor2].include?(letter)
A bit simplified variant of your code:
puts 'Enter your Text: '
text = gets.chomp.downcase
puts 'Word to censor: '
censor1 = gets.chomp.downcase
puts 'Second word to censor: '
censor2 = gets.chomp.downcase
text.split(' ').each do |word|
if [censor1, censor2].include?(word)
print 'CENSORED '
else
print word + ' '
end
end
And much easier and better solution with String#gsub which replaces all occurrences of censored words in text:
puts 'Enter your Text: '
text = gets.chomp.downcase
puts 'Word to censor: '
censor1 = gets.chomp.downcase
puts 'Second word to censor: '
censor2 = gets.chomp.downcase
[censor1, censor2].each { |c| text.gsub!(c, 'CENSORED') }
puts text
If you are asking if either (downcased) censorX contains the character letter:
censor1+censor2.include?(letter)
If you are asking if both censorX's contain the character letter:
censor1.include?(letter) && censor1.include?(letter)
If you are asking if all censorX strings equal the string letter, then:
if [censor1, censor2,...].uniq == [letter]
...
end
Related
I am new to Ruby and working with this hangman style word guessing game. I have 2 main issues. Here is what I am working with now:
class Word_game
def initialize(word)
#word = word.downcase
#display_word = "_ " * word.length
end
def guess_the_word(word_guess)
word_guess.downcase
#word.split("").each_with_index do |word_letter, index|
if word_guess == word_letter
#display_word[index] = word_guess
p #display_word
puts "You're getting somewhere! Keep trying!"
end
end
if !#word.include? (word_guess)
puts "Nope, guess again..."
end
def win?
if #word == #display_word
puts "Congratulations you won!!! You are the word master!!!"
true
else
false
end
end
def lose?
if #attempts == 0
puts "You lose!!"
true
end
end
puts "Welcome to the Word Guessing Game! Let's see if YOU have what it TAKES!!!"
puts "This is a 2 player game. "
puts "Player 1... please enter a word for Player 2 to guess!"
puts ">>"
game_word = gets.chomp
game = Word_game.new(game_word)
attempts = 0
guessed_letters = []
until #attempts == game_word.length
puts "Ok Player 2, Guess a letter! GO!!!"
letter_guess = gets.chomp
if guessed_letters.include? letter_guess
puts "You already guessed that letter! Enter a new one."
letter_guess = gets.chomp
end
guessed_letters << letter_guess
game.guess_the_word(letter_guess)
if game.win?
attempts += 1
else game.lose?
end
end
end
First, the word progress should look like this if the word is hello:
h _ e _ _ o
Instead of this, the spaces are not in the right places and looks like this (an actual outcome of running my code):
.
Ok Player 2, Guess a letter! GO!!!
h
"h _ _ _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
o
"h _ o _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
e
"he_ o _ _ "
You're getting somewhere! Keep trying!
Ok Player 2, Guess a letter! GO!!!
l
"hel o _ _ "
You're getting somewhere! Keep trying!
"hello _ _ "
When the user guesses the word, it does not put my "congrats" statement and end the game.
I am also stuck on my 'lose' method. I am not sure how to fix the method so that the game ends when the user runs out of attempts and prints the "lose" statement.
Thanks for your help!
I think you're making the output too complicated. I would track the word and the guesses in an array. Instead of a display_word variable, I'd make it a method, possibly "to_s"
By the way, Ruby convention is to use CamelCase class names.
class WordGame
def initialize(word)
#word = word.downcase.chars
#guesses = ["_"] * #word.size
end
def to_s
#guesses.join " "
end
This should fix your spacing problem. This will also simplify guesses.
Also, the checking to see if you've already used the letter should probably be handled by the WordGame class.
For your first problem, your #display_word starts as follows:
[0] = '_' # For h
[1] = ' '
[2] = '_' # For e
[3] = ' '
...
When you guess 'e', for instance, you do:
#display_word[index] = word_guess
Where index equals 1, the second character in "hello", so as you can see it doesn't write to the 'e' index in #display_word.
For your second problem, there are a number of ways to fix it. For instance, I would do something like using #attempts_remaining starting from a value of 10 or so, then using the existing code:
if !#word.include? (word_guess)
#attempts_remaining -= 1 # Count failure to guess
puts "Nope, guess again..."
end
Then:
def win?
# If you've guessed all the letters, there's no '_' left in the display word
if !#display_word.include? ('_')
puts "Congratulations you won!!! You are the word master!!!"
true
else
false
end
end
def lose?
if #attempts_remaining == 0
puts "You lose!!"
true
end
end
Finally, tweak the until loop termination condition:
until game.win? or game.lose?
The existing calls to win? and lose? can be deleted.
(WORD MISSING GAME)
puts " "
puts "Total Round"
puts " "
puts "=> [Round-One ,Round-two,Round -three Round-four]"
puts " "
puts "=> [TOTAL 5 Tries]"
puts " "
one=""
two=""
three=""
four=""
puts " "
puts " --ROUND One press-- => (1)"
one=gets.to_i
puts '==================='
puts "Question:=> ( K ? N G )"
puts ""
c=5
5.times do
string1 = 'i'
stringone ="I"
puts "Answer:=> Try NO:#{c}"
string2 = gets.chomp
if (string1==string2)
puts "Good Work correct spaling"
break
elsif (stringone == string2 )
puts "Good Work correct spaling"
break
else
puts "-Worng spaling-"
end
c -=1
end
puts " Round Over "
if c<1
puts " Tries Over Game End "
exit
end
puts '==================='
puts "--ROUND Two press-- => (2)"
two=gets.to_i
puts '==================='
puts "Question:=> (P L ? Y )"
5.times do
string1 = 'a'
stringone = "A"
puts "Answer:=> Try NO:#{c}"
string2 = gets.chomp
if (string1==string2)
puts "Good Work correct spaling"
break
elsif (stringone==string2)
puts "Good Work correct spaling"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " Tries Over Game End "
exit
end
end
puts " Round Over "
puts '==================='
puts "--ROUND Three press-- => (3)"
three=gets.to_i
puts '==================='
puts "Question:=> ( S P ? T )"
5.times do
string1 = 'o'
stringone= 'O'
puts "Answer:=> Try NO:#{c}*"
string2 = gets.chomp
if (string1==string2)
puts "_Good Work correct spaling_"
break
elsif (stringone == string2)
puts "_Good Work correct spaling_"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " *Tries Over Game End* "
exit
end
end
puts " *Round Over* "
puts '==================='
puts "--ROUND Four press-- => (4)"
four=gets.to_i
puts '==================='
puts "Question:=> ( G ? M E )"
5.times do
string1 = 'a'
stringone = "A"
puts "Answer:=> Try NO:#{c}*"
string2 = gets.chomp
if (string1==string2)
puts "_Good Work correct spaling_"
break
elsif (stringone == string2)
puts "_Good Work correct spaling_"
break
else
puts "-Worng spaling-"
end
c -=1
if c<1
puts " *Tries Over Game End* "
exit
end
end
puts "**Yahoo Congragualtion complete All Round**"
Run my code your ruby interpretor, to see my code. Afterwards, try to guess the full word. The program will tell you that your guess was correct but it doesn't end the game if you guess the entire word instead of each letter one by one.
I also want to add a Dictionary to my code to be able to play against the computer instead of with myself or a friend!
def clear_screen
return system('cls') if Gem.win_platform?
system('clear')
end
loop do
incorrect_guesses = 0
puts ''
puts 'Welcome to Hangman, Win or lose your life!'
puts ''
puts 'Choose Category: It can be anything you desire!'
player1_category = gets.chomp
puts ''
puts 'Player 1, Please enter your desired word'
secret_word = gets.chomp.downcase
clear_screen
correct_guess = ['-'] * secret_word.length
clear_screen
puts "The category is: #{player1_category}"
puts 'Player 2, Please enter your guess'
loop do
puts '_ ' * secret_word.length
player2_guess = gets.chomp.downcase
clear_screen
if secret_word.include? player2_guess
secret_word.each_char.with_index do |letter, i|
next unless letter == player2_guess
correct_guess[i] = letter
end
puts "The category is: #{player1_category}"
puts ''
print 'Guess the word: '
print correct_guess.join('')
puts ''
puts 'Correct. Keep trying!!'
puts ''
else
puts "The category is: #{player1_category}"
puts ''
print 'Guess the word: '
print correct_guess.join('')
puts ''
puts "The word doesn't contain that letter '#{player2_guess.upcase}'"
puts ''
incorrect_guesses += 1
end
puts "Incorrect Guesses: #{incorrect_guesses}"
puts ''
if incorrect_guesses == 6
puts ''
puts '|---+---+- '
puts '| |'
puts '| 0'
puts '| |\\'
puts '| /\\'
puts '-+----------'
puts "The Secret Word is '#{secret_word.capitalize!}'"
puts ''
break
end
next unless secret_word == correct_guess.join('')
puts ''
puts ' (#)'
puts ' ^\\|'
puts ' |/^'
puts '____|_____'
puts ''
puts 'You Win!'
puts ''
puts "You correctly guessed the word '#{secret_word.capitalize!}'"
break
end
end
I got to work with the following change to the next unless test:
if secret_word.include? player2_guess
secret_word.each_char.with_index do |letter, i|
next unless player2_guess.include? letter
correct_guess[i] = letter
end
You were comparing the entire entry to a single character. 't' != 'test'
As for a dictionary, the answer in this link should help
Your question is not super clear, but here are a few comments / answers:
Guessing the whole word: You could wrap your current if secret_word.include? player2_guess in another if that tests the length of the input. (This assumes all words are greater than 1 letter). The if statement should test if the user_input.length > 1. If so, evaluate whether the guess is the correct word, etc.
Adding a dictionary: Easiest was would be to hardcode an array of possible word values. If you want them to correspond to a category, you could make a hash like this {'category_1' => [word, word, word], 'category_2' => [word, word, word]}. Then you could pick a random value from the hash (category) and then a random value from the corresponding array.
I have made this program which counts characters in your name.
puts 'What is your first name?'
forename = gets.chomp
puts 'what is your middle name?'
middlename = gets.chomp
puts 'what is your surname?'
surname = gets.chomp
puts 'Did you know there are ' + forename.length.to_s + middlename.length.to_s + surname.length.to_s + ' characters in your name?'
However this adds the numbers next to each other to equal 555 instead of 15.
I cant convert the lengths to integers as I won't be able to add the string of text before.
puts 'What is your first name?'
forename = gets.chomp
puts 'what is your middle name?'
middlename = gets.chomp
puts 'what is your surname?'
surname = gets.chomp
name_length = [forename,middlename,surname].map(&:length).inject(:+)
puts 'Did you know there are ' + name_length + ' characters in your name?'
OR simply without the #to_s. With #to_s you are converting numbers back to string and concatenating string.
puts 'What is your first name?'
forename = gets.chomp
puts 'what is your middle name?'
middlename = gets.chomp
puts 'what is your surname?'
surname = gets.chomp
puts 'Did you know there are ' + forename.length + middlename.length + surname.length + ' characters in your name?'
I am going through a Ruby course on Codecademy.com. The problem is listed under Iterators and Loops. Here are the instructions:
Let's start simple: write an .each loop that goes through words and just prints out each word it finds.
Here is what I have which does not seem to pass the test, so I just want to know if it is correct or not.
puts "need input please"
text = gets.chomp
words = text.split(" ")
words.each do |x|
puts "#{x}"
end
puts "need another input"
redact = gets.chomp
Somewhat oddly, this is what passed the course example
puts "need input please"
text = gets.chomp
words = text.split(" ")
redact = gets.chomp
Which is obcviously not right since it does not make use of the .each loop.
words.each do |x|
puts "#{x}"
end
x is your block variable, and doesn't need to be interpolated.
Try
words.each do |x|
puts x
end
hello im doing the same course on codecademy and wrote this even though it lets me pass im unsure if its correct if this helps
puts "Enter paragraph here: "
text=gets.chomp
puts "Word to redact"
redact = gets.chomp
words = text.split {" "}
words.each do |words|
if words == redact
print "REDACTED "
else
print words + " "
end
end
I'm trying to write an application that removes words from a list of words:
puts "Words:"
text = gets.chomp
puts "Words to remove:"
remove = gets.chomp
words = text.split(" ")
removes = remove.split(" ")
words.each do |x|
if removes.include.upcase? x.upcase
print "REMOVED "
else
print x, " "
end
end
How would I make this case insensitive?
I tried putting .upcase in there but no luck.
words.each do |x|
if removes.select{|i| i.downcase == x.downcase} != []
print "REMOVED "
else
print x, " "
end
end
array#select will select any element from the array if the block yields true. So if select do not select any element and return an empty array, it is not in the array.
Edit
You can also use if removes.index{|i| i.downcase==x.downcase}. It performs better than select since it does not create a temporary array and returns whenever it finds the first match.
puts "Words:"
text = gets.chomp
puts "Words to remove:"
remove = gets.chomp
words = text.split(" ")
removes = remove.upcase.split(" ")
words.each do |x|
if removes.include? x.upcase
print "REMOVED "
else
print x, " "
end
end