欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

R语言构造扑克牌自动发牌,洗牌

程序员文章站 2022-04-23 22:44:42
...

在R语言构建自动洗牌,发牌
要求:自动洗牌、发牌
任务一:创建一副牌。学会如何使用R的数据类型和数据结构。
任务二:编写发牌和洗牌的函数。学习从一个数据集中抽取想要的数值。
首先需要创建一副牌(不包括大小王),从R语言的数据对象来看,数据框最合适。
因为花色是字符串,而点数是数字,所以能够承担数据类型不同的二维数据对象——数据框最合适。下面是创建pkp数据对象的代码

pkp<-data.frame(face=rep(c(2:10,"J","Q","K","A"),4),hs=rep(c("黑桃","方块","红桃","梅花"),each=13))

然后我们需要构造发牌,洗牌函数
在构造发牌,洗牌函数的过程中,最重要的理解逻辑,怎么才能发牌呢?
不妨思考模拟下日常生活中是怎么发牌的呢?首先我们都是从牌堆里面抽取一张扑克牌,然后牌堆就少了一张牌,继续按照顺序抽取,直到牌堆没有牌。
如果用代码思考的话,就是在pkp这个牌堆里面抽取第一张,然后有pkp[-1,]丢掉这张牌,继续抽取后丢掉,这就是发牌的过程。

#licensing pkp
licensing<-function(){
  assign("copypkp",copypkp[-1,],envir = globalenv())
  copypkp[1,]
}

在这里需要介绍下assign函数,assign函数是一个赋值语句,与”=”和”<-“不同的是,assign能在不同的环境下赋值。
下面需要介绍环境,环境在R中是比较重要的概念,什么是环境呢?
可以说环境和我们电脑里面的文件夹很类似
环境:用来具体存储对象的地方。
规则1:每一个对象都存储在一个环境当中。
规则2:每一个环境都与一个父环境相连接。构成一个分层的环境系统。
规则3:子环境与父环境的连接是单向的。
parenvs{pryr}:查看R的环境系统,parenvs(all=TRUE)会返回当前会话包含的环境列表。
as.environment():指向环境树中的任意一个环境。
globalenv();base();emptyenv();parent.env()
assign():赋值函数
下面通过parenvs查看当前R语言下的环境
R语言构造扑克牌自动发牌,洗牌
默认环境是globalenv(全局变量),也就是说我们创建对象,一般都是在globalenv环境里,
如果创建函数的话,R会自动给函数分配环境,且函数环境是globalenv的子环境
说环境的话可能不好理解,我们把环境比作文件夹。globalenv环境相当于默认文件夹,我们在globalenv环境创建的对象都储存在默认文件夹里面,函数相当于在默认文件夹里面再创建一个文件夹,函数文件夹创建的对象储存在函数文件夹中。
R语言构造扑克牌自动发牌,洗牌
关于环境有一点很重要。就是如何应用环境里面的对象。下面是环境作用域规则
活动环境:当前R执行活动的地方。
规则1:任何时候,R的活动环境都只有一个。
规则2:所有的新对象都会被存储在该环境中。
environment():查看当前的活动环境。
作用域规则:R搜索对象时会遵循的一系列规则。
规则1:R首先在当前的活动环境中搜索对象。
规则2:在命令行工作中,活动环境就是全局环境。
规则3:当R在某个环境中没有搜索到对象时,R会进入到该环境的父环境。
下面是洗牌函数的构造
我理解的洗牌就是要把pkp这个数据对象里面的顺序打乱,如何打乱顺序呢?
我的思路是,构造一个随机向量,里面有52个值,然后构造一个循环52次的结构,将随机向量一个个的赋值给pkp这个数据对象.下面是洗牌函数代码

#shuffle pkp
shuffle<-function(){
  copypkp<-pkp
  random<-sample(c(1:52),size=52)
  for (i in 1:52)
  {
    assign("copypkp",copypkp[random,],envir = globalenv())
  }
  print("your pkp has been shuffled")
}

完整代码如下

#create pkp data
pkp<-data.frame(face=rep(c(2:10,"J","Q","K","A"),4),hs=rep(c("黑桃","方块","红桃","梅花"),each=13))
#copy pkp
copypkp<-pkp
#licensing pkp
licensing<-function(){
  assign("copypkp",copypkp[-1,],envir = globalenv())
  copypkp[1,]
}
#shuffle pkp
shuffle<-function(){
  copypkp<-pkp
  random<-sample(c(1:52),size=52)
  for (i in 1:52)
  {
    assign("copypkp",copypkp[random,],envir = globalenv())
  }
  print("your pkp has been shuffled")
}

有一个点需要特别注意,就是对象的更改。两个函数我都是对copypkp这个数据对象进行更改,pkp这个数据对象是没有变化的。这样有利于shuffle(洗牌)后的重置化。
但是这个自动洗牌,发牌还有一个重大的缺陷:如果pkp这个数据对象不小心被删除的化,整个洗牌,发牌过程都实现不了。
要解决这个问题,我们就必须用到闭包函数的概念和深入理解环境
在下一篇我会详细介绍闭包的实现和环境的深入理解

相关标签: R