如何使用Ruby在二维数组中迭代并增加迭代步长?

3

我想从一个数组中抓取两个子数组,有什么好的方法吗?

例如:

deck = [[2,spades],[3,hearts],[6,diamonds],[10,clubs],[8,hearts],[9,clubs]]

有没有办法用循环一次抓取两张卡牌,每次增加索引并从[0..1]到[1..0]等等,以此类推。
我想放入:
玩家1的牌:[2,黑桃],[3,红心]
玩家2的牌:[6,方块],[10,梅花]

请注意,deck 的每个元素都是一个数组这一事实并不重要。如果 deck = [:card1, :card2,..., :card6],同样的解决方案也适用。顺便提一下,您是指 "spades" 还是 :spaces?如所述,spades 必须是一个变量或方法。 - Cary Swoveland
@max paspa,提供的答案中有没有一个对您有用?如果有,请选择一个答案,这样当用户搜索时,它就会显示为一个带有答案的问题。谢谢! - OneNeptune
3个回答

3

我的建议是将牌组数组传递给一个方法,并返回包含[player1,player2,deck]的数组。如果你只是从牌组的“顶部”抽取,你可以使用 shift 来取出数组的第一个元素。

长期解决方案

deck = [[2,"spades"],[3,"hearts"],[6,"diamonds"],[10,"clubs"],[8,"hearts"],[9,"clubs"]]

def drawTwo(arr)
  if arr.count >= 4
    player_one = [deck.shift, deck.shift]
    player_two = [deck.shift, deck.shift]
    return [player_one, player_two, deck]
  else
    return "Not enough cards in deck, please provide a new deck"
  end
end

round = drawTwo(deck)
player_one = round[0]
player_two = round[1]
deck = round[2]

puts "Player one: #{player_one}"
puts "Player two: #{player_two}"
puts "Deck: #{deck}"

我尽力详细描述这段代码,不会让它变得复杂,所以应该很容易理解。

你可以通过像这样重写它来使它更简短,但我想让它易于理解:

简洁的解决方案

deck = [[2,"spades"],[3,"hearts"],[6,"diamonds"],[10,"clubs"],[8,"hearts"],[9,"clubs"]]

def drawTwo(arr)
  arr.count >= 4 ? [[arr.shift, arr.shift], [arr.shift, arr.shift]] : raise "Not enough cards..."
end

player_one, player_two = drawTwo(deck)

puts "Player one: #{player_one}"
puts "Player two: #{player_two}"
puts "Deck: #{deck}"

请确保在首次生成牌组时包含deck.shuffle
此外,我不知道您用什么来生成牌组,但是我很喜欢这个方法:

生成洗牌后的牌组

def newShuffledDeck
    ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
    suits = ["hearts", "spades", "clubs", "diamonds"]
    deck = ranks.product(suits)
    deck.shuffle
end

一些 Ruby 小技巧 —— 你可以写成 player_one, player_two, deck = drawTwo(deck),Ruby 会自动解包。此外,函数不需要返回 deck,我假设你有其他编程语言中“按值传递”的背景知识。在 Ruby 中,所有东西都是“按指针传递”的。 - akuhn
@akuhn 给出了很好的建议,谢谢!关于返回牌组,我假设这将在某种游戏中多次运行,那么他们不需要使用相同的卡牌来继续第2、3轮等,难道他们不需要更新后的牌组吗? - OneNeptune
你返回的 deck 指向与传递给函数的 deck 相同的对象。因此不需要返回它。 - akuhn
更多Ruby技巧 - 不要返回错误信息,因为这会导致后续的错误。只需要使用 raise "Not enough cards ..." 抛出运行时异常即可。 - akuhn
你可以写成 deck.shift(2) 而不是 [deck.shift, deck.shift] - Sagar Pandya

2

试试这个

hands = array.each_slice(hand_size).take(player_count)

hands.each_with_index do |hand, n|
  puts "player #{n + 1} cards are: #{hand}"
end

这是如何工作的?

  • each_slice(n) 将数组切成长度为n的片段
  • take(n) 取前n个片段

0
你可以使用Enumerable::each_slice
deck = [[2,"spades"],[3,"hearts"],[6,"diamonds"],[10,"clubs"],[8,"hearts"],[9,"clubs"]]

deck.each_slice(2) do |el|
  puts el
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接