如何重构Ruby方法以通过Rubocop测试,同时保持干燥
作为Launch学校课程的一部分,我正在制作一款21人游戏(可以将该游戏想象为21点的轻量级版本) 我需要正确地重构我自己的代码,以保持其干燥,同时通过所有Rubocop测试。我目前正在使用Rubocop版本0.85.0(本课程要求使用此版本) 在我的游戏中,我将所有数据存储在一个名为Keep Score的散列中:如何重构Ruby方法以通过Rubocop测试,同时保持干燥,ruby,refactoring,Ruby,Refactoring,作为Launch学校课程的一部分,我正在制作一款21人游戏(可以将该游戏想象为21点的轻量级版本) 我需要正确地重构我自己的代码,以保持其干燥,同时通过所有Rubocop测试。我目前正在使用Rubocop版本0.85.0(本课程要求使用此版本) 在我的游戏中,我将所有数据存储在一个名为Keep Score的散列中: keep_score = { 'player_cards' => [], \ 'dealer_cards' => [], \
keep_score = { 'player_cards' => [], \
'dealer_cards' => [], \
'player_card_values' => [], \
'dealer_card_values' => [], \
'player_points' => 0, \
'dealer_points' => 0, \
'player_move' => '', \
'dealer_move' => '', \
'end_game' => false }
到目前为止,我的代码可以正常工作,到目前为止,我已经做了很多重构,但是我需要进一步重构这两种方法,使代码更加枯燥,同时仍然通过Rubocop测试
我有两种方法,一种是convert_face_cards
,它可以转换国王、王后和杰克(分别处理王牌)。然后有一个单独的方法,添加整数值\u点
来处理卡片上的整数值:
def convert_face_cards(keep_score)
keep_score['player_points'] = 0
keep_score['dealer_points'] = 0
keep_score['player_card_values'].each do |card|
if card == "jack" || card == "queen" || card == "king"
keep_score['player_points'] += 10
end
end
keep_score['dealer_card_values'].each do |card|
if card == "jack" || card == "queen" || card == "king"
keep_score['dealer_points'] += 10
end
end
end
def add_integer_points(keep_score)
keep_score['player_card_values'].each do |card|
if card.is_a? Integer
keep_score['player_points'] += card
end
end
keep_score['dealer_card_values'].each do |card|
if card.is_a? Integer
keep_score['dealer_points'] += card
end
end
end
虽然这段代码从技术角度来看是有效的,但我没有通过Rubocop测试。convert\u face\u cards
方法返回错误:convert\u face\u cards的圈复杂度太高。[7/6]
我的代码显然没有可能的那么枯燥。例如,在convert\u face\u cards
方法中,我基本上在player\u card\u值
散列键和dealer\u card\u值
散列键上以相同的方式运行each
方法
但我不知道如何进一步浓缩这些方法。感谢您的帮助和指导 因为无论是玩家还是庄家,计算脸牌的逻辑都是相同的,所以你可以将其提取到自己的方法中,使事情变得更干枯
def convert_face_cards(keep_score)
players = keep_score['player_card_values'].select { |card| card == "jack" || card == "queen" || card == "king" }
dealers = keep_score['dealer_card_values'].select { |card| card == "jack" || card == "queen" || card == "king" }
keep_score['player_points'] = players.length * 10
keep_score['dealer_points'] = dealers.length * 10
end
def convert_face_cards(keep_score)
keep_score['player_points'] = count_faces(keep_score['player_card_values'])
keep_score['dealer_points'] = count_faces(keep_score['dealer_card_values'])
end
def sum_faces(cards)
faces = cards.select { |card| face?(card) }
faces.length * 10
end
def face?(card)
%w[jack queen king].include?(card)
end
您不应该使用散列来存储此数据,也不应该编写在散列上循环的代码。您应该使用包含这些知识的数据结构作为方法 例如:
Card = Struct.new(:value) do
def score
case value
when :king, :queen, :jack
10
when :ace
1
else
value
end
end
end
CARDS = [
:ace,
:king,
:queen,
:jack,
10,
... # other cards here
2
].map { |card| Card.new(card) }
player_cards = []
dealer_cards = []
def score(cards)
cards.sum(&:score)
end
这可能更简单,我们可以将卡片类型放入一个变量:。。。卡牌类型=%w(杰克·奎因·金)玩家=保留分数['player_card_values']。选择{卡牌{卡牌类型。包括?卡牌}。。。