Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #3971 > unrolled thread
| Started by | Super Goat <ruby-forum@sgoat.33mail.com> |
|---|---|
| First post | 2011-05-05 01:45 -0500 |
| Last post | 2011-05-09 00:29 -0500 |
| Articles | 20 — 8 participants |
Back to article view | Back to comp.lang.ruby
Lets play a guessing game. (how to code this better?) Super Goat <ruby-forum@sgoat.33mail.com> - 2011-05-05 01:45 -0500
Re: Lets play a guessing game. (how to code this better?) Stu <stu@rubyprogrammer.net> - 2011-05-05 02:28 -0500
Re: Lets play a guessing game. (how to code this better?) Josh Cheek <josh.cheek@gmail.com> - 2011-05-05 02:51 -0500
Re: Lets play a guessing game. (how to code this better?) John Feminella <johnf@bitsbuilder.com> - 2011-05-05 03:10 -0500
Re: Lets play a guessing game. (how to code this better?) Johannes Held <johannes.held@informatik.uni-erlangen.de> - 2011-05-06 10:51 +0200
Re: Lets play a guessing game. (how to code this better?) Johnny Morrice <spoon@killersmurf.com> - 2011-05-06 07:01 -0500
Re: Lets play a guessing game. (how to code this better?) Johnny Morrice <spoon@killersmurf.com> - 2011-05-06 07:04 -0500
Re: Lets play a guessing game. (how to code this better?) Johannes Held <johannes.held@informatik.uni-erlangen.de> - 2011-05-06 14:13 +0200
Re: Lets play a guessing game. (how to code this better?) Johnny Morrice <spoon@killersmurf.com> - 2011-05-06 07:23 -0500
Re: Lets play a guessing game. (how to code this better?) Jesús Gabriel y Galán <jgabrielygalan@gmail.com> - 2011-05-05 03:56 -0500
Re: Lets play a guessing game. (how to code this better?) Martin Boese <boesemar@gmx.de> - 2011-05-05 10:32 -0500
Re: Lets play a guessing game. (how to code this better?) Super Goat <ruby-forum@sgoat.33mail.com> - 2011-05-06 01:18 -0500
Re: Lets play a guessing game. (how to code this better?) Jesús Gabriel y Galán <jgabrielygalan@gmail.com> - 2011-05-06 02:27 -0500
Re: Lets play a guessing game. (how to code this better?) Josh Cheek <josh.cheek@gmail.com> - 2011-05-06 02:34 -0500
Re: Lets play a guessing game. (how to code this better?) Super Goat <ruby-forum@sgoat.33mail.com> - 2011-05-08 00:08 -0500
Re: Lets play a guessing game. (how to code this better?) Josh Cheek <josh.cheek@gmail.com> - 2011-05-08 00:30 -0500
Re: Lets play a guessing game. (how to code this better?) Stu <stu@rubyprogrammer.net> - 2011-05-08 01:16 -0500
Re: Lets play a guessing game. (how to code this better?) Stu <stu@rubyprogrammer.net> - 2011-05-08 02:22 -0500
Re: Lets play a guessing game. (how to code this better?) Super Goat <ruby-forum@sgoat.33mail.com> - 2011-05-08 21:20 -0500
Re: Lets play a guessing game. (how to code this better?) Stu <stu@rubyprogrammer.net> - 2011-05-09 00:29 -0500
| From | Super Goat <ruby-forum@sgoat.33mail.com> |
|---|---|
| Date | 2011-05-05 01:45 -0500 |
| Subject | Lets play a guessing game. (how to code this better?) |
| Message-ID | <60cd2d7685f4d805fa7b7b953b5667d5@ruby-forum.com> |
I am a new Rubyist. I told my friend that I was learning Ruby. He asked me how that was going and then gave me a little challenge. His challenge, "Write a text game that guesses numbers 0-100". My reply, "you mean it picks a number at random, and you guess the number, it tells you higher or lower until you get it?". Up to this point I had not coded anything in Ruby on my own (aside from the examples in the book) and I saw this as a great first challenge. So here is what I got. It took me some time. I ran into trouble because I forgot to take into consideration the Class of the variables and couldn't figure out why the loops weren't working. My question to you all... how could I have done this better or do you seeing anything that is wrong. Attached is the code. Thanks for the feedback. Attachments: http://www.ruby-forum.com/attachment/6168/100guess.rb -- Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | Stu <stu@rubyprogrammer.net> |
|---|---|
| Date | 2011-05-05 02:28 -0500 |
| Message-ID | <BANLkTim-F1KCtdmSfjv6sij23cFSd04pkg@mail.gmail.com> |
| In reply to | #3971 |
Looks good. You don't need the extra call to_i where it is already an integer: random = rand(100) choice == random Both expressions are fine without any castiing. small nit pick. ruby is on my machine in /usr/local/bin ... to make this portable use: #!/usr/bin/env ruby I suggest your next task is to break everything down to methods. When you get comfortable with the concept of methods make your user input more strict as to only acquire a number. You did a very good job, Keep it going. ~Stu On Thu, May 5, 2011 at 1:45 AM, Super Goat <ruby-forum@sgoat.33mail.com> wrote: > I am a new Rubyist. I told my friend that I was learning Ruby. He asked > me how that was going and then gave me a little challenge. His > challenge, "Write a text game that guesses numbers 0-100". My reply, > "you mean it picks a number at random, and you guess the number, it > tells you higher or lower until you get it?". Up to this point I had not > coded anything in Ruby on my own (aside from the examples in the book) > and I saw this as a great first challenge. So here is what I got. It > took me some time. I ran into trouble because I forgot to take into > consideration the Class of the variables and couldn't figure out why the > loops weren't working. > My question to you all... how could I have done this better or do you > seeing anything that is wrong. Attached is the code. Thanks for the > feedback. > > Attachments: > http://www.ruby-forum.com/attachment/6168/100guess.rb > > > -- > Posted via http://www.ruby-forum.com/. > >
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-05-05 02:51 -0500 |
| Message-ID | <BANLkTikk-CX2fSswa=WtzVeayk2F6V2JCg@mail.gmail.com> |
| In reply to | #3971 |
[Note: parts of this message were removed to make it a legal post.]
On Thu, May 5, 2011 at 1:45 AM, Super Goat <ruby-forum@sgoat.33mail.com>wrote:
> I am a new Rubyist. I told my friend that I was learning Ruby. He asked
> me how that was going and then gave me a little challenge. His
> challenge, "Write a text game that guesses numbers 0-100". My reply,
> "you mean it picks a number at random, and you guess the number, it
> tells you higher or lower until you get it?". Up to this point I had not
> coded anything in Ruby on my own (aside from the examples in the book)
> and I saw this as a great first challenge. So here is what I got. It
> took me some time. I ran into trouble because I forgot to take into
> consideration the Class of the variables and couldn't figure out why the
> loops weren't working.
> My question to you all... how could I have done this better or do you
> seeing anything that is wrong. Attached is the code. Thanks for the
> feedback.
>
> Attachments:
> http://www.ruby-forum.com/attachment/6168/100guess.rb
>
>
Hi, Super Goat :)
Congratulations on your first program! Hope you're enjoying Ruby.
Here are some thoughts, that might be helpful:
* On line1 your shebang is `#!/usr/bin/ruby`, but the best shebang is
`#!/usr/bin/env ruby` because Ruby can be located in lots of different
places, but env is always (I think) located in /usr/bin/env, and it is smart
enough to figure out where your real Ruby is and then invoke it.
* On line 4, you have `rand(100).to_i`, rand already returns an integer when
you pass it a parameter, so you don't need to use to_i on it (
http://www.ruby-doc.org/core/classes/Kernel.html#M001388)
* For that variable, I would have probably named it "target" rather than
"random", I think this clearer.
* On line 11, `if choice > random.to_i` again you are converting it to an
integer, but it is already an integer. (not harmful, but redundant and thus
confusing as it makes reader say "wait, I thought it was an integer already,
what did I miss?")
* Lines 13-14 look like this:
if choice > random.to_i
puts "\nIncorrect, please choose a lower number."
else puts "\nIncorrect, please choose a higher number."
end
Your indenting is off, the if/else/end should be at the same level, and for
multiline conditionals, the code would go between them, so it should look
like this:
if choice > target
puts "\nIncorrect, please choose a lower number."
else
puts "\nIncorrect, please choose a higher number."
end
I would personally probably save space by putting the conditional into the
string like this:
puts "\nIncorrect, please choose a #{if choice > target then 'higher' else
'lower' end} number"
I'm not sure whether many other Rubyists would do that or not, but I like it
much better.
* On line 16, you have gets.chomp.to_i The chomp here is unnecessary,
because to_i will disregard anything after the digit.
---
Anyway, nice job. Keep it up, after you get comfortable with the language,
you can play with gems, which is where all the fun stuff is!
[toc] | [prev] | [next] | [standalone]
| From | John Feminella <johnf@bitsbuilder.com> |
|---|---|
| Date | 2011-05-05 03:10 -0500 |
| Message-ID | <BANLkTi=kWUQq1RgFpra6ecCB_YSEhT78aQ@mail.gmail.com> |
| In reply to | #3971 |
There's a small bug: ==== puts "Choose a number between 0 and 100" random = rand(100).to_i ==== This actually produces numbers between 0 and 99 inclusive, not 0 and 100. Also the name "random" doesn't describe the point of the variable in the program, which is to serve as the answer. So it might be better to call it "answer", for instance. Finally, `rand(100)` already produces an integer, so you don't need the .to_i method. Also, for this condition, ==== until choice <= 100 and choice >= 0 ==== a more succinct way of writing this is to check if it's included in the range 0..100: ==== until (0..100).include? choice ==== Next, notice that "100" appears a lot, so it might be better to describe what that number is -- it's the maximum value that your random number can take on. So, w emight write: ==== max = 100 ==== and then use `max` everywhere instead of the `100` literal. Otherwise, looks good overall for your first attempt at this, minus a few rough spots. For another challenge, you might try writing a program that can guess a number between 0 and 100 in as few guesses as possible (hint: it should take around 7 guesses). ~ jf -- John Feminella Principal Consultant, BitsBuilder LI: http://www.linkedin.com/in/johnxf SO: http://stackoverflow.com/users/75170/ On Thu, May 5, 2011 at 02:45, Super Goat <ruby-forum@sgoat.33mail.com> wrote: > I am a new Rubyist. I told my friend that I was learning Ruby. He asked > me how that was going and then gave me a little challenge. His > challenge, "Write a text game that guesses numbers 0-100". My reply, > "you mean it picks a number at random, and you guess the number, it > tells you higher or lower until you get it?". Up to this point I had not > coded anything in Ruby on my own (aside from the examples in the book) > and I saw this as a great first challenge. So here is what I got. It > took me some time. I ran into trouble because I forgot to take into > consideration the Class of the variables and couldn't figure out why the > loops weren't working. > My question to you all... how could I have done this better or do you > seeing anything that is wrong. Attached is the code. Thanks for the > feedback. > > Attachments: > http://www.ruby-forum.com/attachment/6168/100guess.rb > > > -- > Posted via http://www.ruby-forum.com/. > >
[toc] | [prev] | [next] | [standalone]
| From | Johannes Held <johannes.held@informatik.uni-erlangen.de> |
|---|---|
| Date | 2011-05-06 10:51 +0200 |
| Message-ID | <92hr2kFplbU1@mid.dfncis.de> |
| In reply to | #3974 |
On 05.05.2011 10:10, John Feminella wrote: > For another challenge, you might try writing a program that can guess > a number between 0 and 100 in as few guesses as possible (hint: it > should take around 7 guesses). Ah, that's a nice challenge. You could even try to solve it with the functional pradigm. In this case: recursion! http://pastie.org/1870939 -- Johannes
[toc] | [prev] | [next] | [standalone]
| From | Johnny Morrice <spoon@killersmurf.com> |
|---|---|
| Date | 2011-05-06 07:01 -0500 |
| Message-ID | <20110506130036.138b5255@beastie> |
| In reply to | #4028 |
> You could even try to solve it with the functional pradigm.
That's not functional enough for me ;)
In case the syntax gets chewed: http://pastie.org/1871414
# Z combinator defines explicit recursion
Z = lambda { |f| (lambda {|x| f.call(lambda {|*ys|
x.call(x).call(*ys)})}).call(lambda {|x| f.call(lambda {|*ys|
x.call(x).call(*ys)})})}
# The guess combinator holds a reference to itself in the 'again'
variable Guess = lambda do |again|
lambda do |magic|
print "Choose 0-100> "
n = gets.to_i
if !(0..100).include?(n)
puts "0-100!"
next
end
puts "Higher!" if n<magic
puts "Lower!" if n>magic
if n==magic
puts "You won: #{magic} is the number!"
else
again.call magic
end
end
end
magic = rand(101).to_i
puts "Guess the magic number!"
Z.call(Guess).call(magic)
Clearly this is the most obvious solution.
Cheers,
Johnny
[toc] | [prev] | [next] | [standalone]
| From | Johnny Morrice <spoon@killersmurf.com> |
|---|---|
| Date | 2011-05-06 07:04 -0500 |
| Message-ID | <20110506130346.19c395b4@beastie> |
| In reply to | #4032 |
Actually I left a bug in that due to side effects. (When will lazy
functional ruby be out?)
Here you go:
# I have defined the combinators as constants to reflect the TRUTH and
PURITY of COMPUTER SCIENCE
# Z combinator defines explicit recursion
Z = lambda { |f| (lambda {|x| f.call(lambda {|*ys|
x.call(x).call(*ys)})}).call(lambda {|x| f.call(lambda {|*ys|
x.call(x).call(*ys)})})}
# The guess combinator holds a reference to itself in the 'again'
variable Guess = lambda do |again|
lambda do |magic|
print "Choose 0-100> "
n = gets.to_i
if (0..100).include?(n)
puts "Higher!" if n<magic
puts "Lower!" if n>magic
if n==magic
puts "You won: #{magic} is the number!"
else
again.call magic
end
else
puts "0-100!"
again.call magic
end
end
end
magic = rand(101).to_i
puts "Guess the magic number!"
Z.call(Guess).call(magic)
[toc] | [prev] | [next] | [standalone]
| From | Johannes Held <johannes.held@informatik.uni-erlangen.de> |
|---|---|
| Date | 2011-05-06 14:13 +0200 |
| Message-ID | <92i6t4Fnh2U1@mid.dfncis.de> |
| In reply to | #4032 |
On 06.05.2011 14:01, Johnny Morrice wrote: > That's not functional enough for me;) And now, the OP is frightenend of functional programming … ;-) You may provide functional code for the machine-solver, too. -- Johannes
[toc] | [prev] | [next] | [standalone]
| From | Johnny Morrice <spoon@killersmurf.com> |
|---|---|
| Date | 2011-05-06 07:23 -0500 |
| Message-ID | <20110506132330.49a31210@beastie> |
| In reply to | #4034 |
> And now, the OP is frightenend of functional programming … ;-) Good point. Please OP, for the love of all things computery do not code like me.
[toc] | [prev] | [next] | [standalone]
| From | Jesús Gabriel y Galán <jgabrielygalan@gmail.com> |
|---|---|
| Date | 2011-05-05 03:56 -0500 |
| Message-ID | <BANLkTimxFoqDRr90Y9=X=oL1STUcvHrC9g@mail.gmail.com> |
| In reply to | #3971 |
On Thu, May 5, 2011 at 8:45 AM, Super Goat <ruby-forum@sgoat.33mail.com> wrote:
> I am a new Rubyist. I told my friend that I was learning Ruby. He asked
> me how that was going and then gave me a little challenge. His
> challenge, "Write a text game that guesses numbers 0-100". My reply,
> "you mean it picks a number at random, and you guess the number, it
> tells you higher or lower until you get it?". Up to this point I had not
> coded anything in Ruby on my own (aside from the examples in the book)
> and I saw this as a great first challenge. So here is what I got. It
> took me some time. I ran into trouble because I forgot to take into
> consideration the Class of the variables and couldn't figure out why the
> loops weren't working.
> My question to you all... how could I have done this better or do you
> seeing anything that is wrong. Attached is the code. Thanks for the
> feedback.
>
> Attachments:
> http://www.ruby-forum.com/attachment/6168/100guess.rb
Apart from the other comments, I would like to point out that the
check about the choice being a valid number (between 0 and 100) is
made only for the first choice. After the first incorrect choice, you
already inside the second loop, and don't check again.
My advice is to create a method that contains that logic: outputting a
prompt, getting the input from the user and validating it, the code
would get much cleaner:
def get_valid_input
# the prompt and validation logic here
end
target = rand(100)
until (choice = get_valid_input) == target
puts "Wrong, my number is #{choice < target ? 'higher' : 'lower'}"
end
Or something like that.
Jesus.
[toc] | [prev] | [next] | [standalone]
| From | Martin Boese <boesemar@gmx.de> |
|---|---|
| Date | 2011-05-05 10:32 -0500 |
| Message-ID | <20110505163204.70927e77@ita-martin> |
| In reply to | #3971 |
On Thu, 5 May 2011 15:45:52 +0900
Super Goat <ruby-forum@sgoat.33mail.com> wrote:
> I am a new Rubyist. I told my friend that I was learning Ruby. He
> asked me how that was going and then gave me a little challenge. His
> challenge, "Write a text game that guesses numbers 0-100". My reply,
> "you mean it picks a number at random, and you guess the number, it
> tells you higher or lower until you get it?". Up to this point I had
> not coded anything in Ruby on my own (aside from the examples in the
> book) and I saw this as a great first challenge. So here is what I
> got. It took me some time. I ran into trouble because I forgot to
> take into consideration the Class of the variables and couldn't
> figure out why the loops weren't working.
> My question to you all... how could I have done this better or do you
> seeing anything that is wrong. Attached is the code. Thanks for the
> feedback.
Hey, ruby-quiz is back?!
This is how I would have done it... One loop, break-out once you got the
number. Maybe it helps.. Cheers, Martin
magic = rand(101).to_i
puts "Guess the magic number!"
loop do
print "Choose 0-100> "
n = gets.to_i
if !(0..100).include?(n)
puts "0-100!"
next
end
puts "Higher!" if n<magic
puts "Lower!" if n>magic
break if n==magic
end
puts "You won: #{magic} is the number!"
>
> Attachments:
> http://www.ruby-forum.com/attachment/6168/100guess.rb
>
>
[toc] | [prev] | [next] | [standalone]
| From | Super Goat <ruby-forum@sgoat.33mail.com> |
|---|---|
| Date | 2011-05-06 01:18 -0500 |
| Message-ID | <b38c8af4585da663e93ac2f2facf10df@ruby-forum.com> |
| In reply to | #3971 |
Thanks everyone for taking the time to reply! The reason I had 'rand(100).to_i' and 'random.to_i' is because in IRB it told me it was a Fixnum. Also, I had just figured out why my operators weren't working so I wanted everything to be an integer. Obviously, in retrospect, I see now that I didn't have to do it that way. After I submitted to Ruby-Forum I did notice that when I was checking to see if the input was within range that it would only do this at the beginning. Putting that code in was an afterthought. I also thought that I should really check to see if it was a number but I didn't know how to do that. I was unaware that I didn't need the chomp in 'gets.chomp.to_i'. I am still trying to wrap my head around Methods. I get it, but don't know how to put down the code. Even when I look at Jesus's example I am a bit confused but I have a feeling that using Methods is a very Rubyist thing and the way Ruby was intended to be written. I really like Martin's example. I am going to try to use a Method and make this work and see if I can figure out how to reject any input that isn't a number (probably isn't hard just don't know how yet). I want to thank everyone again for their help. I definitely feel welcomed and will be back. Goat -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Jesús Gabriel y Galán <jgabrielygalan@gmail.com> |
|---|---|
| Date | 2011-05-06 02:27 -0500 |
| Message-ID | <BANLkTikFiLoPK_gLtNSs+n+Vcmdw0G35Uw@mail.gmail.com> |
| In reply to | #4023 |
On Fri, May 6, 2011 at 8:18 AM, Super Goat <ruby-forum@sgoat.33mail.com> wrote: > I am still trying to wrap my head around Methods. I get it, but don't > know how to put down the code. Even when I look at Jesus's example I am > a bit confused but I have a feeling that using Methods is a very Rubyist > thing and the way Ruby was intended to be written. A method is just a block of code with a name that can be invoked from other points in the code. It can receive parameters, which are like local variables within the method
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-05-06 02:34 -0500 |
| Message-ID | <BANLkTikvyURgj9-iWYvGRjh7HLOBco2kcQ@mail.gmail.com> |
| In reply to | #4023 |
[Note: parts of this message were removed to make it a legal post.] On Fri, May 6, 2011 at 1:18 AM, Super Goat <ruby-forum@sgoat.33mail.com>wrote: > Thanks everyone for taking the time to reply! > > The reason I had 'rand(100).to_i' and 'random.to_i' is because in IRB it > told me it was a Fixnum. Also, I had just figured out why my operators > weren't working so I wanted everything to be an integer. Obviously, in > retrospect, I see now that I didn't have to do it that way. > > In OOP, classes can inherit functionality from other classes. There are several kinds of Integers, Fixnum is one of them, Bignum is another (okay, actually, those are the only two). 1.class # => Fixnum 1.kind_of? Integer # => true Fixnum.ancestors # => [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject] n = 10**1000 n.class # => Bignum n.kind_of? Integer # => true Bignum.ancestors # => [Bignum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
[toc] | [prev] | [next] | [standalone]
| From | Super Goat <ruby-forum@sgoat.33mail.com> |
|---|---|
| Date | 2011-05-08 00:08 -0500 |
| Message-ID | <300d3c20c6331d56a96f4ec2018510c7@ruby-forum.com> |
| In reply to | #3971 |
Thanks again for everyones input and thanks to Jesus for explaining and providing examples for using a method in my code. >And now, the OP is frightenend of functional programming No, this sounds like fun. I'll work my way there eventually. So attached is my updated version. As you can see I also added a # of 'guesses' variable that counts the number of attempts and then exits when you hit the max. That took me a little while to figure out, but I am pleased that I got it. I was thinking of asking if the player would like to play again and then figuring out how to restart the whole thing but I wasn't sure how to do this. How can I make prompt to "Play again?" and when answered "Yes" restart, whether the person wins or loses (or if "No" just exits)? Or is the way my code is written make this impossible? Attachments: http://www.ruby-forum.com/attachment/6181/meth_100guess.rb -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Josh Cheek <josh.cheek@gmail.com> |
|---|---|
| Date | 2011-05-08 00:30 -0500 |
| Message-ID | <BANLkTiky_8vPyTKb8E4R-BeFtO-g7xePRg@mail.gmail.com> |
| In reply to | #4113 |
[Note: parts of this message were removed to make it a legal post.] On Sun, May 8, 2011 at 12:08 AM, Super Goat <ruby-forum@sgoat.33mail.com>wrote: > > Attachments: > http://www.ruby-forum.com/attachment/6181/meth_100guess.rb > > > attempts = "0".to_i In the same way you have string literals (the "0"), you also have integer literals (just 0). 0 == "0".to_i # => true So just make it `attempts = 0`, same for flag. > flag = "8".to_i This seems to record the maximum number of times you can guess. I would call it something like "max_attempts", "flag" is not a descriptive name. On Sun, May 8, 2011 at 12:08 AM, Super Goat <ruby-forum@sgoat.33mail.com>wrote: > > I was thinking of asking if the player would like to play again and then > figuring out how to restart the whole thing but I wasn't sure how to do > this. How can I make prompt to "Play again?" and when answered "Yes" > restart, whether the person wins or loses (or if "No" just exits)? Or > is the way my code is written make this impossible? > > Right now there is no mechanism to get back to the beginning where variables are set and such. What if you had a method that did everything involved with a game, then you could play a game by calling that method. That would allow you to just have a little piece of code that is responsible for handling whether you should play another game or not. def play_game # ... end def play_again? # prompt user, return true or false end play_game play_game while play_again? puts "goodbye!"
[toc] | [prev] | [next] | [standalone]
| From | Stu <stu@rubyprogrammer.net> |
|---|---|
| Date | 2011-05-08 01:16 -0500 |
| Message-ID | <BANLkTim6YJ1ZQWw28Oh4v5gz+v-T-244Hg@mail.gmail.com> |
| In reply to | #4113 |
On Sun, May 8, 2011 at 12:08 AM, Super Goat <ruby-forum@sgoat.33mail.com> wrote: > > I was thinking of asking if the player would like to play again and then > figuring out how to restart the whole thing but I wasn't sure how to do > this. How can I make prompt to "Play again?" and when answered "Yes" > restart, whether the person wins or loses (or if "No" just exits)? Or > is the way my code is written make this impossible? > > Attachments: > http://www.ruby-forum.com/attachment/6181/meth_100guess.rb > > > -- > Posted via http://www.ruby-forum.com/. > > You can do it with more methods. In fact you should break as much down as possible. The concept is to keep every method as small as possible. Does one thing and does it well. Ruby allows you to add ? at the end of a method name which should return true/false so you could almost have it kind of tell a story. Ruby is also liberal with it's parens and has implied return statements. so for a contrived example a traditional language would look like this: def add_num( first_num, second_num) answer = (first_num + second_num) return( answer) end x = add_num( 42, 100) where in ruby it could look like this: def add_num first_num, second_num first_num + second_num end x = add_num 42, 100 methods always return a value (this is contrast to functions which do one thing and do it well but may only return success or error) Ruby has only methods. Methods give the user the ability to reuse code using the example above: x = add_num 42, 100 y = add_num( x, 16) z = add_num( y, x) puts z => 300 using good names for your methods make it easier for others to read them as well as making them easier to read years later if you ever have to revisit. Method definitions start with the def keyword, the method name, then there are optional arguments which are variables passed as copies into the scope of the method. The method body can contain the same code logic you have which reads much like a fall through shell script right now. Every method closes with the end keyword. The last statement returns regardless in ruby. My personal preference in style is to keep the parens in the definition but only use the return when I need to force it: def add_num( first_num, second_num) first_num + second_num end Once you have normalized the script in pure methods we can then begin to talk about how user created methods can relate to user created classes and start talking about object oriented programming. ~Stu
[toc] | [prev] | [next] | [standalone]
| From | Stu <stu@rubyprogrammer.net> |
|---|---|
| Date | 2011-05-08 02:22 -0500 |
| Message-ID | <BANLkTikt1dCh8LyK65-JkyMYtj0N8jBWnw@mail.gmail.com> |
| In reply to | #4116 |
I also wanted to add that you can embed methods directly into the
argument area.
following my previous example:
x = add_num( 42, 100)
add_num( x, add_num(16, x))
=> 300
in this case add_num(16, x) is evaluating 16+142 before sending it through.
My last piece of advice when you begin to figure out names for your
variables and methods is to separate as much of the game logic as you
can from the peripheral data. This will make it easier to change
things in the long run if you need.
puts "\nLets play a guessing game! You have 8 guesses before you lose."
target = rand(101) #creates a random number from 0 - 100
attempts = "0".to_i #
flag = "8".to_i
can be rewritten like so
max_user_attempts = 8
@attempt_counter = 0
directions = "\nLets play a guessing game! You have
#{max_user_attempts.to_s} guesses before you lose."
winning_response = rand(101)
def game_loop
print directions
#.. start loop and call many methods
end
If you want to change max_user_attempts later you have just one place
to change it. or better yet create a method that ask the user if they
want 'easy', 'medium', 'hard', 'elite' and set it based on the user
response. ( good way to learn about hashes though you can program it
other ways. Make easy infinite for responses so you can have the
chance to test the functionality of your game without really playing
it. sneaking in an easter egg cheat to reveal winning_response is also
a good way for testing =)
Last note. notice the @ in front of attempt_counter. This allows for
methods to see the variable outside their own scope. it's optional if
you want to use it but allows for direct manipulation:
def increment_attempt
@attempt_counter += 1
end
vs a more generic approach:
counter = 0
def inc_counter( arg)
arg += 1
end
counter = inc_counter( counter)
I hope I haven't confused you. I do not want to make it
overcomplicated or obfuscate it so please ask many questions. Methods(
and functions) are a very important concept to grok in every
programming language in every paradigm.
~Stu
[toc] | [prev] | [next] | [standalone]
| From | Super Goat <ruby-forum@sgoat.33mail.com> |
|---|---|
| Date | 2011-05-08 21:20 -0500 |
| Message-ID | <bac0bfea865bcd8393da546bc2652938@ruby-forum.com> |
| In reply to | #4118 |
Josh Cheek wrote in post #997327:
>> attempts = "0".to_i
>
> In the same way you have string literals (the "0"), you also have
> integer
> literals (just 0).
> 0 == "0".to_i # => true
>
> So just make it `attempts = 0`, same for flag.
Josh: I originally had the variables like that way you described but I
changed it because I was getting an error when I tried to add 1
'attempts += 1'. I just now changed it back and of course there was no
error so I must have mistyped something. Who knows now but thanks for
pointing that out.
>
> On Sun, May 8, 2011 at 12:08 AM, Super Goat
> <ruby-forum@sgoat.33mail.com>wrote:
>
>>
>> I was thinking of asking if the player would like to play again and then
>> figuring out how to restart the whole thing but I wasn't sure how to do
>> this. How can I make prompt to "Play again?" and when answered "Yes"
>> restart, whether the person wins or loses (or if "No" just exits)? Or
>> is the way my code is written make this impossible?
>>
>>
> Right now there is no mechanism to get back to the beginning where
> variables
> are set and such. What if you had a method that did everything involved
> with
> a game, then you could play a game by calling that method. That would
> allow
> you to just have a little piece of code that is responsible for handling
> whether you should play another game or not.
>
> def play_game
> # ...
> end
>
> def play_again?
> # prompt user, return true or false
> end
>
> play_game
> play_game while play_again?
> puts "goodbye!"
I like this idea and will give this a go on my next version.
Thanks again for your insight.
==============================
Stu wrote in post #997331:
> On Sun, May 8, 2011 at 12:08 AM, Super Goat
> <ruby-forum@sgoat.33mail.com> wrote:
>
>>
>> --
>> Posted via http://www.ruby-forum.com/.
>>
>>
>
> Every method closes with the end keyword.
>
> The last statement returns regardless in ruby.
>
Can you explain these two lines more thoroughly and when you say 'the
last statement returns', where does it return to.
Sorry for my ignorance, this is my first true attempt to learn a
language (I took 2 classes C++ 15 years ago in highschool)
Stu wrote in post #997333:
> My last piece of advice when you begin to figure out names for your
> variables and methods is to separate as much of the game logic as you
> can from the peripheral data. This will make it easier to change
> things in the long run if you need.
>
> puts "\nLets play a guessing game! You have 8 guesses before you lose."
> target = rand(101) #creates a random number from 0 - 100
> attempts = "0".to_i #
> flag = "8".to_i
>
> can be rewritten like so
>
> max_user_attempts = 8
> @attempt_counter = 0
> directions = "\nLets play a guessing game! You have
> #{max_user_attempts.to_s} guesses before you lose."
> winning_response = rand(101)
>
> def game_loop
> print directions
> #.. start loop and call many methods
> end
Stu, this make complete sense. I probably would have read this or
sortof figured this out eventually but now I will really consider it as
I start to code each project.
> Last note. notice the @ in front of attempt_counter. This allows for
> methods to see the variable outside their own scope. it's optional if
> you want to use it but allows for direct manipulation:
>
> def increment_attempt
> @attempt_counter += 1
> end
>
So can I just refer to increment_attempt each time i want the
@attempt_counter to increase by one? for instance, replacing the way i
did it here.
until (choice = get_valid_input) == target
puts "\nWrong, my number is #{choice < target ? 'higher' : 'lower'}"
attempts += 1
with
until (choice = get_valid_input) == target
puts "\nWrong, my number is #{choice < target ? 'higher' : 'lower'}"
@attempt_counter
and if there were any other places where I would want to increase the
attempts just refer to @attempt_counter again?
> I hope I haven't confused you. I do not want to make it
> overcomplicated or obfuscate it so please ask many questions. Methods(
> and functions) are a very important concept to grok in every
> programming language in every paradigm.
>
> ~Stu
Not at all Stu. I think you are really helping me establish some solid
Ruby coding processes and techniques. (I'm sure a lot of this applies to
more than just Ruby) One thing I have learned, which may sound obvious
but I never realized, is that there are so many ways to code something
and get the same end result. That coding can even be someones style.
Thanks for taking your time to explain everything.
Goat
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Stu <stu@rubyprogrammer.net> |
|---|---|
| Date | 2011-05-09 00:29 -0500 |
| Message-ID | <BANLkTi=Gguy=AHfK83_Cx9w80wKhwnYQhg@mail.gmail.com> |
| In reply to | #4146 |
Hi Goat,
The basic skeletal structure of a ruby method is so:
def method_name( arg1, arg2, *args) # and so on
#.. method body
return #.. or implicit return( i.e. the keyword is optional)
end
In traditional languages you have a return keyword which returns a
value to the caller. In ruby everything is a caller and everything is
a sender. This is another paradigm you'll come to understand the more
you work with ruby.
very contrived example:
def return_42( )
return( 42)
end
is equivalent to
def return_42
42
end
Here is another conceptual example with my style please try it in irb.
I will create a adder method and then create a square method using the
the previous methods in effort to show you how methods can be reused:
def adder( x,y)
x + y
end
def square_num( x)
y = 0
count = 0
while count != x
y+=adder( x,0)
count += 1
end
return( y)
end
irb session:
>> square_num( 3)
=> 9
>> adder( 1, 4)
=> 5
>> square_num( adder( 3, 1))
=> 16
>> adder( square_num( 3), square_num( 5))
=> 34
starting with the adder method I did not use a return statement. I
could have rewritten the last line as return( x+y) but I didn't. It's
up to you to figure out if it's more readable with or without it.
Either way if I write this code:
var = adder( 41, 100) # the variable 'var' will be populated with the
return value from the function adder.
The square_num( ) method reuses the adder method in a conditional
while loop. Though contrived for this example it's a good way to
understand methods to be composed for reuse. When you get to get to
OOPS programming there is a concept of composite objects. The concept
is the same but in a less linear fashion.
You'll also notice I used the return statement in the square_num( )
method. I did this because I personally feel the freestanding variable
'y' looks awkward and less readable. Others opinion on the subject may
vary. It's up to you to decide what works best and use those
conventions.
A more succinct way to write the square_num( ) method would be this:
def square_ruby_way( x)
y = 0
x.times { y+=adder(x,0) }
y
end
The right ruby way( and quickest) with the most most brevity would be
to use ruby's built in power of operator method:
def best_ruby_square( x)
x**2
end
The first example of course removes the while loop and follows one of
ruby's object oriented conventions. I don't want to get to deep into
it as it is a abstraction of a while loop and begins to expose some of
ruby's built in iterator design patterns. The times method should be
saved for another discussion after you get your bearings with method
creation and definition.
~Stu
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web