0

我无法弄清楚这个基于文本的 RPG 的指导。我希望玩家的输入在四个类别之一之间进行选择,然后保存该类别并为其分配统计数据。目前,它仅在我选择"Warrior". 我究竟做错了什么?

stats = Hash.new
stats["Strength"] = 10
stats["Dexterity"] = 10
stats["Charisma"] = 10
stats["Stamina"] = 10
puts "Hello, brave adventurer.  What is your name?"
player_name = gets.chomp.capitalize

puts "Well, #{player_name}, you are certainly brave!  Choose your profession.  (Choose         from Warrior, Wizard, Archer, or Thief)."

player_class = gets.chomp.downcase

while player_class != ("warrior" || "thief" || "archer" || "wizard")
  puts "I do not recognize #{player_class} as a valid class.  Please choose between     Warrior, Wizard, Archer, or Thief."
  player_class = gets.chomp.downcase
end

if player_class == "warrior"
  puts "Yay a warrior!"
  stats["Strength"] = 20
elsif player_class == "thief"
  puts "yay a thief!"
  stats["Dexterity"] = 20
elsif player_class == "archer"
  puts "yay an archer!"
elsif player_class == "wizard"
  puts "Sweet a wizard!"
end
4

3 回答 3

3

It's very simple.

1.9.3p194 :001 > ("warrior" || "thief" || "archer" || "wizard")
 => "warrior" 

The logical OR of several strings evaluates to the first one.

You could replace that line by something like:

while player_class != "warrior" and player_class != "thief" and player_class !=  "archer" and player_class != "wizard"
于 2013-01-05T16:00:56.300 回答
2

Try setting up the classes as an array...

player_classes = ["warrior", "thief", "archer", "wizard"]

And then when you want to check if the player has entered a valid class...

while ! player_classes.include? player_class 

instead.

You can use an even nicer idiom for single words...

%w(warrior thief archer wizard)

Generates

["warrior", "thief", "archer", "wizard"]

Moving forward

You could take this approach a step forward by putting the player classes into a hash.

For example:

player_classes = {
  'warrior' => {:message => "Yay a warrior!", :stats => {:strength => 20} },
  'thief'   => {:message => "Ooh a thief!", :stats => {:dexterity => 20} },
  'archer'  => {:message => "Cool! an archer" },
  'wizard'  => {:message => "Sweet! a wizard" }
}

You can then do things like this:

while ! player_classes.key? player_class

Once you've got a match you can then pull the values out of the hash, like this:

selected_class = player_classes[player_class]
stats.merge selected_class[:stats] if selected_class[:stats] 

If there's no stats in the hash for that player class nothing will happen, if there is, it'll be merged in.

e.g. to test this...

selected_class = player_classes['warrior']
stats.merge selected_class[:stats] if selected_class[:stats] 

# stats is now {:strength=>20, :dexterity=>10, :charisma=>10, :stamina=>10}

selected_class = player_classes['wizard']
stats.merge selected_class[:stats] if selected_class[:stats] 

# stats is now {:strength=>10, :dexterity=>10, :charisma=>10, :stamina=>10}

We can then show the message with:

puts player_classes[player_class][:message]

This would reduce your logic down to capturing the player class input and then processing the hash.

Revisting your original code

Using a hash to act as a simple data-model.

You'd end up with code like this:

#!/usr/bin/env ruby

stats = { :strength => 10, :dexterity => 10, :charisma => 10, :stamina => 10 }

player_classes = {
  'warrior' => {:message => "Yay a warrior!", :stats => {:strength => 20} },
  'thief'   => {:message => "Ooh a thief!", :stats => {:dexterity => 20} },
  'archer'  => {:message => "Cool! an archer" },
  'wizard'  => {:message => "Sweet! a wizard" }
}

puts "Welcome brave adventurer, what is your name?"
player_name = gets.chomp.capitalize

puts "Well, #{player_name}, you are certainly brave!  Choose your profession.  (Choose from Warrior, Wizard, Archer, or Thief)."
player_class = gets.chomp.downcase

while ! player_classes.key? player_class
  puts "I do not recognize #{player_class} as a valid class.  Please choose between Warrior, Wizard, Archer, or Thief."
  player_class = gets.chomp.downcase
end

selected_class = player_classes[player_class]
stats.merge selected_class[:stats] if selected_class[:stats] 

puts selected_class[:message]

You should also find this more readable, however, as you extend your game, you'll find that you can't easily work with code like this. You should next learn about using functions to break up your code into different routines. There are also more things you can do with arrays, hashes and collections.

Also, as soon as possible, you should start learning about programming Ruby in an Object Oriented style, which is how it should be used, ideally.

Tutorials Point is a pretty decent site for learning more about Ruby

于 2013-01-05T16:01:38.540 回答
0

对于您做错了什么,请参阅 Diego 的回答。

case这是您应该使用该语句的典型情况。您可以删除例程以获取播放器类,如下所示:

public
def get_player_class
  case player_class = gets.chomp.downcase
  when "warrior" then puts "Yay a warrior!"; stats["Strength"] = 20
  when "thief" then puts "yay a thief!"; stats["Dexterity"] = 20
  when "archer" then puts "yay an archer!"; true
  when "wizard" then puts "Sweet a wizard!"; true
  else puts "I do not recognize #{player_class} as a valid class. "\
    "Please choose between Warrior, Wizard, Archer, or Thief."; false
  end
end

stats = {"Strength" => 10, "Dexterity" => 10, "Charisma" => 10, "Stamina" => 10,}
puts "Hello, brave adventurer.  What is your name?"
player_name = gets.chomp.capitalize
puts "Well, #{player_name}, you are certainly brave! "\
  "Choose your profession.  (Choose from Warrior, Wizard, Archer, or Thief)."
nil until get_player_class
于 2013-01-05T16:19:28.377 回答