首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Deck#shuffle和Deck#shuffle!做同样的事

Deck#shuffle和Deck#shuffle!做同样的事
EN

Stack Overflow用户
提问于 2014-05-16 22:24:43
回答 3查看 141关注 0票数 0

我正在用Ruby编写一个卡片游戏框架,我发现了一个问题。我做了一个洗牌方法,把牌混在一起,效果很好。但是,我叫Deck#shuffle而不是Deck#shuffle!它能让甲板保持混乱,而我不想这样。

我还发现奇怪的是,当我添加:里弗斯作为一个论点,然后洗牌并不保持我想要的牌洗牌。

我希望在如何防止Deck#shuffle修改甲板方面提供任何帮助。谢谢!

下面是我的代码(其中的一部分,如果有人需要我的话,我也可以发布其余的代码):

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-16 22:52:32

您的Deck类有一个实例变量-- @cards --它持有卡片。@cards实际上是对一组卡片的引用。

您没有实现Deck#dup,当您使用它时,您使用的是Object#dup,它执行一个浅拷贝&它将所有实例变量复制为引用。它不复制实例变量!

这意味着duped Deck持有一个不同的 @cards变量,该变量引用与原始Deck@cards相同的数组。当您shuffle时,相同的数组被洗牌。它可以通过不同的引用变量访问,但仍然是相同的数组。

如果您尝试:riffle:farro洗牌,它不会影响原始对象,因为这些洗牌类型中的对象可以做@cards = [],这会将@cards设置为一个新数组。

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

因此,您需要重写dup方法并使其复制@cards。您还可能希望更改initialize以支持以下内容:

代码语言:javascript
复制
def initialize(cards = nil)
    if cards
        @cards = cards
    else
        @cards = []
        (1..4).each { |suit|
            (1..13).each { |rank|
                @cards << Card.new(rank, suit)
            }
        }
    end
end

def dup
    Deck.new(@cards.dup)
end       
票数 2
EN

Stack Overflow用户

发布于 2014-05-16 22:52:43

当您对对象执行dup时,您只创建该对象的浅副本。。这意味着当您获得一个新的Deck实例时,您的原始Deck和这个新的Deck都将引用相同的@cards实例变量。

票数 0
EN

Stack Overflow用户

发布于 2014-05-16 22:54:52

这一行..。

代码语言:javascript
复制
dup.shuffle!(type, precision)

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23705410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档