In Ruby/Tk I'm am currently making a length converter but I want to be able to allow the user to either press the up or down arrow key and it will increase or decrease the number the user inputed into the Entry box.
require "tk"
require "tkextlib/tile"
root = TkRoot.new {title "Length converter"}
content = Tk::Tile::Frame.new(root){padding "50 15 50 15"}.grid
$input_variable = TkVariable.new
$output_variable = TkVariable.new
input_frame = Tk::Tile::Labelframe.new(content) {text 'Input'; borderwidth 5; relief "sunken"; width 300; height 200; padding "5 0 5 5"}
output_frame = Tk::Tile::Labelframe.new(content) {text 'Conversion'; borderwidth 5; relief "sunken"; width 300; height 200; padding "5 0 5 5"}
go_button = Tk::Tile::Button.new(content) {text 'Calculate'command {func1}}
input_box = Tk::Tile::Entry.new(content) {width 10; textvariable $input_variable}
output_text = Tk::Tile::Label.new(content) {textvariable $output_variablefont TkFont.new('sans 12')}
underbutton_text = Tk::Tile::Label.new(content) {text 'is equivalent to'}
unit_label = Tk::Tile::Label.new(content) {textvariable $unitfont TkFont.new('sans 12')}
$input_dom = TkVariable.new
$unit = TkVariable.new
feet = Tk::Tile::RadioButton.new(input_frame){
text 'Feet'
variable $input_dom
value 1
pack('fill'=>'x')
}
meters = Tk::Tile::RadioButton.new(input_frame){
text 'Meters'
variable $input_dom
value 2
pack('fill'=>'x')
}
inches = Tk::Tile::RadioButton.new(input_frame){
text 'Inches'
variable $input_dom
value 3
pack('fill'=>'x')
}
centi = Tk::Tile::RadioButton.new(input_frame){
text 'Centimeters'
variable $input_dom
value 4
pack('fill'=>'x')
}
miles = Tk::Tile::RadioButton.new(input_frame){
text 'Miles'
variable $input_dom
value 5
pack('fill'=>'x')
}
kilometers = Tk::Tile::RadioButton.new(input_frame){
text 'Kilometers'
variable $input_dom
value 6
pack('fill'=>'x')
}
$output_dom = TkVariable.new
feet = Tk::Tile::RadioButton.new(output_frame){
text 'Feet'
variable $output_dom
value 1
pack('fill'=>'x')
}
meters = Tk::Tile::RadioButton.new(output_frame){
text 'Meters'
variable $output_dom
value 2
pack('fill'=>'x')
}
inches = Tk::Tile::RadioButton.new(output_frame){
text 'Inches'
variable $output_dom
value 3
pack('fill'=>'x')
}
centi = Tk::Tile::RadioButton.new(output_frame){
text 'Centimeters'
variable $output_dom
value 4
pack('fill'=>'x')
}
miles = Tk::Tile::RadioButton.new(output_frame){
text 'Miles'
variable $output_dom
value 5
pack('fill'=>'x')
}
kilometers = Tk::Tile::RadioButton.new(output_frame){
text 'Kilometers'
variable $output_dom
value 6
pack('fill'=>'x')
}
content.grid(:column => 0, :row => 0)
input_frame.grid(:column => 0, :row => 0, :columnspan => 5, :rowspan =>6)
output_frame.grid(:column => 9, :row => 0, :columnspan => 5, :rowspan =>6)
input_box.grid(:column => 0, :row => 7)
go_button.grid( :column => 7, :row => 7)
output_text.grid(:column => 9, :row => 7)
underbutton_text.grid( :column => 7, :row => 9)
unit_label.grid(:column => 10, :row => 7)
def func1
calculate()
unit()
end
def calculate
begin
if $input_dom == $output_dom
$output_variable.value = $input_variable
#Feet to ...
elsif $input_dom == 1 && $output_dom == 2
$output_variable.value = (($input_variable/3.2808)*10000000.0).round()/10000000.0
elsif $input_dom == 1 && $output_dom == 3
$output_variable.value = (($input_variable*12.000)*10000000.0).round()/10000000.0
elsif $input_dom == 1 && $output_dom == 4
$output_variable.value = (($input_variable/0.032808)*10000000.0).round()/10000000.0
elsif $input_dom == 1 && $output_dom == 5
$output_variable.value = (($input_variable/0.00018939)*10000000.0).round()/10000000.0
elsif $input_dom == 1 && $output_dom == 6
$output_variable.value = (($input_variable/3280.8)*10000000.0).round()/10000000.0
#Meters to ...
elsif $input_dom == 2 && $output_dom == 1
$output_variable.value = (($input_variable*3.2808)*10000000.0).round()/10000000.0
elsif $input_dom == 2 && $output_dom == 3
$output_variable.value = (($input_variable*39.370)*10000000.0).round()/10000000.0
elsif $input_dom == 2 && $output_dom == 4
$output_variable.value = (($input_variable/0.010000)*10000000.0).round()/10000000.0
elsif $input_dom == 2 && $output_dom == 5
$output_variable.value = (($input_variable*0.00062137)*10000000.0).round()/10000000.0
elsif $input_dom == 2 && $output_dom == 6
$output_variable.value = (($input_variable/1000.000)*10000000.0).round()/10000000.0
#Inches to ...
elsif $input_dom == 3 && $output_dom == 1
$output_variable.value = (($input_variable*0.083333)*10000000.0).round()/10000000.0
elsif $input_dom == 3 && $output_dom == 2
$output_variable.value = (($input_variable/39.370)*10000000.0).round()/10000000.0
elsif $input_dom == 3 && $output_dom == 4
$output_variable.value = (($input_variable/0.39370)*10000000.0).round()/10000000.0
elsif $input_dom == 3 && $output_dom == 5
$output_variable.value = (($input_variable*0.0000157828281218333)*10000000.0).round()/10000000.0
elsif $input_dom == 3 && $output_dom == 6
$output_variable.value = (($input_variable/39370.0)*10000000.0).round()/10000000.0
#Centimeters to ...
elsif $input_dom == 4 && $output_dom == 1
$output_variable.value = (($input_variable*0.032808)*10000000.0).round()/10000000.0
elsif $input_dom == 4 && $output_dom == 2
$output_variable.value = (($input_variable/100.000)*10000000.0).round()/10000000.0
elsif $input_dom == 4 && $output_dom == 3
$output_variable.value = (($input_variable*0.39370)*10000000.0).round()/10000000.0
elsif $input_dom == 4 && $output_dom == 5
$output_variable.value = (($input_variable*0.0000062137119)*10000000.0).round()/10000000.0
elsif $input_dom == 4 && $output_dom == 6
$output_variable.value = (($input_variable/100000.000)*10000000.0).round()/10000000.0
#miles to...
elsif $input_dom == 5 && $output_dom == 1
$output_variable.value = (($input_variable*5280.0)*10000000.0).round()/10000000.0
elsif $input_dom == 5 && $output_dom == 2
$output_variable.value = (($input_variable/0.00062137)*10000000.0).round()/10000000.0
elsif $input_dom == 5 && $output_dom == 3
$output_variable.value = (($input_variable*63360.000)*10000000.0).round()/10000000.0
elsif $input_dom == 5 && $output_dom == 4
$output_variable.value = (($input_variable/0.0000062137119)*10000000.0).round()/10000000.0
elsif $input_dom == 5 && $output_dom == 6
$output_variable.value = (($input_variable/0.62137)*10000000.0).round()/10000000.0
#kilometers to...
elsif $input_dom == 6 && $output_dom == 1
$output_variable.value = (($input_variable*3280.8)*10000000.0).round()/10000000.0
elsif $input_dom == 6 && $output_dom == 2
$output_variable.value = (($input_variable/0.0010000)*10000000.0).round()/10000000.0
elsif $input_dom == 6 && $output_dom == 3
$output_variable.value = (($input_variable*39370.000)*10000000.0).round()/10000000.0
elsif $input_dom == 6 && $output_dom == 4
$output_variable.value = (($input_variable/0.00001)*10000000.0).round()/10000000.0
elsif $input_dom == 6 && $output_dom == 5
$output_variable.value = (($input_variable*0.62137)*10000000.0).round()/10000000.0
end
rescue
$output_variable.value = ''
end
end
def unit
begin
if $output_dom == 1
$unit.value = 'ft'
elsif $output_dom == 2
$unit.value = 'm'
elsif $output_dom == 3
$unit.value = 'in'
elsif $output_dom == 4
$unit.value = 'cm'
elsif $output_dom == 5
$unit.value = 'mi'
elsif $output_dom == 6
$unit.value = 'km'
end
rescue
$unit.value = ''
end
end
Tk.mainloop
Adding this line (after you've defined $input_variable):
$input_variable.value = 0.0
as well as adding the following lines (after you've defined input_box):
input_box.bind 'Down', lambda {$input_variable.value = $input_variable - 1.0}
input_box.bind 'Up', lambda {$input_variable.value = $input_variable + 1.0}
should get you closer to seeing it work.
See also
this question
about determining things like Down and Up.
Related
What I am trying to do is have a random generator generate 9 cremates and 1 impostor but what happens when it generates them is one of the cremates isn't generated and its just a blank space in between the other string values when I display the values on cmd so idk why it doesn't but I feel it may be to do with the player so there is 10 crews and 1 impostor.
impgen = rand (1..10)
deadgen = rand (1..9)
if impgen == 2
impot = 'Red'
elsif impgen == 3
impot = 'Orange'
elsif impgen == 4
impot = 'Yellow'
elsif impgen == 5
impot = 'Green'
end
if impgen == 6
impot = 'Dark Green'
elsif impgen == 7
impot = 'Blue'
elsif impgen == 8
impot = 'Purple'
elsif impgen == 9
impot = 'Black'
elsif impgen == 10
impot = 'Cyan'
end
if impgen != 2
crew1 = 'Red'
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
end
end
end
end
puts "Enter Name"
un = gets.chomp
puts "Ok " + un + " let's play Among Us"
sleep (1)
if impgen == 1
puts "You are an imposter!"
else impgen
puts "You are a crewmate there is 1 imposter among us!"
sleep (1.5)
puts "The other players are Red, Orange, Yellow, Green, Dark Green, Blue, Purple, Black, and Cyan you are Lime"
sleep (4)
puts impot
puts crew1
puts crew2
puts crew3
puts crew4
puts crew5
puts crew6
puts crew7
puts crew8
puts crew9
end
I think the biggest issue becomes apparent when you indent your code:
if impgen != 2
crew1 = 'Red'
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
end
end
end
end
There is a major bug here. For example, if impgen == 2, then none of the following code will get executed, and none of the crew variables will be assigned. You probably don't want to use nested if statements here, but instead do something like this:
if impgen != 2
crew1 = 'Red'
end
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
end
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
end
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
end
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
If you just make this change, you'll see that there is a consistent empty line that appears in the output. The reasoning is pretty clear, the imposter's crew member variable isn't getting assigned when impgen is a certain value. For example, if impgen is 2, impgen != 2 evaluates to false, and crew1 = 'Red' doesn't get executed.
If this behavior is undesirable, you can just drop the if statements completely:
crew1 = 'Red'
crew2 = 'Orange'
crew3 = 'Yellow'
crew4 = 'Green'
crew5 = 'Dark Green'
crew6 = 'Blue'
crew7 = 'Purple'
crew8 = 'Black'
crew9 = 'Cyan'
Edit:
You may want to consider refactoring this code. I'm not sure how you plan to use your crew mate variables, but it might be easier to keep track of each member in an array:
crew_members = ["Red", "Orange", "Yellow", "Green", "Dark Green", "Blue", "Purple", "Black", "Cyan"]
player = crew_members.sample
imposter = crew_members.sample
puts "Enter Name"
un = gets.chomp
puts "Ok " + un + " let's play Among Us"
sleep (1)
if player == imposter
puts "You are an imposter!"
else
puts "You are a crewmate there is 1 imposter among us!"
sleep (1.5)
puts "The other players are #{(crew_members - [player]).join(", ")} you are #{player}"
end
I'm having trouble with my code here what it's supposed to do is generate a number from 1 to 6 and than ask you who you think the imposter is after it asks you it waits for input and than checks for the input and the random number that was generated if the input is Red and the random number was 1 it would say that red is the imposter and so on with Orange and 2 Green and 3 Yelow and 4 Cyan with 5 and Black with 6 but the problem is that if you put anything that isn't red EX: Orange it just stops for no reason. What did I do wrong with the code? Please help.
susas = rand (1..6)
puts "Who is the imposter?"
sleep (1)
puts "Is it Red, Orange, Green, Yellow, Cyan, Or Black (use capital format EX:Red)"
answr = gets.chomp
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
if answr == "Orange" && susas == 2
puts "Orange was the imposter"
elsif answr == "Orange" && susas != 2
puts "Orange was not the imposter you failed"
if answr == "Green" && susas == 3
puts "Green was the imposter"
elsif answr == "Green" && susas != 3
puts "Green was not the imposter you failed"
if answr == "Yellow" && susas == 4
puts "Yellow was the imposter"
elsif answr == "Yellow" && susas != 4
puts "Yellow was not the imposter you failed"
if answr == "Cyan" && susas == 5
puts "Cyan was the imposter"
elsif answr == "Cyan" && susas != 5
puts "Cyan was not the imposter you failed"
if answr == "Black" && susas == 6
puts "Black was the imposter"
elsif answr == "Black" && susas != 6
puts "Black was not the imposter you failed"
end
end
end
end
end
end
Here is a repl.it link https://repl.it/#Student_Aiden_K/SmoothFaithfulComputerscience#main.rb
if you put anything that isn't red EX: Orange it just stops for no reason. What did I do wrong with the code?
You have two main branches:
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
# anything else
end
The other colors are all under the elsif branch but Ruby will not reach them because answr == "Red" will be false for all colors beside red.
What you want is more elsif's on the same level:
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
elsif answr == "Orange" && susas == 2
puts "Orange was the imposter"
elsif answr == "Orange" && susas != 2
puts "Orange was not the imposter you failed"
# ...
end
Needless to say, there's a lot of repetition in your code. You should try to reduce that.
You could for example add a hash to map color names to numbers:
colors = {
'Red' => 1, 'Orange' => 2, 'Green' => 3,
'Yellow' => 4, 'Cyan' => 5, 'Black' => 6
}
Then fetch the number for the given answer:
answer = gets.chomp
number = colors[answer]
And have just one if to check whether it is correct or not:
if number == susas
puts "#{answer} was the imposter"
else
puts "#{answer} was not the imposter you failed"
end
According to this tutorial, I only need one end statement for the if, elsif, and else loop:
def dasherize_number(num)
nums = num.to_s
final_string = ''
i = 0
while i < nums.length
if i == 0
final_string += nums[i]
if nums[i].to_i % 2 == 1
final_string += '-'
end
elsif i == nums.length
final_string += nums[i]
else
if i % 2 == 1
final_string += '-'
final_string += nums[i]
end
end
i += 1
end
puts final_string
end
Why do there need to be two end statement between i += 1?
Indentation is important:
def dasherize_number(num)
nums = num.to_s
final_string = ''
i = 0
while i < nums.length
if i == 0
final_string += nums[i]
if nums[i].to_i % 2 == 1
final_string += '-'
end
elsif i == nums.length
final_string += nums[i]
else
if i % 2 == 1
final_string += '-'
final_string += nums[i]
end
end
i += 1
end
puts final_string
end
After a good 10 minutes of trying to come up with a more informative title, I ran out of ideas.
I have 2 prolems. The first is that whenever I try to input a position for pos_in, it registers as nul when run through the case statement that determines what m_index will be for that turn.
The second is that whenever the AI takes a turn, it always selects 1 1.
My question is: is there some way to fix this? I've tried switching the input types to no avail and I'm completely clueless on what to do.
My code:
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
possiblesx = (1..3)
possiblesy = (1..3)
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3, 6] == "x" || $spots[4, 8] == "x" || $spots[1, 2] == "x"
pos_in = "1 1"
elsif $spots[1, 3] == "x" || $spots[4, 7] == "x"
pos_in = "1 2"
elsif $spots[0, 1] == "x" || $spots[6, 4] == "x" || $spots[5, 8] == "x"
pos_in = "1 3"
elsif $spots[0, 6] == "x" || $spots[4, 5] == "x"
pos_in = "2 1"
elsif $spots[0, 8] == "x" || $spots[1, 7] == "x" || $spots[2, 6] == "x" || $spots[5, 3] == "x"
pos_in = "2 2"
elsif $spots[2, 8] == "x" || $spots[3, 4] == "x"
pos_in = "2 3"
elsif $spots[0, 3] == "x" || $spots[2, 4] == "x" || $spots[7, 8] == "x"
pos_in = "3 1"
elsif $spots[1, 4] == "x" || $spots[6, 8] == "x"
pos_in = "3 2"
elsif $spots[6, 7] == "x" || $spots[0, 4] == "x" || $spots[2, 5] == "x"
pos_in = "3 3"
else
aimx = possiblesx.to_a.sample
aimy = possiblesy.to_a.sample
pos_in = "#{aimx} #{aimy}"
end
end
def game
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
pos_in = gets.chomp
end
case pos_in
when ["1 1"]
m_index = 0
when ["1 2"]
m_index = 1
when ["1 3"]
m_index = 2
when ["2 1"]
m_index = 3
when ["2 2"]
m_index = 4
when ["2 3"]
m_index = 5
when ["3 1"]
m_index = 6
when ["3 2"]
m_index = 7
when ["3 3"]
m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter $move."
sleep(3)
system "cls"
$move = c_$move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend or [2]AI"
$opp = gets.to_i
game
The problem you had was with your scoping, along with the fact you were trying to match a string to an array as Piotr Kruczek pointed out.
Make the pos_in variable global and change the when statements from an array input to a string.
Here is the working version of your code:
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
$pos_in = nil
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3, 6] == "x" || $spots[4, 8] == "x" || $spots[1, 2] == "x"
$pos_in = "1 1"
elsif $spots[1, 3] == "x" || $spots[4, 7] == "x"
$pos_in = "1 2"
elsif $spots[0, 1] == "x" || $spots[6, 4] == "x" || $spots[5, 8] == "x"
$pos_in = "1 3"
elsif $spots[0, 6] == "x" || $spots[4, 5] == "x"
$pos_in = "2 1"
elsif $spots[0, 8] == "x" || $spots[1, 7] == "x" || $spots[2, 6] == "x" || $spots[5, 3] == "x"
$pos_in = "2 2"
elsif $spots[2, 8] == "x" || $spots[3, 4] == "x"
$pos_in = "2 3"
elsif $spots[0, 3] == "x" || $spots[2, 4] == "x" || $spots[7, 8] == "x"
$pos_in = "3 1"
elsif $spots[1, 4] == "x" || $spots[6, 8] == "x"
$pos_in = "3 2"
elsif $spots[6, 7] == "x" || $spots[0, 4] == "x" || $spots[2, 5] == "x"
$pos_in = "3 3"
else
aimx = (1..3).to_a.sample
aimy = (1..3).to_a.sample
$pos_in = "#{aimx} #{aimy}"
end
end
def game
m_index = nil
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
$pos_in = gets.chomp
end
case $pos_in
when "1 1"
p m_index = 0
when "1 2"
p m_index = 1
when "1 3"
p m_index = 2
when "2 1"
p m_index = 3
when "2 2"
p m_index = 4
when "2 3"
p m_index = 5
when "3 1"
p m_index = 6
when "3 2"
p m_index = 7
when "3 3"
p m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter $move."
sleep(3)
system "cls"
$move = c_$move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend or [2]AI"
$opp = gets.to_i
game
You assign
pos_in = "1 1"
as a String, while in you case statement you check for Array
case pos_in
when ["1 1"]
As Stated by Piotr and Menelik, there were a few obvious errors in this. Oddly enough, the structure of ai_move was one of those. The working code is as follows. It's not the cleanest thing ever and there are some bugs to iron out but it does it's job.
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = Array.new(9, " ")
$possiblesx = [1, 2, 3]
$possiblesy = [1, 2, 3]
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3] == "x" && $spots[6] == "x"
$pos_in = "1 1"
elsif $spots[4] == "x" && $spots[8] == "x"
$pos_in = "1 1"
elsif $spots[1] == "x" && $spots[2] == "x"
$pos_in = "1 1"
elsif $spots[1] == "x" && $spots[3] == "x"
$pos_in = "1 2"
elsif $spots[4] == "x" && $spots[7] == "x"
$pos_in = "1 2"
elsif $spots[0] == "x" && $spots[1] == "x"
$pos_in = "1 3"
elsif $spots[6] == "x" && $spots[4] == "x"
$pos_in = "1 3"
elsif $spots[5] == "x" && $spots[8] == "x"
$pos_in = "1 3"
elsif $spots[0] == "x" && $spots[6] == "x"
$pos_in = "2 1"
elsif $spots[4] == "x" && $spots[5] == "x"
$pos_in = "2 1"
elsif $spots[0] == "x" && $spots[8] == "x"
$pos_in = "2 2"
elsif $spots[1] == "x" && $spots[7] == "x"
$pos_in = "2 2"
elsif $spots[2] == "x" && $spots[6] == "x"
$pos_in = "2 2"
elsif $spots[5] == "x" && $spots[3] == "x"
$pos_in = "2 2"
elsif $spots[2] == "x" && $spots[8] == "x"
$pos_in = "2 3"
elsif $spots[3] == "x" && $spots[4] == "x"
$pos_in = "2 3"
elsif $spots[0] == "x" && $spots[3] == "x"
$pos_in = "3 1"
elsif $spots[2] == "x" && $spots[4] == "x"
$pos_in = "3 1"
elsif $spots[7] == "x" && $spots[8] == "x"
$pos_in = "3 1"
elsif $spots[1] == "x" && $spots[4] == "x"
$pos_in = "3 2"
elsif $spots[6] == "x" && $spots[8] == "x"
$pos_in = "3 2"
elsif $spots[6] == "x" && $spots[7] == "x"
$pos_in = "3 3"
elsif $spots[0] == "x" && $spots[4] == "x"
$pos_in = "3 3"
elsif $spots[2] == "x" && $spots[5] == "x"
$pos_in = "3 3"
else
aimx = $possiblesx.sample
aimy = $possiblesy.sample
$pos_in = "#{aimx} #{aimy}"
end
end
def game
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
$pos_in = gets.chomp
end
case $pos_in
when "1 1"
m_index = 0
when "1 2"
m_index = 1
when "1 3"
m_index = 2
when "2 1"
m_index = 3
when "2 2"
m_index = 4
when "2 3"
m_index = 5
when "3 1"
m_index = 6
when "3 2"
m_index = 7
when "3 3"
m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter move."
sleep(3)
system "cls"
$move = $c_move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend [2]AI"
$opp = gets.to_i
game
I have this if statement:
if value_n_in_f > 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}"
elsif value_n_in_f == 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x"
elsif value_n_in_f < 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x#{value_n_in_f}"
elsif value_n_in_f > 0 && value_m_in_f == 1
puts "I: f(x)=x+#{value_n_in_f}"
elsif value_n_in_f == 0 && value_m_in_f == 1
puts "I: f(x)=x"
elsif value_n_in_f < 0 && value_m_in_f == 1
puts "I: f(x)=x#{value_n_in_f}"
end`
I have to use this statement really often in other statements and it makes my code unnecessarily long. Obviously if_for_f=if ....... end won't work. Is there any other way?
Here's an example what I want it to look like:
puts "Now we insert #{value_of_x} in #{if_for_f}"
Is there any way I can do something like this? Note that I am absolutly new to this.
Thanks in advance,
Kaiton
can't I just def a function with its function to run this case
statement and call it then when I need it it?
Of course:
def do_stuff(m, n)
if m == 1
if n > 0 then "I: f(x)=x+#{n}"
elsif n == 0 then "I: f(x)=x"
elsif n < 0 then "I: f(x)=x#{n}"
end
else
if n > 0 then "I: f(x)=#{m}x+#{n}"
elsif n == 0 then "I: f(x)=#{m}x"
elsif n < 0 then "I: f(x)=#{m}x#{n}"
end
end
end
puts do_stuff(1, 1) #I: f(x)=x+1
Or, if compactness is the goal, we can get to this:
def do_stuff(m, n)
if m == 1
n == 0 ? "I: f(x)=x" : "I: f(x)=x#{sprintf("%+d", n)}"
else
n == 0 ? "I: f(x)=#{m}x" : "I: f(x)=#{m}x#{sprintf("%+d", n)}"
end
end
...and then a one liner:
def do_stuff(m, n)
(m == 1) ? (n == 0 ? "I: f(x)=x" : "I: f(x)=x#{sprintf("%+d", n)}") : (n == 0 ? "I: f(x)=#{m}x" : "I: f(x)=#{m}x#{sprintf("%+d", n)}")
end
end
But your methodology has some problems with zeros and -1:
def do_stuff(value_m_in_f, value_n_in_f)
if value_n_in_f > 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}"
elsif value_n_in_f == 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x"
elsif value_n_in_f < 0 && value_m_in_f != 1
puts "I: f(x)=#{value_m_in_f}x#{value_n_in_f}"
elsif value_n_in_f > 0 && value_m_in_f == 1
puts "I: f(x)=x+#{value_n_in_f}"
elsif value_n_in_f == 0 && value_m_in_f == 1
puts "I: f(x)=x"
elsif value_n_in_f < 0 && value_m_in_f == 1
puts "I: f(x)=x#{value_n_in_f}"
end
end
do_stuff(1, 0)
do_stuff(1,-1)
do_stuff(1, 1)
do_stuff(0,-1)
do_stuff(0, 0)
do_stuff(-1, 1)
--output:--
I: f(x)=x
I: f(x)=x-1
I: f(x)=x+1
I: f(x)=0x-1 #<---HERE
I: f(x)=0x #<---HERE
I: f(x)=-1x+1 #<---HERE
So let's fix that:
def get_line_equ(m, b)
constant = (b == 0) ? "" : sprintf("%+d", b) # 2 => "+2"
case m
when 0
xterm = ""
constant = b
when 1
xterm = "x"
when -1
xterm = "-x"
else
xterm = "#{m}x"
end
"I: f(x)=#{xterm}#{constant}"
end
puts get_line_equ(0, 0)
puts get_line_equ(0, -1)
puts get_line_equ(0, 1)
puts get_line_equ(1, 0)
puts get_line_equ(1,-1)
puts get_line_equ(1, 1)
puts get_line_equ(-1, 0)
puts get_line_equ(-1, -1)
puts get_line_equ(-1, 1)
puts get_line_equ(2, 0)
puts get_line_equ(2, -1)
puts get_line_equ(2, 1)
--output:--
I: f(x)=0
I: f(x)=-1
I: f(x)=1
I: f(x)=x
I: f(x)=x-1
I: f(x)=x+1
I: f(x)=-x
I: f(x)=-x-1
I: f(x)=-x+1
I: f(x)=2x
I: f(x)=2x-1
I: f(x)=2x+1
Better?
spoiler:
The final def is not as efficient as it could be: the first line should be removed and copied to each of the when branches--except for the first.
In response to comment:
def my_sprintf(str, *numbers)
str.gsub(/% .*? [df]/x) do |match| #Looks for %...d or %...f sequences
puts match
end
end
my_sprintf("The answer is: %+d or %+d", -2, 3)
--output:--
%+d
%+d
Next:
def my_sprintf(str, *numbers)
str.gsub(/% .*? [df]/x) do |format_sequ|
number_as_str = numbers.shift.to_s
p number_as_str
if format_sequ[1] == "+" and number_as_str[0] != "-"
"+#{number_as_str}"
else
number_as_str
end
end
end
puts my_sprintf("The answer is: %+d or %+d.", -2, 3)
--output:--
"-2"
"3"
The answer is: -2 or +3.
Here's a more compact way to write your case statement. Recall that a <=> b => -1 if a < b, a <=> b => 0 if a == b and a <=> b => -1 if a > b.
"I: f(x)=" +
case [value_n_in_f <=> 0, value_m_in_f == 1]
when [ 1,false] then "#{value_m_in_f}x+#{value_n_in_f}"
when [ 0,false] then "#{value_m_in_f}x"
when [-1,false] then "#{value_m_in_f}x#{value_n_in_f}"
when [ 1,true] then "x+#{value_n_in_f}"
when [ 0,true] then "x"
when [-1,true] then "x#{value_n_in_f}"
end
If you wish to demonstrate how the string is built, you could do something like this (with value_n_in_f and value_m_in_f renamed intercept and slope, respectively):
"I: f(x)=" +
case
when slope.zero?
intercept.zero? ? "0" : "#{intercept}"
else
case slope.to_f
when 1.0 then ""
when -1.0 then "-"
else "#{slope}"
end + "x" +
case intercept <=> 0
when 0 then ""
when -1 then "#{intercept}"
else "+#{intercept}"
end
end
Note that this permits slope < 0, which is not part of the specification. I tested this for various combinations of intercept and slope:
intercept slope string
-2.1 4 I: f(x)=4x-2.1
-2.1 -2.2 I: f(x)=-2.2x-2.1
-2.1 0 I: f(x)=-2.1
-2.1 0.0 I: f(x)=-2.1
-2.1 -1 I: f(x)=-x-2.1
-2.1 1.0 I: f(x)=x-2.1
0 4 I: f(x)=4x
0 -2.2 I: f(x)=-2.2x
0 0 I: f(x)=0
0 0.0 I: f(x)=0
0 -1 I: f(x)=-x
0 1.0 I: f(x)=x
0.0 4 I: f(x)=4x
0.0 -2.2 I: f(x)=-2.2x
0.0 0 I: f(x)=0
0.0 0.0 I: f(x)=0
0.0 -1 I: f(x)=-x
0.0 1.0 I: f(x)=x
3 4 I: f(x)=4x+3
3 -2.2 I: f(x)=-2.2x+3
3 0 I: f(x)=3
3 0.0 I: f(x)=3
3 -1 I: f(x)=-x+3
3 1.0 I: f(x)=x+3
A couple of things here: you can put "puts" before the whole if/elsif block and avoid having puts on every line, like so:
puts case
when (value_n_in_f > 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}"
when (value_n_in_f == 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x"
end
Second, a case statement would be much more readable, like so:
def big_compare(value_n_in_f, value_m_in_f)
msg = case
when (value_n_in_f > 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x+#{value_n_in_f}"
when (value_n_in_f == 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x"
when (value_n_in_f < 0 && value_m_in_f != 1) then "I: f(x)=#{value_m_in_f}x#{value_n_in_f}"
when (value_n_in_f > 0 && value_m_in_f == 1) then "I: f(x)=x+#{value_n_in_f}"
when (value_n_in_f == 0 && value_m_in_f == 1) then "I: f(x)=x"
when (value_n_in_f < 0 && value_m_in_f == 1) then "I: f(x)=x#{value_n_in_f}"
end
end
puts big_compare(0, 0)