使用 R 进行动手编程中的随机操作函数



这是个问题

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

答案是

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

我的问题是

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

  2. 在随机函数之前,我们定义了一个成交函数。

这是deal函数。

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

因此,在我们发牌后,它将删除该牌,然后将其余的牌保存到"deck"中

因此,当我们使用洗牌功能时,移除的卡将如下所示

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

我该如何解决这个问题?

我认为 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

最新更新