2012-02-20 201 views
1

我正在寻找一些关于动态变量的建议。特别是如果我充分利用instance_variable_set或者我应该看到更好的方法。提前感谢您的任何建议。现在代码。动态变量值

我正在创建一个二十一点游戏。我有两个value_creator方法看起来像这样:

class Blackjack 

    def dealers_card_value_creator 
    @card_value = @hit_dealer 
     case 
     when @card_value.match(/\d+/) 
     @card_value = @card_value.match(/\d+/)[0].to_i 
     when @card_value.match(/Ace/) 
     if @dealers_hand >= 11 
      @card_value = 1 
     else 
      @card_value = 11 
     end 
     when @card_value.match(/Jack|Queen|King/) 
     @card_value = 10 
     else 
     puts "there was an error. please try again." 
     end 
    @hit_dealer = @card_value 
    @dealers_hand = @dealers_hand + @hit_dealer 
     if @dealers_hand > 21 then puts "Dealer went over 21. You won $#{@bet}. Nice!" 
     deal end 
    end 

def players_card_value_creator 
    @card_value = @hit_player 
    case 
    when @card_value.match(/\d+/) 
     @card_value = @card_value.match(/\d+/)[0].to_i 
    when @card_value.match(/Ace/) 
     if @players_hand >= 11 
     @card_value = 1 
     else 
     @card_value = 11 
     end 
    when @card_value.match(/Jack|Queen|King/) 
     @card_value = 10 
    else 
     puts "there was an error. please try again." 
    end 
    @hit_player = @card_value 
    @players_hand = @players_hand + @hit_player 
     if @players_hand > 21 then puts "You went over 21. You lost $#{@bet}. Try again." 
     deal end 
    end 
end 

你可以看到,他们基本上是相同的。所以我创建了这个方法供经销商和玩家使用。

def value_creator(string) 
    hit = "@#{string}" #returns either @player or @dealer 
    instance_variable_set(hit, "#{@hit_card}") 
    @card_value = hit 
    case 
    when @card_value.match(/\d+/) 
     @card_value = @card_value.match(/\d+/)[0].to_i 
    when @card_value.match(/Ace/) 
     if "@#{string}"_hand >= 11 
     @card_value = 1 
     else 
     @card_value = 11 
     end 
    when @card_value.match(/Jack/) 
     @card_value = 10 
    when @card_value.match(/Queen/) 
     @card_value = 10 
    when @card_value.match(/King/) 
     @card_value = 10 
    else 
     puts "there was an error. please try again." 
    end 
    "@#{string}" = @card_value 
    "@#{string}"_hand = "@#{string}"_hand + "@#{string}" 
    end 

    def hit_dealer 
    @hit_card = @shuffled_deck.pop 
    value_creator("dealer") 
    end 

    def hit_player 
    @hit_card = @shuffled_deck.pop 
    value_creator("player") 
    end 

但是当我尝试调用"@#{string}"值与hit_player返回@player,没有被分配的值。

很多代码,但我希望它有助于更​​好地理解我正在尝试做什么,并将有助于更好地指导建议。再次,在此先感谢。

回答

1

hit = "@#{string}" #returns either @player or @dealer 

的评论是不正确的。 结果不是@player@dealer,它是字符串'@player''@dealer'

你可以这样做:

def value_creator(variant) 
    case variant 
    when :player 
     hit = @player 
    when :dealer 
     hit = @dealer 
    else 
     raise ArgumentError 
    end 
    #.... 
end 
def hit_dealer 
    @hit_card = @shuffled_deck.pop 
    value_creator(:dealer) 
end 

def hit_player 
    @hit_card = @shuffled_deck.pop 
    value_creator(:player) 
end 

另一种方法:instance_variable_get来获取值。其他

hit = instance_variable_get("@#{string}") 

两种可能性:

hit = eval("@#{string}") 

(我不喜欢它 - EVAL是邪恶的)。

并与send

你必须定义两个访问第一:

attr_reader :player 
attr_reader :dealer 

然后你可以使用:

def value_creator(string) 
    hit = send(string) 
+0

感谢这个作品。因此,检索该值的最佳方法是使用'instance_variable_get',是否存在'hit =“@#{string}”上的任何变化''你知道会返回值,而不是字符串?再次感谢。 – Alekx 2012-02-20 23:29:47

+0

'hit = eval(“@#{string}”)' - 但eval是邪恶的。 – knut 2012-02-20 23:31:26

+0

哈哈,再次感谢! – Alekx 2012-02-20 23:39:47