Having some trouble checking for multiple sets of values.
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[0..2].all?{|move| move == "X"}
end
I wanted to use a multi-dimensional hash like this. Is my syntax wrong or is this just something you cannot do?
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[[0..2][3..5]].all?{|move| move =="X"}
end
another problem is when values[0..2] are already equal to "x" the loop doesn't break until the next turn.
Here is the repl
https://repl.it/JrQe/57
Source code
#entries = {1=>" ", 2=>" ", 3=>" ", 4=>" ", 5=>" ", 6=>" ", 7=>" ", 8=>" ", 9=>" "}
puts "###########################################"
puts " tic-tac-toe"
puts "\t\t 1 | 2 | 3 "
puts "\t\t-----------"
puts "\t\t 4 | 5 | 6 "
puts "\t\t-----------"
puts "\t\t 7 | 8 | 9 "
puts" ###########################################"
class Players
attr_accessor :name, :piece
end
puts "Player one, what is your name?"
player1 = Players.new
player1.name = gets.chomp
player1.piece = "X"
puts "Hello #{player1.name}, you have been assigned #{player1.piece}."
puts "Player two, what is your name?"
player2 = Players.new
player2.name = gets.chomp
player2.piece = "O"
puts "Hello #{player2.name}, you have been assigned #{player2.piece}."
def grid
puts "\t\t #{#entries[1]} | #{#entries[2]} | #{#entries[3]} "
puts "\t\t-----------"
puts "\t\t #{#entries[4]} | #{#entries[5]} | #{#entries[6]} "
puts "\t\t-----------"
puts "\t\t #{#entries[7]} | #{#entries[8]} | #{#entries[9]} "
end
def choice(grid)
name = gets.chomp
name2 = name.to_i
#entries.each do |key,value|
if name2 == key
#entries[key]= "X"
end
end
end
def choice2(grid)
name = gets.chomp
name2 = name.to_i
#entries.each do |key,value|
if name2 == key
#entries[key]= "O"
end
end
end
def turns(player1,player2)
puts "#{player1.name} make your move"
player1 = choice(grid)
puts "#{player2.name} make your move"
player2 = choice2(grid)
end
def win
loop do
turns(player1,player2)
break puts "you win!" if #entries.values[0..2].all?{|move| move == "X"}
end
I think the specific question you're asking is answered like this:
rows = [[0..2],[3..5],[6..8]]
cols = [[0,3,6],[1,4,7],[2,5,8]]
diag = [[0,4,8],[2,4,6]]
(rows + cols + diag).any?{ |line| line.all?{ |cell| #entries[cell] == "X"} }
Also, you can't have two expressions, break and puts before a trailing if statement. Try this:
if ...
puts "You win!"
break
end
Related
I created a calculator in ruby. I am wondering how to put this in a loop so I don't have to run it constantly. I am new to programming so please understand I am I just trying to learn. I would appreciate any help provided.
puts "Hello, My name is Calvin The Calculator and I am a calculator that can do basic functions such as Adding, Subtracting, Multiplying and Dividing"
puts "Press a and enter to enable my services"
enable = gets.chomp
if enable == "a"
puts "Choose which operation you want to do. + for adding, - for subtraction, * for multiplication and / for division"
else
"Puts Im Waiting..."
end
which_operation = gets.chomp
if which_operation == "+"
puts "What is the first number you want to add"
adding_first_number = gets.chomp.to_i
puts "What is the second number you want to add to #{adding_first_number}"
adding_second_number = gets.chomp.to_i
puts "#{adding_first_number} + #{adding_second_number} is #{adding_first_number + adding_second_number}"
else
end
if which_operation == "-"
puts "What is the first number you want to subtract"
subtracting_first_number = gets.chomp.to_i
puts "What is the number you want to subtract from #{subtracting_first_number}"
subtracting_second_number = gets.chomp.to_i
puts "#{subtracting_first_number} - #{subtracting_second_number} is #{subtracting_first_number - subtracting_second_number}"
else
end
if which_operation == "*"
puts "What is the first number you want to multiple"
multiplying_first_number = gets.chomp.to_i
puts "What is the number you want to multiple #{multiplying_first_number} by"
multiplying_second_number = gets.chomp.to_i
puts "#{multiplying_first_number} * by #{multiplying_second_number} is #{multiplying_first_number * multiplying_second_number}"
else
end
if which_operation == "/"
puts "What is the first number to your divison question?"
dividing_first_number = gets.chomp.to_i
puts "What is the divisor?"
dividing_second_number = gets.chomp.to_i
puts "#{dividing_first_number} divided by #{dividing_second_number} is #{dividing_first_number / dividing_second_number}"
else
end
For example:
until (which_operation = gets.chomp).empty?
if which_operation == "+"
...
end
if which_operation == "-"
...
end
if which_operation == "*"
...
end
if which_operation == "/"
...
end
end
This loop will work until you press Enter without entering any text before it.
P.S.: Better use case operator instead of multiple if.
P.P.S.: All your code, after loop addition and without case operator, will be:
puts "Hello, My name is Calvin The Calculator and I am a calculator that can do basic functions such as Adding, Subtracting, Multiplying and Dividing"
puts "Press a and enter to enable my services"
until gets.chomp == "a"
puts "I'm Waiting..."
end
puts "Choose which operation you want to do. + for adding, - for subtraction, * for multiplication and / for division"
until (which_operation = gets.chomp).empty?
if which_operation == "+"
puts "What is the first number you want to add"
adding_first_number = gets.chomp.to_i
puts "What is the second number you want to add to #{adding_first_number}"
adding_second_number = gets.chomp.to_i
puts "#{adding_first_number} + #{adding_second_number} is #{adding_first_number + adding_second_number}"
elsif which_operation == "-"
puts "What is the first number you want to subtract"
subtracting_first_number = gets.chomp.to_i
puts "What is the number you want to subtract from #{subtracting_first_number}"
subtracting_second_number = gets.chomp.to_i
puts "#{subtracting_first_number} - #{subtracting_second_number} is #{subtracting_first_number - subtracting_second_number}"
elsif which_operation == "*"
puts "What is the first number you want to multiple"
multiplying_first_number = gets.chomp.to_i
puts "What is the number you want to multiple #{multiplying_first_number} by"
multiplying_second_number = gets.chomp.to_i
puts "#{multiplying_first_number} * by #{multiplying_second_number} is #{multiplying_first_number * multiplying_second_number}"
elsif which_operation == "/"
puts "What is the first number to your divison question?"
dividing_first_number = gets.chomp.to_i
puts "What is the divisor?"
dividing_second_number = gets.chomp.to_i
puts "#{dividing_first_number} divided by #{dividing_second_number} is #{dividing_first_number / dividing_second_number}"
end
puts "\nLet's try again: "
end
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**"
I am trying to convert a numeric output given by the user so that it always shows 2 decimals. I know that '%.2f' % exists, but it always displays this error "string can't be coerced into fixnum" (I think it conflicts with the methods)
Here's my code:
hash = {}
entry = " "
while entry != "q"
print "Enter your item: "
item = gets.chomp
print "Enter the associated cost: "
cost = gets.chomp.to_f.round(2)
print "Press any key to continue or 'q' to quit: "
entry = gets.chomp
hash[item] = cost
end
puts "Receipt: "
puts "----------"
hash.each do |k,v|
puts "#{k} => $#{v}"
end
puts "----------"
print "subtotal: "
subtotal = hash.values.inject(0, :+)
print "$"
puts '%.2f' % subtotal.round(2)
print "tax: $"
tax = subtotal * 0.06
puts '%.2f' % tax.round(2)
print "total: $"
total = subtotal + tax
puts '%.2f' % total.round(2)
So basically this step:
hash.each do |k,v|
puts "#{k} => $#{v}"
For instance, when I input a cost of 1 in a step before it will show it as
$1.0 and not $1.00
I appreciate any help!
You can do:
hash.each do |k,v|
puts "#{k} => $#{'%.2f' % v}"
end
I'm doing a game creation exercise from Learn Ruby the Hard Way. It's themed after Destiny since that's what I've got on the brain at the moment.
I wanted to have the player pick a character class, and then have that choice hand off some numbers as stats to be checked later in play. Below is the version that actually worked, but it involves creating a several global variables, which I keep reading is not a "best practice" in Ruby.
My question is, is there a way to do what I've got the code below doing without creating all of these global variables, or am I doing what needs to be done?
$might = 1
$agility = 1
$intellect = 1
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
if choice == "1"
$might = 3
puts "You've chosen Titan!"
elsif choice == "2"
$agility = 3
puts "You've chosen Hunter!"
elsif choice == "3"
$intellect = 3
puts "You've chosen Warlock!"
else
puts "Try again."
start
end
end
puts start
puts "Might: #{$might}"
puts "Agility: #{$agility}"
puts "Intellect: #{$intellect}"
You can create a class and use instance variables:
class Game
def initialize
#might = 1
#agility = 1
#intellect = 1
end
attr_reader :might
attr_reader :agility
attr_reader :intellect
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
case choice
when "1"
#might = 3
puts "You've chosen Titan!"
when "2"
#agility = 3
puts "You've chosen Hunter!"
when "3"
#intellect = 3
puts "You've chosen Warlock!"
else
puts "Try again."
start
end
end
end
game = Game.new
game.start
puts "Might: #{game.might}"
puts "Agility: #{game.agility}"
puts "Intellect: #{game.intellect}"
Remark:
I replaced your if-sequence with a case-statement
attr_reader defined the attribute accessor for the instance variables.
Maybe something like this. I prepare it for updates.
class Character
attr_accessor :might, :agility, :intelect, :type
def initialize(type, might = 1, agility = 1, intelect = 1)
#type = type
#might, #agility, #intelect = might, agility, intelect
end
def print_attributes
puts "Type: #{#type}"
puts "Might: #{#might}"
puts "Agility: #{#agility}"
puts "Intelect: #{#intelect}"
end
end
class Player
attr_reader :character
def initialize(character)
#character = character
end
end
class Game
CHARACTER_CLASSES = [
{:type => "Titan", :might => 3, :agility => 1, :intelect => 1},
{:type => "Hunter", :might => 1, :agility => 3, :intelect => 1},
{:type => "Warlock", :might => 1, :agility => 1, :intelect => 3}
]
attr_reader :player
def initialize
#player = nil
end
def start
puts "Make all decisions by pressing the corresponding number."
repeat = true
while repeat
puts "Choose your class:"
CHARACTER_CLASSES.each_with_index do |char_config, i|
puts "#{i+1}. #{char_config[:type]}"
end
choice = gets.chomp
choice_i = choice.to_i
unless choice_i == 0
if char_data = CHARACTER_CLASSES[choice_i - 1]
#player = Player.new( Character.new(char_data[:type], char_data[:might], char_data[:agility], char_data[:intelect]) )
repeat = false
end
end
end
end
end
game = Game.new
game.start
game.player.character.print_attributes
One option could be returning whatever you want from a method:
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
case choice
when '1'
puts "You've chosen Titan!"
{agility: 1, might: 3, intellect: 1}
when '2'
puts "You've chosen Hunter!"
{agility: 3, might: 1, intellect: 1}
when '3'
puts "You've chosen Warlock!"
{agility: 1, might: 1, intellect: 3}
else
puts "Try again."
start
end
end
hero = start
puts "Might: #{hero[:might]}"
puts "Agility: #{hero[:agility]}"
puts "Intellect: #{hero[:intellect]}"
I hope I'm not too annoying . I started ruby 2 weeks ago.
I'm trying to put my calculator in a loop so it restart after calculation ends. Something like "Would you like to try again?"
def add(a, b)
puts "ADDING #{a} + #{b}"
puts "The result is #{a + b}"
end
def arg1()
puts "You chose option 1"
print "please enter first entry "
first_number = gets.to_i
print "Please enter second entry "
second_number = gets.to_i
add(first_number,second_number)
end
def selection()
puts "please enter your option : "
puts "For Adding : 1 "
puts "For Subtacting : 2 "
print "> "
end
selection
options_of_choice = gets.to_i
if options_of_choice == 1
arg1()
elsif options_of_choice == 2
arg2()
else
puts " Restarting"
end
calculator_on = true
while calculator_on
selection
options_of_choice = gets.to_i
if options_of_choice == 1
arg1()
elsif options_of_choice == 2
arg2()
else
puts " Restarting"
end
puts "do you want to try again?"
calculator_on = gets.chomp.downcase == 'y'
end