Forum: Ruby Writing a game, trying to make dynamic loops

2249f6442e16bc469d670d96f38ef2e2?d=identicon&s=25 Nick G. (nick_g62)
on 2013-03-24 17:55
Hey there,

This is likely very simple, but I haven't stumbled across the right code
yet.

I want the following to take place:
[code]
class Player
end
puts "How many players?"
players = gets()
players.times do
  puts "Name of player?"
  playername = gets()
  # This is  where I get stuck.  I want to make an object
    named after what is stored as playername
  playername = Player.new???  Doesn't seem to work
end
[/code]

I did go through several Google searches, and I can't seem to find the
location of a break down on loops that run based on user input.  Any
tips would be appreciated!  :)

Thanks,
Nick

PS:  I hope this code was small enough to just toss in here.  Sorry if
it's not!

Edit: Took out players.each and fixed it to players.times do.
45441e46d19d428be152ecb81883044a?d=identicon&s=25 Calvin B. (calvin_b)
on 2013-03-24 19:15
(Received via mailing list)
Hello Nick,

it is, indeed, quite simple. gets returns the input as a string. Since
you want it as an integer, convert it via to_i. Then, with the integer,
you can use Integer#times instead of your each call, which will execute
the block multiple times.

Your second problem is that you create a new player object (and assign
it to your playername variable), but your objects of class Player are
just hollow objects without any information (you seem to have an empty
Player class). If you want those objects to store a name, do something
like

   class Player
     def initialize( name )
       @name = name
     end
     attr_reader :name
   end

and then create your objects by Player.new( player_name_here ).

In general, I think you should see the documentation of the functions
you want to use, and consider what they return vs. what you want. May I
ask what tutorials you read on ruby (or programming in general)? Afaik
all ruby tutorials cover these two topics.

Kind regards, Calvin

P.S.: Googling "ruby loop number" gives some results, of which the
second mentions the #times method of integers. Just a heads up for
future searches. ;)

On 24.03.2013 17:55, Nick G. wrote:
> players = gets()
> players.each {  # Trying to make this loop run based on the number
[...]
2249f6442e16bc469d670d96f38ef2e2?d=identicon&s=25 Nick G. (nick_g62)
on 2013-03-24 19:58
Hi Calvin,

Hmm...okay, that makes sense.  I'm reading through the Book of Ruby, but
I got caught up with making objects via:

player1 = Player.new

The looping now works, but I'm stuck with storing this data properly.

puts("How many players?")
players = gets().to_i
x = 1
players.times do
  puts("Name of player #{x}?")
  Player.new(gets())
  x += 1
end

What could I add within the loop to make these new players store as a
variable I can recall?  What can I add to a basic variable to add in
which player the loop is currently on as an additional character in the
variable?  I'm looking for something like this:

player#{x} = Player.new(gets())

But I know this doesn't work.

Thanks for your time (and patience)!

Calvin B. wrote in post #1103032:
> Hello Nick,
>
> it is, indeed, quite simple. gets returns the input as a string. Since
> you want it as an integer, convert it via to_i. Then, with the integer,
[...]
2249f6442e16bc469d670d96f38ef2e2?d=identicon&s=25 Nick G. (nick_g62)
on 2013-03-24 20:48
I figured out how to handle what I'm trying to accomplish by making an
array of the players.

Thanks for your help, Calvin!
086dc381f93a2bb727b87fabd2f980fe?d=identicon&s=25 Daniel Ferguson (Guest)
on 2013-03-24 21:07
(Received via mailing list)
Hi!

Would you be happy accessing players by an array index?
eg. players[0].name would return player 1's name
players[2].score would return player 3's score etc.

Possibly not the best solution but I think it would work:

class Player
  def initialize(name)
    @name = name
  end
end

puts "How many players?"
players = Array.new(gets.to_i) #.to_i converts the string to an integer
if possible

# players is now an array the size of entered number and will look like
this if player entered '3' [nil, nil, nil]

# map! lets you alter array elements and goes through them exactly as
.each does
# have a look at the documentation for more info

n = 1
players.map! { |e|
  puts "Name of player #{n}?"
  e = Player.new(gets.chomp()) #chomp strips off the newline character
}

players[0] will give you access to your first player object
players[1] etc.

you could use players[1].name
or players[2].score to use your player methods once you've defined them



# inspecting the array gives you a list of Player objects

# you could instead use hashes to access your objects with some tweaks
to the assignment process

# also are you sure you want objects named after what is set as the
player name?
15000f55138ae94b0f362ed7c625461a?d=identicon&s=25 unknown (Guest)
on 2013-03-24 21:54
(Received via mailing list)
Am 24.03.2013 21:06, schrieb Daniel Ferguson:

> puts "How many players?"
> players = Array.new(gets.to_i) #.to_i converts the string to an integer if
possible
...
> n = 1
> players.map! { |e|
>   puts "Name of player #{n}?"
>   e = Player.new(gets.chomp()) #chomp strips off the newline character
> }

The assignment to `e' doesn't have any effect.

The above could be simpler written as:

   puts "How many players?"
   players = Array.new(gets.to_i)

   n = 1
   players.map! {
     puts "Name of player #{n}?"
     n += 1  # missing
     Player.new(gets.chomp)
   }

BUT: map! isn't really needed here: the old array elements are
all `nil' and not used at all. Also, using a separate `n' to count
through the players is redundant.

To me a more natural solution would be something like this:

   puts "How many players?"
   number_of_players = gets.to_i

   players = []
   1.upto(number_of_players) do |n|
     puts "Name of player #{n}?"
     players << Player.new(gets.chomp)
   end

or maybe:

   puts "How many players?"
   number_of_players = gets.to_i

   players = (1..number_of_players).map do |n|
               puts "Name of player #{n}?"
               Player.new(gets.chomp)
             end
D9ebdcb66f1583378e6f72155db507e2?d=identicon&s=25 Hans Mackowiak (hanmac)
on 2013-03-25 09:39
how about this?

puts "How many players?"
players = Array.new(gets.to_i) do |n|
  puts "Name of player #{n+1}?"
  Player.new(gets.chomp)
end
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-25 12:53
(Received via mailing list)
On Mon, Mar 25, 2013 at 9:40 AM, Hans Mackowiak <lists@ruby-forum.com>
wrote:
> how about this?
>
> puts "How many players?"
> players = Array.new(gets.to_i) do |n|
>   puts "Name of player #{n+1}?"
>   Player.new(gets.chomp)
> end

I'd rather use #times with #map:

players = Integer(gets).times.map do |i|
    puts "Name of player #{n+1}?"
    Player.new(gets.chomp)
  end

Kind regards

robert
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.