甲板#shuffle和甲板#shuffle!做同样的事情

时间:2014-05-16 22:24:43

标签: ruby shuffle

我正在用Ruby写一个卡片游戏框架,我发现了一个问题。我做了一个混乱方法,混合卡,它工作正常。但是我打电话给Deck #shuffle而不是Deck #shuffle!它保持了洗牌,这是我不想要的。

我也觉得奇怪的是,当我添加:riffle作为一个参数时,然后洗牌不会让我想要的牌组洗牌。

我很感激有关如何防止Deck #shuffle修改甲板的任何帮助。谢谢!

这是我的代码(很好的一部分,如果有人也需要我,我可以发布其余部分):

class Deck

    def initialize
        @cards = []
        (1..4).each { |suit|
            (1..13).each { |rank|
                @cards << Card.new(rank, suit)
            }
        }
    end

    def size
        @deck.length
    end

    def shuffle!(type = :random, precision = 100)
        case type
        when :random
            @cards.shuffle!
        when :riffle, :farro
            i = 0
            first, second = cut
            @cards = []
            while size != 52
                pile = (i.even? ? first : second)
                if pile.empty?
                        pile = (pile == first ? second : first)
                end
                add_card(pile.pop)
                i += 1  if (1..precision) === rand(1..100)
            end
        else
            warn "Invalid shuffle method."
        end
    end

    def shuffle(type = :random, precision = 100)
        dup.shuffle!(type, precision)
    end

    def add_card(card)
        @cards << card
    end

end

deck = Deck.new
deck.shuffle

p deck.cards.map(&:to_a)

3 个答案:

答案 0 :(得分:2)

您的Deck班级有一个实例变量 - @cards - 用于存放卡片。 @cards实际上是对一系列卡片的引用。

使用它时没有实现Deck#dup,使用Object#dup执行浅拷贝 - 它将所有实例变量复制为引用。 它不会复制实例变量!

这意味着dup ed Deck拥有不同的 @cards变量,该变量引用与原始数据相同的数组Deck的{​​{1}}。当你@cards时,同一个数组被洗牌。它可以通过不同的引用变量访问,但它仍然是相同的数组。

如果您尝试shuffle:riffle改组,它将不会影响原始对象,因为您使用:farro这些随机播放类型中的那些将@cards = []设置为a新阵列。

尽管如此,我要说即使你没有@cards类型,实现仍然是错误的 - 因为新:random与旧版本的分离不应该在@cards - 它应该在shuffle!

那么,您需要覆盖dup方法并使其重复dup。您可能还想更改@cards以支持此功能:

initialize

答案 1 :(得分:0)

在对象上dup Deck时。这意味着当您获得新的Deck实例时,原始@cards和新{{1}}都会引用相同的{{1}}实例变量。

答案 2 :(得分:0)

这一行...

dup.shuffle!(type, precision)

...正在创建Deck对象的浅表副本。

虽然它有自己的实例变量@cards,但实例变量实际上引用的是与原始对象中的实例变量相同的对象。