首页 > 解决方案 > 使用 R 进行动手编程中的随机播放功能

问题描述

这是问题

练习 8.3(重写 shuffle) 重写 shuffle 以便它用 DECK 的 shuffle 版本替换存在于全局环境中的甲板副本,甲板的完整副本也存在于全局环境中。新版本的 shuffle 应该没有参数并且不返回任何输出。

答案是

shuffle <- function(){
    random <- sample(1:52, size = 52)
    assign("deck", DECK[random, ], envir = globalenv())
}

我的问题是

  1. 添加一个新对象“DECK”有什么意义,为什么即使我们没有定义它也能工作?

  2. 在 shuffle 函数之前,我们定义一个 deal 函数。

这就是deal功能。

deal <- function(){
     card <- deck[1, ]
     assign("deck", deck[-1, ], envir = globalenv())
     card
}

因此,在我们发牌后,它会移除这张牌,然后将其余的牌保存到“牌组”中

因此,当我们使用洗牌功能时,被移除的牌会看起来像

    face     suit  value
NA  <NA>     <NA>    NA
17   ten    clubs    10

我该如何解决这个问题?

标签: r

解决方案


我不认为 DECK 应该工作,即使它还没有定义。我认为这隐含地指回了文本或先前问题中描述的任务。

我认为 DECK 意味着保持原样并成为 52 个值的静态资源,而deck意味着是相同的对象,但在一个单独的对象中,其组件的随机排序。该deal操作可能只是多步骤过程中的一个步骤,该过程会产生几个不同的“手”对象(可能每张 5 张牌,或两张牌和一张暴露,具体取决于特定类型的扑克)。你不会在分发一张特定的牌后重新洗牌,而是宁愿以(随机)顺序“发”下一张牌。

该作业的作者正在使用非功能性方法。他在函数内部创建一个对象,但将其“推”到函数环境之外,其结果实际上是一个副作用。一些评论者正试图通过构造一个在函数操作完成后完成分配的函数来使其更具“功能性”。在这种情况下,它确实不会改变正在发生的事情,但作者提出的策略并不被 R cognoscenti 视为最佳实践。在某些情况下它可能会有所作为,我的建议是尽可能采用函数式风格。

因此,您现在应该定义一个可以容纳多个“手”的数据结构,然后编写代码来跟踪有多少手,以及已经发了多少张牌。您可以在每次发牌操作时增加手数和牌数。也许是矩阵?

DECK <- expand.grid(Suit =c('S','D','C','H'),
                    Val = c("A","K","Q","J",10:2) )
# insert the functions you already have.
Suitable control  ... perhaps nested `for`-loops? or nested `sapply` loops?
 {
 hand[i,j] <- deal()
 }

以前是否在 SO 上说明过这样的过程?也许,甚至可能。搜索“[r] 套牌交易卡”: https ://stackoverflow.com/search?q=%5Br%5D+cards+deck+deal


推荐阅读