Ruby实现二十一点游戏提示undefined method `make_card`错误
Ruby实现二十一点游戏
undefined method "make_card"报错排查 问题现象
运行基于Ruby编写的二十一点纸牌游戏代码时,触发报错:undefined method "make_card",涉及的Deck类原始代码如下:
class Deck def initialize @faces = [*(2..10),'Jack','Queen','King','Ace'] @suits = ['clubs','spades','hearts','diamonds'] @cards = [] @faces.each do |face| if face.class == "Integer" value = face elsif face == 'Ace' value = 11 else value = 10 end @suits.each do |suit| @cards << Card.new(face,suit,value) end end @cards.shuffle! end def make_card(participant) fresh_card = Card.new(face,suit,value) participant.turn << fresh_card participant.total = participant.total + fresh_card.value end def deal(number,participant) number.times{@cards.shift.make_card(participant)} end end
报错根因
- 方法调用对象错误:
make_card是定义在Deck类上的实例方法,但deal方法中是对@cards.shift返回的Card类实例调用该方法,Card类并没有实现make_card方法,因此触发方法不存在的报错。 - 代码存在两处隐藏逻辑错误,即使修正调用对象也会运行异常:
make_card方法中引用的face/suit/value属于initialize方法循环内的局部变量,作用域不覆盖make_card方法,调用时会触发未定义变量错误。- 牌值判断逻辑错误:
face.class == "Integer"的判断永远不成立——face.class返回的是Integer类对象,和字符串"Integer"不相等,会导致2-10的数字牌全部被错误赋值为10点。
修正后代码
调整逻辑后可正常运行的Deck类实现如下:
class Deck def initialize @faces = [*(2..10),'Jack','Queen','King','Ace'] @suits = ['clubs','spades','hearts','diamonds'] @cards = [] @faces.each do |face| # 修正类型判断逻辑 if face.is_a?(Integer) value = face elsif face == 'Ace' value = 11 else value = 10 end @suits.each do |suit| @cards << Card.new(face, suit, value) end end @cards.shuffle! end def make_card(participant) # 直接从已洗牌堆取牌,无需重复创建Card实例 fresh_card = @cards.shift participant.turn << fresh_card participant.total += fresh_card.value end def deal(number, participant) # 对Deck实例自身调用make_card方法 number.times { make_card(participant) } end end
内容的提问来源于stack exchange,提问作者Muhammad Fahad
相关产品推荐
相关产品推荐

